ActivityManagerService.java revision dc249c4ae7c7838928f53f151bfda8a6817b8784
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;
21
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.ProcessStats;
31import com.android.internal.app.SystemUserHomeActivity;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.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;
242import libcore.io.IoUtils;
243import libcore.util.EmptyArray;
244
245import static android.Manifest.permission.INTERACT_ACROSS_USERS;
246import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
247import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
248import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
249import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
250import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
251import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
252import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
253import static android.app.ActivityManager.StackId.HOME_STACK_ID;
254import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
255import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
256import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
257import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
258import static android.content.pm.PackageManager.PERMISSION_GRANTED;
259import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
260import static android.provider.Settings.Global.DEBUG_APP;
261import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
262import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
263import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
264import static com.android.internal.util.XmlUtils.readBooleanAttribute;
265import static com.android.internal.util.XmlUtils.readIntAttribute;
266import static com.android.internal.util.XmlUtils.readLongAttribute;
267import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
268import static com.android.internal.util.XmlUtils.writeIntAttribute;
269import static com.android.internal.util.XmlUtils.writeLongAttribute;
270import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
271import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
272import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
273import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
274import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
275import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
276import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
277import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
278import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
302import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
303import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
304import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
305import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
306import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
307import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
308import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
309import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
327import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
328import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
329import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
330import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
331import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
332import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
333import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
334import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
335import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
336import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
337import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
338import static org.xmlpull.v1.XmlPullParser.START_TAG;
339
340public final class ActivityManagerService extends ActivityManagerNative
341        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
342
343    // File that stores last updated system version and called preboot receivers
344    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
345
346    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
347    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
348    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
349    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
350    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
351    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
352    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
353    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
354    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
355    private static final String TAG_LRU = TAG + POSTFIX_LRU;
356    private static final String TAG_MU = TAG + POSTFIX_MU;
357    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
358    private static final String TAG_POWER = TAG + POSTFIX_POWER;
359    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
360    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
361    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
362    private static final String TAG_PSS = TAG + POSTFIX_PSS;
363    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
364    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
365    private static final String TAG_STACK = TAG + POSTFIX_STACK;
366    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
367    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
368    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
369    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
370    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
371
372    /** Control over CPU and battery monitoring */
373    // write battery stats every 30 minutes.
374    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
375    static final boolean MONITOR_CPU_USAGE = true;
376    // don't sample cpu less than every 5 seconds.
377    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
378    // wait possibly forever for next cpu sample.
379    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
380    static final boolean MONITOR_THREAD_CPU_USAGE = false;
381
382    // The flags that are set for all calls we make to the package manager.
383    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
384
385    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
386
387    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
388
389    // Amount of time after a call to stopAppSwitches() during which we will
390    // prevent further untrusted switches from happening.
391    static final long APP_SWITCH_DELAY_TIME = 5*1000;
392
393    // How long we wait for a launched process to attach to the activity manager
394    // before we decide it's never going to come up for real.
395    static final int PROC_START_TIMEOUT = 10*1000;
396    // How long we wait for an attached process to publish its content providers
397    // before we decide it must be hung.
398    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
399
400    // How long we will retain processes hosting content providers in the "last activity"
401    // state before allowing them to drop down to the regular cached LRU list.  This is
402    // to avoid thrashing of provider processes under low memory situations.
403    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
404
405    // How long we wait for a launched process to attach to the activity manager
406    // before we decide it's never going to come up for real, when the process was
407    // started with a wrapper for instrumentation (such as Valgrind) because it
408    // could take much longer than usual.
409    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
410
411    // How long to wait after going idle before forcing apps to GC.
412    static final int GC_TIMEOUT = 5*1000;
413
414    // The minimum amount of time between successive GC requests for a process.
415    static final int GC_MIN_INTERVAL = 60*1000;
416
417    // The minimum amount of time between successive PSS requests for a process.
418    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
419
420    // The minimum amount of time between successive PSS requests for a process
421    // when the request is due to the memory state being lowered.
422    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
423
424    // The rate at which we check for apps using excessive power -- 15 mins.
425    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
426
427    // The minimum sample duration we will allow before deciding we have
428    // enough data on wake locks to start killing things.
429    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
430
431    // The minimum sample duration we will allow before deciding we have
432    // enough data on CPU usage to start killing things.
433    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
434
435    // How long we allow a receiver to run before giving up on it.
436    static final int BROADCAST_FG_TIMEOUT = 10*1000;
437    static final int BROADCAST_BG_TIMEOUT = 60*1000;
438
439    // How long we wait until we timeout on key dispatching.
440    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
441
442    // How long we wait until we timeout on key dispatching during instrumentation.
443    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
444
445    // This is the amount of time an app needs to be running a foreground service before
446    // we will consider it to be doing interaction for usage stats.
447    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
448
449    // Maximum amount of time we will allow to elapse before re-reporting usage stats
450    // interaction with foreground processes.
451    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
452
453    // This is the amount of time we allow an app to settle after it goes into the background,
454    // before we start restricting what it can do.
455    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
456
457    // How long to wait in getAssistContextExtras for the activity and foreground services
458    // to respond with the result.
459    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
460
461    // How long top wait when going through the modern assist (which doesn't need to block
462    // on getting this result before starting to launch its UI).
463    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
464
465    // Maximum number of persisted Uri grants a package is allowed
466    static final int MAX_PERSISTED_URI_GRANTS = 128;
467
468    static final int MY_PID = Process.myPid();
469
470    static final String[] EMPTY_STRING_ARRAY = new String[0];
471
472    // How many bytes to write into the dropbox log before truncating
473    static final int DROPBOX_MAX_SIZE = 256 * 1024;
474
475    // Access modes for handleIncomingUser.
476    static final int ALLOW_NON_FULL = 0;
477    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
478    static final int ALLOW_FULL_ONLY = 2;
479
480    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
481
482    // Delay in notifying task stack change listeners (in millis)
483    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
484
485    // Necessary ApplicationInfo flags to mark an app as persistent
486    private static final int PERSISTENT_MASK =
487            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
488
489
490    // Delay to disable app launch boost
491    static final int APP_BOOST_MESSAGE_DELAY = 3000;
492    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
493    static final int APP_BOOST_TIMEOUT = 2500;
494
495    // Used to indicate that a task is removed it should also be removed from recents.
496    private static final boolean REMOVE_FROM_RECENTS = true;
497    // Used to indicate that an app transition should be animated.
498    static final boolean ANIMATE = true;
499
500    // Determines whether to take full screen screenshots
501    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
502
503    private static native int nativeMigrateToBoost();
504    private static native int nativeMigrateFromBoost();
505    private boolean mIsBoosted = false;
506    private long mBoostStartTime = 0;
507
508    /** All system services */
509    SystemServiceManager mSystemServiceManager;
510
511    private Installer mInstaller;
512
513    /** Run all ActivityStacks through this */
514    ActivityStackSupervisor mStackSupervisor;
515
516    ActivityStarter mActivityStarter;
517
518    /** Task stack change listeners. */
519    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
520            new RemoteCallbackList<ITaskStackListener>();
521
522    public IntentFirewall mIntentFirewall;
523
524    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
525    // default actuion automatically.  Important for devices without direct input
526    // devices.
527    private boolean mShowDialogs = true;
528
529    BroadcastQueue mFgBroadcastQueue;
530    BroadcastQueue mBgBroadcastQueue;
531    // Convenient for easy iteration over the queues. Foreground is first
532    // so that dispatch of foreground broadcasts gets precedence.
533    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
534
535    BroadcastQueue broadcastQueueForIntent(Intent intent) {
536        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
537        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
538                "Broadcast intent " + intent + " on "
539                + (isFg ? "foreground" : "background") + " queue");
540        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
541    }
542
543    /**
544     * Activity we have told the window manager to have key focus.
545     */
546    ActivityRecord mFocusedActivity = null;
547
548    /**
549     * User id of the last activity mFocusedActivity was set to.
550     */
551    private int mLastFocusedUserId;
552
553    /**
554     * If non-null, we are tracking the time the user spends in the currently focused app.
555     */
556    private AppTimeTracker mCurAppTimeTracker;
557
558    /**
559     * List of intents that were used to start the most recent tasks.
560     */
561    private final RecentTasks mRecentTasks;
562
563    /**
564     * For addAppTask: cached of the last activity component that was added.
565     */
566    ComponentName mLastAddedTaskComponent;
567
568    /**
569     * For addAppTask: cached of the last activity uid that was added.
570     */
571    int mLastAddedTaskUid;
572
573    /**
574     * For addAppTask: cached of the last ActivityInfo that was added.
575     */
576    ActivityInfo mLastAddedTaskActivity;
577
578    /**
579     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
580     */
581    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
582
583    /**
584     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
585     */
586    String mDeviceOwnerName;
587
588    final UserController mUserController;
589
590    public class PendingAssistExtras extends Binder implements Runnable {
591        public final ActivityRecord activity;
592        public final Bundle extras;
593        public final Intent intent;
594        public final String hint;
595        public final IResultReceiver receiver;
596        public final int userHandle;
597        public boolean haveResult = false;
598        public Bundle result = null;
599        public AssistStructure structure = null;
600        public AssistContent content = null;
601        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
602                String _hint, IResultReceiver _receiver, int _userHandle) {
603            activity = _activity;
604            extras = _extras;
605            intent = _intent;
606            hint = _hint;
607            receiver = _receiver;
608            userHandle = _userHandle;
609        }
610        @Override
611        public void run() {
612            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
613            synchronized (this) {
614                haveResult = true;
615                notifyAll();
616            }
617            pendingAssistExtrasTimedOut(this);
618        }
619    }
620
621    final ArrayList<PendingAssistExtras> mPendingAssistExtras
622            = new ArrayList<PendingAssistExtras>();
623
624    /**
625     * Process management.
626     */
627    final ProcessList mProcessList = new ProcessList();
628
629    /**
630     * All of the applications we currently have running organized by name.
631     * The keys are strings of the application package name (as
632     * returned by the package manager), and the keys are ApplicationRecord
633     * objects.
634     */
635    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
636
637    /**
638     * Tracking long-term execution of processes to look for abuse and other
639     * bad app behavior.
640     */
641    final ProcessStatsService mProcessStats;
642
643    /**
644     * The currently running isolated processes.
645     */
646    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
647
648    /**
649     * Counter for assigning isolated process uids, to avoid frequently reusing the
650     * same ones.
651     */
652    int mNextIsolatedProcessUid = 0;
653
654    /**
655     * The currently running heavy-weight process, if any.
656     */
657    ProcessRecord mHeavyWeightProcess = null;
658
659    /**
660     * The last time that various processes have crashed.
661     */
662    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
663
664    /**
665     * Information about a process that is currently marked as bad.
666     */
667    static final class BadProcessInfo {
668        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
669            this.time = time;
670            this.shortMsg = shortMsg;
671            this.longMsg = longMsg;
672            this.stack = stack;
673        }
674
675        final long time;
676        final String shortMsg;
677        final String longMsg;
678        final String stack;
679    }
680
681    /**
682     * Set of applications that we consider to be bad, and will reject
683     * incoming broadcasts from (which the user has no control over).
684     * Processes are added to this set when they have crashed twice within
685     * a minimum amount of time; they are removed from it when they are
686     * later restarted (hopefully due to some user action).  The value is the
687     * time it was added to the list.
688     */
689    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
690
691    /**
692     * All of the processes we currently have running organized by pid.
693     * The keys are the pid running the application.
694     *
695     * <p>NOTE: This object is protected by its own lock, NOT the global
696     * activity manager lock!
697     */
698    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
699
700    /**
701     * All of the processes that have been forced to be foreground.  The key
702     * is the pid of the caller who requested it (we hold a death
703     * link on it).
704     */
705    abstract class ForegroundToken implements IBinder.DeathRecipient {
706        int pid;
707        IBinder token;
708    }
709    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
710
711    /**
712     * List of records for processes that someone had tried to start before the
713     * system was ready.  We don't start them at that point, but ensure they
714     * are started by the time booting is complete.
715     */
716    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
717
718    /**
719     * List of persistent applications that are in the process
720     * of being started.
721     */
722    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
723
724    /**
725     * Processes that are being forcibly torn down.
726     */
727    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
728
729    /**
730     * List of running applications, sorted by recent usage.
731     * The first entry in the list is the least recently used.
732     */
733    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
734
735    /**
736     * Where in mLruProcesses that the processes hosting activities start.
737     */
738    int mLruProcessActivityStart = 0;
739
740    /**
741     * Where in mLruProcesses that the processes hosting services start.
742     * This is after (lower index) than mLruProcessesActivityStart.
743     */
744    int mLruProcessServiceStart = 0;
745
746    /**
747     * List of processes that should gc as soon as things are idle.
748     */
749    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
750
751    /**
752     * Processes we want to collect PSS data from.
753     */
754    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
755
756    private boolean mBinderTransactionTrackingEnabled = false;
757
758    /**
759     * Last time we requested PSS data of all processes.
760     */
761    long mLastFullPssTime = SystemClock.uptimeMillis();
762
763    /**
764     * If set, the next time we collect PSS data we should do a full collection
765     * with data from native processes and the kernel.
766     */
767    boolean mFullPssPending = false;
768
769    /**
770     * This is the process holding what we currently consider to be
771     * the "home" activity.
772     */
773    ProcessRecord mHomeProcess;
774
775    /**
776     * This is the process holding the activity the user last visited that
777     * is in a different process from the one they are currently in.
778     */
779    ProcessRecord mPreviousProcess;
780
781    /**
782     * The time at which the previous process was last visible.
783     */
784    long mPreviousProcessVisibleTime;
785
786    /**
787     * Track all uids that have actively running processes.
788     */
789    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
790
791    /**
792     * This is for verifying the UID report flow.
793     */
794    static final boolean VALIDATE_UID_STATES = true;
795    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
796
797    /**
798     * Packages that the user has asked to have run in screen size
799     * compatibility mode instead of filling the screen.
800     */
801    final CompatModePackages mCompatModePackages;
802
803    /**
804     * Set of IntentSenderRecord objects that are currently active.
805     */
806    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
807            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
808
809    /**
810     * Fingerprints (hashCode()) of stack traces that we've
811     * already logged DropBox entries for.  Guarded by itself.  If
812     * something (rogue user app) forces this over
813     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
814     */
815    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
816    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
817
818    /**
819     * Strict Mode background batched logging state.
820     *
821     * The string buffer is guarded by itself, and its lock is also
822     * used to determine if another batched write is already
823     * in-flight.
824     */
825    private final StringBuilder mStrictModeBuffer = new StringBuilder();
826
827    /**
828     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
829     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
830     */
831    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
832
833    /**
834     * Resolver for broadcast intents to registered receivers.
835     * Holds BroadcastFilter (subclass of IntentFilter).
836     */
837    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
838            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
839        @Override
840        protected boolean allowFilterResult(
841                BroadcastFilter filter, List<BroadcastFilter> dest) {
842            IBinder target = filter.receiverList.receiver.asBinder();
843            for (int i = dest.size() - 1; i >= 0; i--) {
844                if (dest.get(i).receiverList.receiver.asBinder() == target) {
845                    return false;
846                }
847            }
848            return true;
849        }
850
851        @Override
852        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
853            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
854                    || userId == filter.owningUserId) {
855                return super.newResult(filter, match, userId);
856            }
857            return null;
858        }
859
860        @Override
861        protected BroadcastFilter[] newArray(int size) {
862            return new BroadcastFilter[size];
863        }
864
865        @Override
866        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
867            return packageName.equals(filter.packageName);
868        }
869    };
870
871    /**
872     * State of all active sticky broadcasts per user.  Keys are the action of the
873     * sticky Intent, values are an ArrayList of all broadcasted intents with
874     * that action (which should usually be one).  The SparseArray is keyed
875     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
876     * for stickies that are sent to all users.
877     */
878    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
879            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
880
881    final ActiveServices mServices;
882
883    final static class Association {
884        final int mSourceUid;
885        final String mSourceProcess;
886        final int mTargetUid;
887        final ComponentName mTargetComponent;
888        final String mTargetProcess;
889
890        int mCount;
891        long mTime;
892
893        int mNesting;
894        long mStartTime;
895
896        Association(int sourceUid, String sourceProcess, int targetUid,
897                ComponentName targetComponent, String targetProcess) {
898            mSourceUid = sourceUid;
899            mSourceProcess = sourceProcess;
900            mTargetUid = targetUid;
901            mTargetComponent = targetComponent;
902            mTargetProcess = targetProcess;
903        }
904    }
905
906    /**
907     * When service association tracking is enabled, this is all of the associations we
908     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
909     * -> association data.
910     */
911    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
912            mAssociations = new SparseArray<>();
913    boolean mTrackingAssociations;
914
915    /**
916     * Backup/restore process management
917     */
918    String mBackupAppName = null;
919    BackupRecord mBackupTarget = null;
920
921    final ProviderMap mProviderMap;
922
923    /**
924     * List of content providers who have clients waiting for them.  The
925     * application is currently being launched and the provider will be
926     * removed from this list once it is published.
927     */
928    final ArrayList<ContentProviderRecord> mLaunchingProviders
929            = new ArrayList<ContentProviderRecord>();
930
931    /**
932     * File storing persisted {@link #mGrantedUriPermissions}.
933     */
934    private final AtomicFile mGrantFile;
935
936    /** XML constants used in {@link #mGrantFile} */
937    private static final String TAG_URI_GRANTS = "uri-grants";
938    private static final String TAG_URI_GRANT = "uri-grant";
939    private static final String ATTR_USER_HANDLE = "userHandle";
940    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
941    private static final String ATTR_TARGET_USER_ID = "targetUserId";
942    private static final String ATTR_SOURCE_PKG = "sourcePkg";
943    private static final String ATTR_TARGET_PKG = "targetPkg";
944    private static final String ATTR_URI = "uri";
945    private static final String ATTR_MODE_FLAGS = "modeFlags";
946    private static final String ATTR_CREATED_TIME = "createdTime";
947    private static final String ATTR_PREFIX = "prefix";
948
949    /**
950     * Global set of specific {@link Uri} permissions that have been granted.
951     * This optimized lookup structure maps from {@link UriPermission#targetUid}
952     * to {@link UriPermission#uri} to {@link UriPermission}.
953     */
954    @GuardedBy("this")
955    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
956            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
957
958    public static class GrantUri {
959        public final int sourceUserId;
960        public final Uri uri;
961        public boolean prefix;
962
963        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
964            this.sourceUserId = sourceUserId;
965            this.uri = uri;
966            this.prefix = prefix;
967        }
968
969        @Override
970        public int hashCode() {
971            int hashCode = 1;
972            hashCode = 31 * hashCode + sourceUserId;
973            hashCode = 31 * hashCode + uri.hashCode();
974            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
975            return hashCode;
976        }
977
978        @Override
979        public boolean equals(Object o) {
980            if (o instanceof GrantUri) {
981                GrantUri other = (GrantUri) o;
982                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
983                        && prefix == other.prefix;
984            }
985            return false;
986        }
987
988        @Override
989        public String toString() {
990            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
991            if (prefix) result += " [prefix]";
992            return result;
993        }
994
995        public String toSafeString() {
996            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
997            if (prefix) result += " [prefix]";
998            return result;
999        }
1000
1001        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1002            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1003                    ContentProvider.getUriWithoutUserId(uri), false);
1004        }
1005    }
1006
1007    CoreSettingsObserver mCoreSettingsObserver;
1008
1009    /**
1010     * Thread-local storage used to carry caller permissions over through
1011     * indirect content-provider access.
1012     */
1013    private class Identity {
1014        public final IBinder token;
1015        public final int pid;
1016        public final int uid;
1017
1018        Identity(IBinder _token, int _pid, int _uid) {
1019            token = _token;
1020            pid = _pid;
1021            uid = _uid;
1022        }
1023    }
1024
1025    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1026
1027    /**
1028     * All information we have collected about the runtime performance of
1029     * any user id that can impact battery performance.
1030     */
1031    final BatteryStatsService mBatteryStatsService;
1032
1033    /**
1034     * Information about component usage
1035     */
1036    UsageStatsManagerInternal mUsageStatsService;
1037
1038    /**
1039     * Access to DeviceIdleController service.
1040     */
1041    DeviceIdleController.LocalService mLocalDeviceIdleController;
1042
1043    /**
1044     * Information about and control over application operations
1045     */
1046    final AppOpsService mAppOpsService;
1047
1048    /**
1049     * Save recent tasks information across reboots.
1050     */
1051    final TaskPersister mTaskPersister;
1052
1053    /**
1054     * Current configuration information.  HistoryRecord objects are given
1055     * a reference to this object to indicate which configuration they are
1056     * currently running in, so this object must be kept immutable.
1057     */
1058    Configuration mConfiguration = new Configuration();
1059
1060    /**
1061     * Current sequencing integer of the configuration, for skipping old
1062     * configurations.
1063     */
1064    int mConfigurationSeq = 0;
1065
1066    boolean mSuppressResizeConfigChanges = false;
1067
1068    /**
1069     * Hardware-reported OpenGLES version.
1070     */
1071    final int GL_ES_VERSION;
1072
1073    /**
1074     * List of initialization arguments to pass to all processes when binding applications to them.
1075     * For example, references to the commonly used services.
1076     */
1077    HashMap<String, IBinder> mAppBindArgs;
1078
1079    /**
1080     * Temporary to avoid allocations.  Protected by main lock.
1081     */
1082    final StringBuilder mStringBuilder = new StringBuilder(256);
1083
1084    /**
1085     * Used to control how we initialize the service.
1086     */
1087    ComponentName mTopComponent;
1088    String mTopAction = Intent.ACTION_MAIN;
1089    String mTopData;
1090    boolean mProcessesReady = false;
1091    boolean mSystemReady = false;
1092    boolean mBooting = false;
1093    boolean mCallFinishBooting = false;
1094    boolean mBootAnimationComplete = false;
1095    boolean mWaitingUpdate = false;
1096    boolean mDidUpdate = false;
1097    boolean mOnBattery = false;
1098    boolean mLaunchWarningShown = false;
1099
1100    Context mContext;
1101
1102    int mFactoryTest;
1103
1104    boolean mCheckedForSetup;
1105
1106    /**
1107     * The time at which we will allow normal application switches again,
1108     * after a call to {@link #stopAppSwitches()}.
1109     */
1110    long mAppSwitchesAllowedTime;
1111
1112    /**
1113     * This is set to true after the first switch after mAppSwitchesAllowedTime
1114     * is set; any switches after that will clear the time.
1115     */
1116    boolean mDidAppSwitch;
1117
1118    /**
1119     * Last time (in realtime) at which we checked for power usage.
1120     */
1121    long mLastPowerCheckRealtime;
1122
1123    /**
1124     * Last time (in uptime) at which we checked for power usage.
1125     */
1126    long mLastPowerCheckUptime;
1127
1128    /**
1129     * Set while we are wanting to sleep, to prevent any
1130     * activities from being started/resumed.
1131     */
1132    private boolean mSleeping = false;
1133
1134    /**
1135     * The process state used for processes that are running the top activities.
1136     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1137     */
1138    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1139
1140    /**
1141     * Set while we are running a voice interaction.  This overrides
1142     * sleeping while it is active.
1143     */
1144    private IVoiceInteractionSession mRunningVoice;
1145
1146    /**
1147     * For some direct access we need to power manager.
1148     */
1149    PowerManagerInternal mLocalPowerManager;
1150
1151    /**
1152     * We want to hold a wake lock while running a voice interaction session, since
1153     * this may happen with the screen off and we need to keep the CPU running to
1154     * be able to continue to interact with the user.
1155     */
1156    PowerManager.WakeLock mVoiceWakeLock;
1157
1158    /**
1159     * State of external calls telling us if the device is awake or asleep.
1160     */
1161    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1162
1163    /**
1164     * A list of tokens that cause the top activity to be put to sleep.
1165     * They are used by components that may hide and block interaction with underlying
1166     * activities.
1167     */
1168    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1169
1170    static final int LOCK_SCREEN_HIDDEN = 0;
1171    static final int LOCK_SCREEN_LEAVING = 1;
1172    static final int LOCK_SCREEN_SHOWN = 2;
1173    /**
1174     * State of external call telling us if the lock screen is shown.
1175     */
1176    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1177
1178    /**
1179     * Set if we are shutting down the system, similar to sleeping.
1180     */
1181    boolean mShuttingDown = false;
1182
1183    /**
1184     * Current sequence id for oom_adj computation traversal.
1185     */
1186    int mAdjSeq = 0;
1187
1188    /**
1189     * Current sequence id for process LRU updating.
1190     */
1191    int mLruSeq = 0;
1192
1193    /**
1194     * Keep track of the non-cached/empty process we last found, to help
1195     * determine how to distribute cached/empty processes next time.
1196     */
1197    int mNumNonCachedProcs = 0;
1198
1199    /**
1200     * Keep track of the number of cached hidden procs, to balance oom adj
1201     * distribution between those and empty procs.
1202     */
1203    int mNumCachedHiddenProcs = 0;
1204
1205    /**
1206     * Keep track of the number of service processes we last found, to
1207     * determine on the next iteration which should be B services.
1208     */
1209    int mNumServiceProcs = 0;
1210    int mNewNumAServiceProcs = 0;
1211    int mNewNumServiceProcs = 0;
1212
1213    /**
1214     * Allow the current computed overall memory level of the system to go down?
1215     * This is set to false when we are killing processes for reasons other than
1216     * memory management, so that the now smaller process list will not be taken as
1217     * an indication that memory is tighter.
1218     */
1219    boolean mAllowLowerMemLevel = false;
1220
1221    /**
1222     * The last computed memory level, for holding when we are in a state that
1223     * processes are going away for other reasons.
1224     */
1225    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1226
1227    /**
1228     * The last total number of process we have, to determine if changes actually look
1229     * like a shrinking number of process due to lower RAM.
1230     */
1231    int mLastNumProcesses;
1232
1233    /**
1234     * The uptime of the last time we performed idle maintenance.
1235     */
1236    long mLastIdleTime = SystemClock.uptimeMillis();
1237
1238    /**
1239     * Total time spent with RAM that has been added in the past since the last idle time.
1240     */
1241    long mLowRamTimeSinceLastIdle = 0;
1242
1243    /**
1244     * If RAM is currently low, when that horrible situation started.
1245     */
1246    long mLowRamStartTime = 0;
1247
1248    /**
1249     * For reporting to battery stats the current top application.
1250     */
1251    private String mCurResumedPackage = null;
1252    private int mCurResumedUid = -1;
1253
1254    /**
1255     * For reporting to battery stats the apps currently running foreground
1256     * service.  The ProcessMap is package/uid tuples; each of these contain
1257     * an array of the currently foreground processes.
1258     */
1259    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1260            = new ProcessMap<ArrayList<ProcessRecord>>();
1261
1262    /**
1263     * This is set if we had to do a delayed dexopt of an app before launching
1264     * it, to increase the ANR timeouts in that case.
1265     */
1266    boolean mDidDexOpt;
1267
1268    /**
1269     * Set if the systemServer made a call to enterSafeMode.
1270     */
1271    boolean mSafeMode;
1272
1273    /**
1274     * If true, we are running under a test environment so will sample PSS from processes
1275     * much more rapidly to try to collect better data when the tests are rapidly
1276     * running through apps.
1277     */
1278    boolean mTestPssMode = false;
1279
1280    String mDebugApp = null;
1281    boolean mWaitForDebugger = false;
1282    boolean mDebugTransient = false;
1283    String mOrigDebugApp = null;
1284    boolean mOrigWaitForDebugger = false;
1285    boolean mAlwaysFinishActivities = false;
1286    boolean mForceResizableActivities;
1287    boolean mSupportsFreeformWindowManagement;
1288    boolean mSupportsPictureInPicture;
1289    Rect mDefaultPinnedStackBounds;
1290    IActivityController mController = null;
1291    String mProfileApp = null;
1292    ProcessRecord mProfileProc = null;
1293    String mProfileFile;
1294    ParcelFileDescriptor mProfileFd;
1295    int mSamplingInterval = 0;
1296    boolean mAutoStopProfiler = false;
1297    int mProfileType = 0;
1298    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1299    String mMemWatchDumpProcName;
1300    String mMemWatchDumpFile;
1301    int mMemWatchDumpPid;
1302    int mMemWatchDumpUid;
1303    String mTrackAllocationApp = null;
1304
1305    final long[] mTmpLong = new long[1];
1306
1307    static final class ProcessChangeItem {
1308        static final int CHANGE_ACTIVITIES = 1<<0;
1309        static final int CHANGE_PROCESS_STATE = 1<<1;
1310        int changes;
1311        int uid;
1312        int pid;
1313        int processState;
1314        boolean foregroundActivities;
1315    }
1316
1317    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1318    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1319
1320    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1321    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1322
1323    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1324    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1325
1326    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1327    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1328
1329    ArraySet<String> mAppsNotReportingCrashes;
1330
1331    /**
1332     * Runtime CPU use collection thread.  This object's lock is used to
1333     * perform synchronization with the thread (notifying it to run).
1334     */
1335    final Thread mProcessCpuThread;
1336
1337    /**
1338     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1339     * Must acquire this object's lock when accessing it.
1340     * NOTE: this lock will be held while doing long operations (trawling
1341     * through all processes in /proc), so it should never be acquired by
1342     * any critical paths such as when holding the main activity manager lock.
1343     */
1344    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1345            MONITOR_THREAD_CPU_USAGE);
1346    final AtomicLong mLastCpuTime = new AtomicLong(0);
1347    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1348
1349    long mLastWriteTime = 0;
1350
1351    /**
1352     * Used to retain an update lock when the foreground activity is in
1353     * immersive mode.
1354     */
1355    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1356
1357    /**
1358     * Set to true after the system has finished booting.
1359     */
1360    boolean mBooted = false;
1361
1362    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1363    int mProcessLimitOverride = -1;
1364
1365    WindowManagerService mWindowManager;
1366
1367    final ActivityThread mSystemThread;
1368
1369    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1370        final ProcessRecord mApp;
1371        final int mPid;
1372        final IApplicationThread mAppThread;
1373
1374        AppDeathRecipient(ProcessRecord app, int pid,
1375                IApplicationThread thread) {
1376            if (DEBUG_ALL) Slog.v(
1377                TAG, "New death recipient " + this
1378                + " for thread " + thread.asBinder());
1379            mApp = app;
1380            mPid = pid;
1381            mAppThread = thread;
1382        }
1383
1384        @Override
1385        public void binderDied() {
1386            if (DEBUG_ALL) Slog.v(
1387                TAG, "Death received in " + this
1388                + " for thread " + mAppThread.asBinder());
1389            synchronized(ActivityManagerService.this) {
1390                appDiedLocked(mApp, mPid, mAppThread, true);
1391            }
1392        }
1393    }
1394
1395    static final int SHOW_ERROR_UI_MSG = 1;
1396    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1397    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1398    static final int UPDATE_CONFIGURATION_MSG = 4;
1399    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1400    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1401    static final int SERVICE_TIMEOUT_MSG = 12;
1402    static final int UPDATE_TIME_ZONE = 13;
1403    static final int SHOW_UID_ERROR_UI_MSG = 14;
1404    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1405    static final int PROC_START_TIMEOUT_MSG = 20;
1406    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1407    static final int KILL_APPLICATION_MSG = 22;
1408    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1409    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1410    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1411    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1412    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1413    static final int CLEAR_DNS_CACHE_MSG = 28;
1414    static final int UPDATE_HTTP_PROXY_MSG = 29;
1415    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1416    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1417    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1418    static final int REPORT_MEM_USAGE_MSG = 33;
1419    static final int REPORT_USER_SWITCH_MSG = 34;
1420    static final int CONTINUE_USER_SWITCH_MSG = 35;
1421    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1422    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1423    static final int PERSIST_URI_GRANTS_MSG = 38;
1424    static final int REQUEST_ALL_PSS_MSG = 39;
1425    static final int START_PROFILES_MSG = 40;
1426    static final int UPDATE_TIME = 41;
1427    static final int SYSTEM_USER_START_MSG = 42;
1428    static final int SYSTEM_USER_CURRENT_MSG = 43;
1429    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1430    static final int FINISH_BOOTING_MSG = 45;
1431    static final int START_USER_SWITCH_UI_MSG = 46;
1432    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1433    static final int DISMISS_DIALOG_UI_MSG = 48;
1434    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1435    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1436    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1437    static final int DELETE_DUMPHEAP_MSG = 52;
1438    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1439    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1440    static final int REPORT_TIME_TRACKER_MSG = 55;
1441    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1442    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1443    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1444    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1445    static final int IDLE_UIDS_MSG = 60;
1446    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1447    static final int LOG_STACK_STATE = 62;
1448    static final int VR_MODE_CHANGE_MSG = 63;
1449    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1450
1451    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1452    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1453    static final int FIRST_COMPAT_MODE_MSG = 300;
1454    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1455
1456    CompatModeDialog mCompatModeDialog;
1457    long mLastMemUsageReportTime = 0;
1458
1459    /**
1460     * Flag whether the current user is a "monkey", i.e. whether
1461     * the UI is driven by a UI automation tool.
1462     */
1463    private boolean mUserIsMonkey;
1464
1465    /** Flag whether the device has a Recents UI */
1466    boolean mHasRecents;
1467
1468    /** The dimensions of the thumbnails in the Recents UI. */
1469    int mThumbnailWidth;
1470    int mThumbnailHeight;
1471
1472    final ServiceThread mHandlerThread;
1473    final MainHandler mHandler;
1474    final UiHandler mUiHandler;
1475
1476    PackageManagerInternal mPackageManagerInt;
1477
1478    final class UiHandler extends Handler {
1479        public UiHandler() {
1480            super(com.android.server.UiThread.get().getLooper(), null, true);
1481        }
1482
1483        @Override
1484        public void handleMessage(Message msg) {
1485            switch (msg.what) {
1486            case SHOW_ERROR_UI_MSG: {
1487                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1488                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1489                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1490                synchronized (ActivityManagerService.this) {
1491                    ProcessRecord proc = (ProcessRecord)data.get("app");
1492                    AppErrorResult res = (AppErrorResult) data.get("result");
1493                    if (proc != null && proc.crashDialog != null) {
1494                        Slog.e(TAG, "App already has crash dialog: " + proc);
1495                        if (res != null) {
1496                            res.set(0);
1497                        }
1498                        return;
1499                    }
1500                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1501                            >= Process.FIRST_APPLICATION_UID
1502                            && proc.pid != MY_PID);
1503                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1504                        isBackground &= (proc.userId != userId);
1505                    }
1506                    if (isBackground && !showBackground) {
1507                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1508                        if (res != null) {
1509                            res.set(0);
1510                        }
1511                        return;
1512                    }
1513                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1514                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1515                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1516                        Dialog d = new AppErrorDialog(mContext,
1517                                ActivityManagerService.this, res, proc);
1518                        d.show();
1519                        proc.crashDialog = d;
1520                    } else {
1521                        // The device is asleep, so just pretend that the user
1522                        // saw a crash dialog and hit "force quit".
1523                        if (res != null) {
1524                            res.set(0);
1525                        }
1526                    }
1527                }
1528
1529                ensureBootCompleted();
1530            } break;
1531            case SHOW_NOT_RESPONDING_UI_MSG: {
1532                synchronized (ActivityManagerService.this) {
1533                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1534                    ProcessRecord proc = (ProcessRecord)data.get("app");
1535                    if (proc != null && proc.anrDialog != null) {
1536                        Slog.e(TAG, "App already has anr dialog: " + proc);
1537                        return;
1538                    }
1539
1540                    Intent intent = new Intent("android.intent.action.ANR");
1541                    if (!mProcessesReady) {
1542                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1543                                | Intent.FLAG_RECEIVER_FOREGROUND);
1544                    }
1545                    broadcastIntentLocked(null, null, intent,
1546                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1547                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1548
1549                    if (mShowDialogs) {
1550                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1551                                mContext, proc, (ActivityRecord)data.get("activity"),
1552                                msg.arg1 != 0);
1553                        d.show();
1554                        proc.anrDialog = d;
1555                    } else {
1556                        // Just kill the app if there is no dialog to be shown.
1557                        killAppAtUsersRequest(proc, null);
1558                    }
1559                }
1560
1561                ensureBootCompleted();
1562            } break;
1563            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1564                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1565                synchronized (ActivityManagerService.this) {
1566                    ProcessRecord proc = (ProcessRecord) data.get("app");
1567                    if (proc == null) {
1568                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1569                        break;
1570                    }
1571                    if (proc.crashDialog != null) {
1572                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1573                        return;
1574                    }
1575                    AppErrorResult res = (AppErrorResult) data.get("result");
1576                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1577                        Dialog d = new StrictModeViolationDialog(mContext,
1578                                ActivityManagerService.this, res, proc);
1579                        d.show();
1580                        proc.crashDialog = d;
1581                    } else {
1582                        // The device is asleep, so just pretend that the user
1583                        // saw a crash dialog and hit "force quit".
1584                        res.set(0);
1585                    }
1586                }
1587                ensureBootCompleted();
1588            } break;
1589            case SHOW_FACTORY_ERROR_UI_MSG: {
1590                Dialog d = new FactoryErrorDialog(
1591                    mContext, msg.getData().getCharSequence("msg"));
1592                d.show();
1593                ensureBootCompleted();
1594            } break;
1595            case WAIT_FOR_DEBUGGER_UI_MSG: {
1596                synchronized (ActivityManagerService.this) {
1597                    ProcessRecord app = (ProcessRecord)msg.obj;
1598                    if (msg.arg1 != 0) {
1599                        if (!app.waitedForDebugger) {
1600                            Dialog d = new AppWaitingForDebuggerDialog(
1601                                    ActivityManagerService.this,
1602                                    mContext, app);
1603                            app.waitDialog = d;
1604                            app.waitedForDebugger = true;
1605                            d.show();
1606                        }
1607                    } else {
1608                        if (app.waitDialog != null) {
1609                            app.waitDialog.dismiss();
1610                            app.waitDialog = null;
1611                        }
1612                    }
1613                }
1614            } break;
1615            case SHOW_UID_ERROR_UI_MSG: {
1616                if (mShowDialogs) {
1617                    AlertDialog d = new BaseErrorDialog(mContext);
1618                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1619                    d.setCancelable(false);
1620                    d.setTitle(mContext.getText(R.string.android_system_label));
1621                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1622                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1623                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1624                    d.show();
1625                }
1626            } break;
1627            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1628                if (mShowDialogs) {
1629                    AlertDialog d = new BaseErrorDialog(mContext);
1630                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1631                    d.setCancelable(false);
1632                    d.setTitle(mContext.getText(R.string.android_system_label));
1633                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1634                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1635                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1636                    d.show();
1637                }
1638            } break;
1639            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1640                synchronized (ActivityManagerService.this) {
1641                    ActivityRecord ar = (ActivityRecord) msg.obj;
1642                    if (mCompatModeDialog != null) {
1643                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1644                                ar.info.applicationInfo.packageName)) {
1645                            return;
1646                        }
1647                        mCompatModeDialog.dismiss();
1648                        mCompatModeDialog = null;
1649                    }
1650                    if (ar != null && false) {
1651                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1652                                ar.packageName)) {
1653                            int mode = mCompatModePackages.computeCompatModeLocked(
1654                                    ar.info.applicationInfo);
1655                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1656                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1657                                mCompatModeDialog = new CompatModeDialog(
1658                                        ActivityManagerService.this, mContext,
1659                                        ar.info.applicationInfo);
1660                                mCompatModeDialog.show();
1661                            }
1662                        }
1663                    }
1664                }
1665                break;
1666            }
1667            case START_USER_SWITCH_UI_MSG: {
1668                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1669                break;
1670            }
1671            case DISMISS_DIALOG_UI_MSG: {
1672                final Dialog d = (Dialog) msg.obj;
1673                d.dismiss();
1674                break;
1675            }
1676            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1677                dispatchProcessesChanged();
1678                break;
1679            }
1680            case DISPATCH_PROCESS_DIED_UI_MSG: {
1681                final int pid = msg.arg1;
1682                final int uid = msg.arg2;
1683                dispatchProcessDied(pid, uid);
1684                break;
1685            }
1686            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1687                dispatchUidsChanged();
1688            } break;
1689            }
1690        }
1691    }
1692
1693    final class MainHandler extends Handler {
1694        public MainHandler(Looper looper) {
1695            super(looper, null, true);
1696        }
1697
1698        @Override
1699        public void handleMessage(Message msg) {
1700            switch (msg.what) {
1701            case UPDATE_CONFIGURATION_MSG: {
1702                final ContentResolver resolver = mContext.getContentResolver();
1703                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1704                        msg.arg1);
1705            } break;
1706            case GC_BACKGROUND_PROCESSES_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    performAppGcsIfAppropriateLocked();
1709                }
1710            } break;
1711            case SERVICE_TIMEOUT_MSG: {
1712                if (mDidDexOpt) {
1713                    mDidDexOpt = false;
1714                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1715                    nmsg.obj = msg.obj;
1716                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1717                    return;
1718                }
1719                mServices.serviceTimeout((ProcessRecord)msg.obj);
1720            } break;
1721            case UPDATE_TIME_ZONE: {
1722                synchronized (ActivityManagerService.this) {
1723                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1724                        ProcessRecord r = mLruProcesses.get(i);
1725                        if (r.thread != null) {
1726                            try {
1727                                r.thread.updateTimeZone();
1728                            } catch (RemoteException ex) {
1729                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1730                            }
1731                        }
1732                    }
1733                }
1734            } break;
1735            case CLEAR_DNS_CACHE_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1738                        ProcessRecord r = mLruProcesses.get(i);
1739                        if (r.thread != null) {
1740                            try {
1741                                r.thread.clearDnsCache();
1742                            } catch (RemoteException ex) {
1743                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1744                            }
1745                        }
1746                    }
1747                }
1748            } break;
1749            case UPDATE_HTTP_PROXY_MSG: {
1750                ProxyInfo proxy = (ProxyInfo)msg.obj;
1751                String host = "";
1752                String port = "";
1753                String exclList = "";
1754                Uri pacFileUrl = Uri.EMPTY;
1755                if (proxy != null) {
1756                    host = proxy.getHost();
1757                    port = Integer.toString(proxy.getPort());
1758                    exclList = proxy.getExclusionListAsString();
1759                    pacFileUrl = proxy.getPacFileUrl();
1760                }
1761                synchronized (ActivityManagerService.this) {
1762                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1763                        ProcessRecord r = mLruProcesses.get(i);
1764                        if (r.thread != null) {
1765                            try {
1766                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1767                            } catch (RemoteException ex) {
1768                                Slog.w(TAG, "Failed to update http proxy for: " +
1769                                        r.info.processName);
1770                            }
1771                        }
1772                    }
1773                }
1774            } break;
1775            case PROC_START_TIMEOUT_MSG: {
1776                if (mDidDexOpt) {
1777                    mDidDexOpt = false;
1778                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1779                    nmsg.obj = msg.obj;
1780                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1781                    return;
1782                }
1783                ProcessRecord app = (ProcessRecord)msg.obj;
1784                synchronized (ActivityManagerService.this) {
1785                    processStartTimedOutLocked(app);
1786                }
1787            } break;
1788            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1789                ProcessRecord app = (ProcessRecord)msg.obj;
1790                synchronized (ActivityManagerService.this) {
1791                    processContentProviderPublishTimedOutLocked(app);
1792                }
1793            } break;
1794            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1795                synchronized (ActivityManagerService.this) {
1796                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1797                }
1798            } break;
1799            case KILL_APPLICATION_MSG: {
1800                synchronized (ActivityManagerService.this) {
1801                    int appid = msg.arg1;
1802                    boolean restart = (msg.arg2 == 1);
1803                    Bundle bundle = (Bundle)msg.obj;
1804                    String pkg = bundle.getString("pkg");
1805                    String reason = bundle.getString("reason");
1806                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1807                            false, UserHandle.USER_ALL, reason);
1808                }
1809            } break;
1810            case FINALIZE_PENDING_INTENT_MSG: {
1811                ((PendingIntentRecord)msg.obj).completeFinalize();
1812            } break;
1813            case POST_HEAVY_NOTIFICATION_MSG: {
1814                INotificationManager inm = NotificationManager.getService();
1815                if (inm == null) {
1816                    return;
1817                }
1818
1819                ActivityRecord root = (ActivityRecord)msg.obj;
1820                ProcessRecord process = root.app;
1821                if (process == null) {
1822                    return;
1823                }
1824
1825                try {
1826                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1827                    String text = mContext.getString(R.string.heavy_weight_notification,
1828                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1829                    Notification notification = new Notification.Builder(context)
1830                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1831                            .setWhen(0)
1832                            .setOngoing(true)
1833                            .setTicker(text)
1834                            .setColor(mContext.getColor(
1835                                    com.android.internal.R.color.system_notification_accent_color))
1836                            .setContentTitle(text)
1837                            .setContentText(
1838                                    mContext.getText(R.string.heavy_weight_notification_detail))
1839                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1840                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1841                                    new UserHandle(root.userId)))
1842                            .build();
1843                    try {
1844                        int[] outId = new int[1];
1845                        inm.enqueueNotificationWithTag("android", "android", null,
1846                                R.string.heavy_weight_notification,
1847                                notification, outId, root.userId);
1848                    } catch (RuntimeException e) {
1849                        Slog.w(ActivityManagerService.TAG,
1850                                "Error showing notification for heavy-weight app", e);
1851                    } catch (RemoteException e) {
1852                    }
1853                } catch (NameNotFoundException e) {
1854                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1855                }
1856            } break;
1857            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1858                INotificationManager inm = NotificationManager.getService();
1859                if (inm == null) {
1860                    return;
1861                }
1862                try {
1863                    inm.cancelNotificationWithTag("android", null,
1864                            R.string.heavy_weight_notification,  msg.arg1);
1865                } catch (RuntimeException e) {
1866                    Slog.w(ActivityManagerService.TAG,
1867                            "Error canceling notification for service", e);
1868                } catch (RemoteException e) {
1869                }
1870            } break;
1871            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1872                synchronized (ActivityManagerService.this) {
1873                    checkExcessivePowerUsageLocked(true);
1874                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1875                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1876                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1877                }
1878            } break;
1879            case REPORT_MEM_USAGE_MSG: {
1880                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1881                Thread thread = new Thread() {
1882                    @Override public void run() {
1883                        reportMemUsage(memInfos);
1884                    }
1885                };
1886                thread.start();
1887                break;
1888            }
1889            case REPORT_USER_SWITCH_MSG: {
1890                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1891                break;
1892            }
1893            case CONTINUE_USER_SWITCH_MSG: {
1894                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1895                break;
1896            }
1897            case USER_SWITCH_TIMEOUT_MSG: {
1898                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1899                break;
1900            }
1901            case IMMERSIVE_MODE_LOCK_MSG: {
1902                final boolean nextState = (msg.arg1 != 0);
1903                if (mUpdateLock.isHeld() != nextState) {
1904                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1905                            "Applying new update lock state '" + nextState
1906                            + "' for " + (ActivityRecord)msg.obj);
1907                    if (nextState) {
1908                        mUpdateLock.acquire();
1909                    } else {
1910                        mUpdateLock.release();
1911                    }
1912                }
1913                break;
1914            }
1915            case PERSIST_URI_GRANTS_MSG: {
1916                writeGrantedUriPermissions();
1917                break;
1918            }
1919            case REQUEST_ALL_PSS_MSG: {
1920                synchronized (ActivityManagerService.this) {
1921                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1922                }
1923                break;
1924            }
1925            case START_PROFILES_MSG: {
1926                synchronized (ActivityManagerService.this) {
1927                    mUserController.startProfilesLocked();
1928                }
1929                break;
1930            }
1931            case UPDATE_TIME: {
1932                synchronized (ActivityManagerService.this) {
1933                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1934                        ProcessRecord r = mLruProcesses.get(i);
1935                        if (r.thread != null) {
1936                            try {
1937                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1938                            } catch (RemoteException ex) {
1939                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1940                            }
1941                        }
1942                    }
1943                }
1944                break;
1945            }
1946            case SYSTEM_USER_START_MSG: {
1947                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1948                        Integer.toString(msg.arg1), msg.arg1);
1949                mSystemServiceManager.startUser(msg.arg1);
1950                break;
1951            }
1952            case SYSTEM_USER_UNLOCK_MSG: {
1953                mSystemServiceManager.unlockUser(msg.arg1);
1954                break;
1955            }
1956            case SYSTEM_USER_CURRENT_MSG: {
1957                mBatteryStatsService.noteEvent(
1958                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1959                        Integer.toString(msg.arg2), msg.arg2);
1960                mBatteryStatsService.noteEvent(
1961                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1962                        Integer.toString(msg.arg1), msg.arg1);
1963                mSystemServiceManager.switchUser(msg.arg1);
1964                break;
1965            }
1966            case ENTER_ANIMATION_COMPLETE_MSG: {
1967                synchronized (ActivityManagerService.this) {
1968                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1969                    if (r != null && r.app != null && r.app.thread != null) {
1970                        try {
1971                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1972                        } catch (RemoteException e) {
1973                        }
1974                    }
1975                }
1976                break;
1977            }
1978            case FINISH_BOOTING_MSG: {
1979                if (msg.arg1 != 0) {
1980                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1981                    finishBooting();
1982                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1983                }
1984                if (msg.arg2 != 0) {
1985                    enableScreenAfterBoot();
1986                }
1987                break;
1988            }
1989            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1990                try {
1991                    Locale l = (Locale) msg.obj;
1992                    IBinder service = ServiceManager.getService("mount");
1993                    IMountService mountService = IMountService.Stub.asInterface(service);
1994                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1995                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1996                } catch (RemoteException e) {
1997                    Log.e(TAG, "Error storing locale for decryption UI", e);
1998                }
1999                break;
2000            }
2001            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2002                synchronized (ActivityManagerService.this) {
2003                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2004                        try {
2005                            // Make a one-way callback to the listener
2006                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2007                        } catch (RemoteException e){
2008                            // Handled by the RemoteCallbackList
2009                        }
2010                    }
2011                    mTaskStackListeners.finishBroadcast();
2012                }
2013                break;
2014            }
2015            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2016                synchronized (ActivityManagerService.this) {
2017                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2018                        try {
2019                            // Make a one-way callback to the listener
2020                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2021                        } catch (RemoteException e){
2022                            // Handled by the RemoteCallbackList
2023                        }
2024                    }
2025                    mTaskStackListeners.finishBroadcast();
2026                }
2027                break;
2028            }
2029            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2030                final int uid = msg.arg1;
2031                final byte[] firstPacket = (byte[]) msg.obj;
2032
2033                synchronized (mPidsSelfLocked) {
2034                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2035                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2036                        if (p.uid == uid) {
2037                            try {
2038                                p.thread.notifyCleartextNetwork(firstPacket);
2039                            } catch (RemoteException ignored) {
2040                            }
2041                        }
2042                    }
2043                }
2044                break;
2045            }
2046            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2047                final String procName;
2048                final int uid;
2049                final long memLimit;
2050                final String reportPackage;
2051                synchronized (ActivityManagerService.this) {
2052                    procName = mMemWatchDumpProcName;
2053                    uid = mMemWatchDumpUid;
2054                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2055                    if (val == null) {
2056                        val = mMemWatchProcesses.get(procName, 0);
2057                    }
2058                    if (val != null) {
2059                        memLimit = val.first;
2060                        reportPackage = val.second;
2061                    } else {
2062                        memLimit = 0;
2063                        reportPackage = null;
2064                    }
2065                }
2066                if (procName == null) {
2067                    return;
2068                }
2069
2070                if (DEBUG_PSS) Slog.d(TAG_PSS,
2071                        "Showing dump heap notification from " + procName + "/" + uid);
2072
2073                INotificationManager inm = NotificationManager.getService();
2074                if (inm == null) {
2075                    return;
2076                }
2077
2078                String text = mContext.getString(R.string.dump_heap_notification, procName);
2079
2080
2081                Intent deleteIntent = new Intent();
2082                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2083                Intent intent = new Intent();
2084                intent.setClassName("android", DumpHeapActivity.class.getName());
2085                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2086                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2087                if (reportPackage != null) {
2088                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2089                }
2090                int userId = UserHandle.getUserId(uid);
2091                Notification notification = new Notification.Builder(mContext)
2092                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2093                        .setWhen(0)
2094                        .setOngoing(true)
2095                        .setAutoCancel(true)
2096                        .setTicker(text)
2097                        .setColor(mContext.getColor(
2098                                com.android.internal.R.color.system_notification_accent_color))
2099                        .setContentTitle(text)
2100                        .setContentText(
2101                                mContext.getText(R.string.dump_heap_notification_detail))
2102                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2103                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2104                                new UserHandle(userId)))
2105                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2106                                deleteIntent, 0, UserHandle.SYSTEM))
2107                        .build();
2108
2109                try {
2110                    int[] outId = new int[1];
2111                    inm.enqueueNotificationWithTag("android", "android", null,
2112                            R.string.dump_heap_notification,
2113                            notification, outId, userId);
2114                } catch (RuntimeException e) {
2115                    Slog.w(ActivityManagerService.TAG,
2116                            "Error showing notification for dump heap", e);
2117                } catch (RemoteException e) {
2118                }
2119            } break;
2120            case DELETE_DUMPHEAP_MSG: {
2121                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2122                        DumpHeapActivity.JAVA_URI,
2123                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2124                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2125                        UserHandle.myUserId());
2126                synchronized (ActivityManagerService.this) {
2127                    mMemWatchDumpFile = null;
2128                    mMemWatchDumpProcName = null;
2129                    mMemWatchDumpPid = -1;
2130                    mMemWatchDumpUid = -1;
2131                }
2132            } break;
2133            case FOREGROUND_PROFILE_CHANGED_MSG: {
2134                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2135            } break;
2136            case REPORT_TIME_TRACKER_MSG: {
2137                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2138                tracker.deliverResult(mContext);
2139            } break;
2140            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2141                mUserController.dispatchUserSwitchComplete(msg.arg1);
2142            } break;
2143            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2144                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2145                try {
2146                    connection.shutdown();
2147                } catch (RemoteException e) {
2148                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2149                }
2150                // Only a UiAutomation can set this flag and now that
2151                // it is finished we make sure it is reset to its default.
2152                mUserIsMonkey = false;
2153            } break;
2154            case APP_BOOST_DEACTIVATE_MSG: {
2155                synchronized(ActivityManagerService.this) {
2156                    if (mIsBoosted) {
2157                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2158                            nativeMigrateFromBoost();
2159                            mIsBoosted = false;
2160                            mBoostStartTime = 0;
2161                        } else {
2162                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2163                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2164                        }
2165                    }
2166                }
2167            } break;
2168            case IDLE_UIDS_MSG: {
2169                idleUids();
2170            } break;
2171            case LOG_STACK_STATE: {
2172                synchronized (ActivityManagerService.this) {
2173                    mStackSupervisor.logStackState();
2174                }
2175            } break;
2176            case VR_MODE_CHANGE_MSG: {
2177                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2178                vrService.setVrMode(msg.arg1 != 0);
2179            } break;
2180            }
2181        }
2182    };
2183
2184    static final int COLLECT_PSS_BG_MSG = 1;
2185
2186    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2187        @Override
2188        public void handleMessage(Message msg) {
2189            switch (msg.what) {
2190            case COLLECT_PSS_BG_MSG: {
2191                long start = SystemClock.uptimeMillis();
2192                MemInfoReader memInfo = null;
2193                synchronized (ActivityManagerService.this) {
2194                    if (mFullPssPending) {
2195                        mFullPssPending = false;
2196                        memInfo = new MemInfoReader();
2197                    }
2198                }
2199                if (memInfo != null) {
2200                    updateCpuStatsNow();
2201                    long nativeTotalPss = 0;
2202                    synchronized (mProcessCpuTracker) {
2203                        final int N = mProcessCpuTracker.countStats();
2204                        for (int j=0; j<N; j++) {
2205                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2206                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2207                                // This is definitely an application process; skip it.
2208                                continue;
2209                            }
2210                            synchronized (mPidsSelfLocked) {
2211                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2212                                    // This is one of our own processes; skip it.
2213                                    continue;
2214                                }
2215                            }
2216                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2217                        }
2218                    }
2219                    memInfo.readMemInfo();
2220                    synchronized (ActivityManagerService.this) {
2221                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2222                                + (SystemClock.uptimeMillis()-start) + "ms");
2223                        final long cachedKb = memInfo.getCachedSizeKb();
2224                        final long freeKb = memInfo.getFreeSizeKb();
2225                        final long zramKb = memInfo.getZramTotalSizeKb();
2226                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2227                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2228                                kernelKb*1024, nativeTotalPss*1024);
2229                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2230                                nativeTotalPss);
2231                    }
2232                }
2233
2234                int num = 0;
2235                long[] tmp = new long[1];
2236                do {
2237                    ProcessRecord proc;
2238                    int procState;
2239                    int pid;
2240                    long lastPssTime;
2241                    synchronized (ActivityManagerService.this) {
2242                        if (mPendingPssProcesses.size() <= 0) {
2243                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2244                                    "Collected PSS of " + num + " processes in "
2245                                    + (SystemClock.uptimeMillis() - start) + "ms");
2246                            mPendingPssProcesses.clear();
2247                            return;
2248                        }
2249                        proc = mPendingPssProcesses.remove(0);
2250                        procState = proc.pssProcState;
2251                        lastPssTime = proc.lastPssTime;
2252                        if (proc.thread != null && procState == proc.setProcState
2253                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2254                                        < SystemClock.uptimeMillis()) {
2255                            pid = proc.pid;
2256                        } else {
2257                            proc = null;
2258                            pid = 0;
2259                        }
2260                    }
2261                    if (proc != null) {
2262                        long pss = Debug.getPss(pid, tmp, null);
2263                        synchronized (ActivityManagerService.this) {
2264                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2265                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2266                                num++;
2267                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2268                                        SystemClock.uptimeMillis());
2269                            }
2270                        }
2271                    }
2272                } while (true);
2273            }
2274            }
2275        }
2276    };
2277
2278    public void setSystemProcess() {
2279        try {
2280            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2281            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2282            ServiceManager.addService("meminfo", new MemBinder(this));
2283            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2284            ServiceManager.addService("dbinfo", new DbBinder(this));
2285            if (MONITOR_CPU_USAGE) {
2286                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2287            }
2288            ServiceManager.addService("permission", new PermissionController(this));
2289            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2290
2291            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2292                    "android", STOCK_PM_FLAGS);
2293            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2294
2295            synchronized (this) {
2296                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2297                app.persistent = true;
2298                app.pid = MY_PID;
2299                app.maxAdj = ProcessList.SYSTEM_ADJ;
2300                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2301                synchronized (mPidsSelfLocked) {
2302                    mPidsSelfLocked.put(app.pid, app);
2303                }
2304                updateLruProcessLocked(app, false, null);
2305                updateOomAdjLocked();
2306            }
2307        } catch (PackageManager.NameNotFoundException e) {
2308            throw new RuntimeException(
2309                    "Unable to find android system package", e);
2310        }
2311    }
2312
2313    public void setWindowManager(WindowManagerService wm) {
2314        mWindowManager = wm;
2315        mStackSupervisor.setWindowManager(wm);
2316        mActivityStarter.setWindowManager(wm);
2317    }
2318
2319    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2320        mUsageStatsService = usageStatsManager;
2321    }
2322
2323    public void startObservingNativeCrashes() {
2324        final NativeCrashListener ncl = new NativeCrashListener(this);
2325        ncl.start();
2326    }
2327
2328    public IAppOpsService getAppOpsService() {
2329        return mAppOpsService;
2330    }
2331
2332    static class MemBinder extends Binder {
2333        ActivityManagerService mActivityManagerService;
2334        MemBinder(ActivityManagerService activityManagerService) {
2335            mActivityManagerService = activityManagerService;
2336        }
2337
2338        @Override
2339        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2340            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2341                    != PackageManager.PERMISSION_GRANTED) {
2342                pw.println("Permission Denial: can't dump meminfo from from pid="
2343                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2344                        + " without permission " + android.Manifest.permission.DUMP);
2345                return;
2346            }
2347
2348            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2349        }
2350    }
2351
2352    static class GraphicsBinder extends Binder {
2353        ActivityManagerService mActivityManagerService;
2354        GraphicsBinder(ActivityManagerService activityManagerService) {
2355            mActivityManagerService = activityManagerService;
2356        }
2357
2358        @Override
2359        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2360            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2361                    != PackageManager.PERMISSION_GRANTED) {
2362                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2363                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2364                        + " without permission " + android.Manifest.permission.DUMP);
2365                return;
2366            }
2367
2368            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2369        }
2370    }
2371
2372    static class DbBinder extends Binder {
2373        ActivityManagerService mActivityManagerService;
2374        DbBinder(ActivityManagerService activityManagerService) {
2375            mActivityManagerService = activityManagerService;
2376        }
2377
2378        @Override
2379        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2380            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2381                    != PackageManager.PERMISSION_GRANTED) {
2382                pw.println("Permission Denial: can't dump dbinfo from from pid="
2383                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2384                        + " without permission " + android.Manifest.permission.DUMP);
2385                return;
2386            }
2387
2388            mActivityManagerService.dumpDbInfo(fd, pw, args);
2389        }
2390    }
2391
2392    static class CpuBinder extends Binder {
2393        ActivityManagerService mActivityManagerService;
2394        CpuBinder(ActivityManagerService activityManagerService) {
2395            mActivityManagerService = activityManagerService;
2396        }
2397
2398        @Override
2399        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2400            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2401                    != PackageManager.PERMISSION_GRANTED) {
2402                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2403                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2404                        + " without permission " + android.Manifest.permission.DUMP);
2405                return;
2406            }
2407
2408            synchronized (mActivityManagerService.mProcessCpuTracker) {
2409                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2410                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2411                        SystemClock.uptimeMillis()));
2412            }
2413        }
2414    }
2415
2416    public static final class Lifecycle extends SystemService {
2417        private final ActivityManagerService mService;
2418
2419        public Lifecycle(Context context) {
2420            super(context);
2421            mService = new ActivityManagerService(context);
2422        }
2423
2424        @Override
2425        public void onStart() {
2426            mService.start();
2427        }
2428
2429        public ActivityManagerService getService() {
2430            return mService;
2431        }
2432    }
2433
2434    // Note: This method is invoked on the main thread but may need to attach various
2435    // handlers to other threads.  So take care to be explicit about the looper.
2436    public ActivityManagerService(Context systemContext) {
2437        mContext = systemContext;
2438        mFactoryTest = FactoryTest.getMode();
2439        mSystemThread = ActivityThread.currentActivityThread();
2440
2441        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2442
2443        mHandlerThread = new ServiceThread(TAG,
2444                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2445        mHandlerThread.start();
2446        mHandler = new MainHandler(mHandlerThread.getLooper());
2447        mUiHandler = new UiHandler();
2448
2449        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2450                "foreground", BROADCAST_FG_TIMEOUT, false);
2451        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2452                "background", BROADCAST_BG_TIMEOUT, true);
2453        mBroadcastQueues[0] = mFgBroadcastQueue;
2454        mBroadcastQueues[1] = mBgBroadcastQueue;
2455
2456        mServices = new ActiveServices(this);
2457        mProviderMap = new ProviderMap(this);
2458
2459        // TODO: Move creation of battery stats service outside of activity manager service.
2460        File dataDir = Environment.getDataDirectory();
2461        File systemDir = new File(dataDir, "system");
2462        systemDir.mkdirs();
2463        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2464        mBatteryStatsService.getActiveStatistics().readLocked();
2465        mBatteryStatsService.scheduleWriteToDisk();
2466        mOnBattery = DEBUG_POWER ? true
2467                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2468        mBatteryStatsService.getActiveStatistics().setCallback(this);
2469
2470        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2471
2472        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2473        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2474                new IAppOpsCallback.Stub() {
2475                    @Override public void opChanged(int op, int uid, String packageName) {
2476                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2477                            if (mAppOpsService.checkOperation(op, uid, packageName)
2478                                    != AppOpsManager.MODE_ALLOWED) {
2479                                runInBackgroundDisabled(uid);
2480                            }
2481                        }
2482                    }
2483                });
2484
2485        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2486
2487        mUserController = new UserController(this);
2488
2489        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2490            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2491
2492        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2493
2494        mConfiguration.setToDefaults();
2495        mConfiguration.setLocales(LocaleList.getDefault());
2496
2497        mConfigurationSeq = mConfiguration.seq = 1;
2498        mProcessCpuTracker.init();
2499
2500        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2501        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2502        mRecentTasks = new RecentTasks(this);
2503        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2504        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2505        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2506
2507        mProcessCpuThread = new Thread("CpuTracker") {
2508            @Override
2509            public void run() {
2510                while (true) {
2511                    try {
2512                        try {
2513                            synchronized(this) {
2514                                final long now = SystemClock.uptimeMillis();
2515                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2516                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2517                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2518                                //        + ", write delay=" + nextWriteDelay);
2519                                if (nextWriteDelay < nextCpuDelay) {
2520                                    nextCpuDelay = nextWriteDelay;
2521                                }
2522                                if (nextCpuDelay > 0) {
2523                                    mProcessCpuMutexFree.set(true);
2524                                    this.wait(nextCpuDelay);
2525                                }
2526                            }
2527                        } catch (InterruptedException e) {
2528                        }
2529                        updateCpuStatsNow();
2530                    } catch (Exception e) {
2531                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2532                    }
2533                }
2534            }
2535        };
2536
2537        Watchdog.getInstance().addMonitor(this);
2538        Watchdog.getInstance().addThread(mHandler);
2539    }
2540
2541    public void setSystemServiceManager(SystemServiceManager mgr) {
2542        mSystemServiceManager = mgr;
2543    }
2544
2545    public void setInstaller(Installer installer) {
2546        mInstaller = installer;
2547    }
2548
2549    private void start() {
2550        Process.removeAllProcessGroups();
2551        mProcessCpuThread.start();
2552
2553        mBatteryStatsService.publish(mContext);
2554        mAppOpsService.publish(mContext);
2555        Slog.d("AppOps", "AppOpsService published");
2556        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2557    }
2558
2559    public void initPowerManagement() {
2560        mStackSupervisor.initPowerManagement();
2561        mBatteryStatsService.initPowerManagement();
2562        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2563        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2564        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2565        mVoiceWakeLock.setReferenceCounted(false);
2566    }
2567
2568    @Override
2569    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2570            throws RemoteException {
2571        if (code == SYSPROPS_TRANSACTION) {
2572            // We need to tell all apps about the system property change.
2573            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2574            synchronized(this) {
2575                final int NP = mProcessNames.getMap().size();
2576                for (int ip=0; ip<NP; ip++) {
2577                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2578                    final int NA = apps.size();
2579                    for (int ia=0; ia<NA; ia++) {
2580                        ProcessRecord app = apps.valueAt(ia);
2581                        if (app.thread != null) {
2582                            procs.add(app.thread.asBinder());
2583                        }
2584                    }
2585                }
2586            }
2587
2588            int N = procs.size();
2589            for (int i=0; i<N; i++) {
2590                Parcel data2 = Parcel.obtain();
2591                try {
2592                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2593                } catch (RemoteException e) {
2594                }
2595                data2.recycle();
2596            }
2597        }
2598        try {
2599            return super.onTransact(code, data, reply, flags);
2600        } catch (RuntimeException e) {
2601            // The activity manager only throws security exceptions, so let's
2602            // log all others.
2603            if (!(e instanceof SecurityException)) {
2604                Slog.wtf(TAG, "Activity Manager Crash", e);
2605            }
2606            throw e;
2607        }
2608    }
2609
2610    void updateCpuStats() {
2611        final long now = SystemClock.uptimeMillis();
2612        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2613            return;
2614        }
2615        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2616            synchronized (mProcessCpuThread) {
2617                mProcessCpuThread.notify();
2618            }
2619        }
2620    }
2621
2622    void updateCpuStatsNow() {
2623        synchronized (mProcessCpuTracker) {
2624            mProcessCpuMutexFree.set(false);
2625            final long now = SystemClock.uptimeMillis();
2626            boolean haveNewCpuStats = false;
2627
2628            if (MONITOR_CPU_USAGE &&
2629                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2630                mLastCpuTime.set(now);
2631                mProcessCpuTracker.update();
2632                if (mProcessCpuTracker.hasGoodLastStats()) {
2633                    haveNewCpuStats = true;
2634                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2635                    //Slog.i(TAG, "Total CPU usage: "
2636                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2637
2638                    // Slog the cpu usage if the property is set.
2639                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2640                        int user = mProcessCpuTracker.getLastUserTime();
2641                        int system = mProcessCpuTracker.getLastSystemTime();
2642                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2643                        int irq = mProcessCpuTracker.getLastIrqTime();
2644                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2645                        int idle = mProcessCpuTracker.getLastIdleTime();
2646
2647                        int total = user + system + iowait + irq + softIrq + idle;
2648                        if (total == 0) total = 1;
2649
2650                        EventLog.writeEvent(EventLogTags.CPU,
2651                                ((user+system+iowait+irq+softIrq) * 100) / total,
2652                                (user * 100) / total,
2653                                (system * 100) / total,
2654                                (iowait * 100) / total,
2655                                (irq * 100) / total,
2656                                (softIrq * 100) / total);
2657                    }
2658                }
2659            }
2660
2661            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2662            synchronized(bstats) {
2663                synchronized(mPidsSelfLocked) {
2664                    if (haveNewCpuStats) {
2665                        if (bstats.startAddingCpuLocked()) {
2666                            int totalUTime = 0;
2667                            int totalSTime = 0;
2668                            final int N = mProcessCpuTracker.countStats();
2669                            for (int i=0; i<N; i++) {
2670                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2671                                if (!st.working) {
2672                                    continue;
2673                                }
2674                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2675                                totalUTime += st.rel_utime;
2676                                totalSTime += st.rel_stime;
2677                                if (pr != null) {
2678                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2679                                    if (ps == null || !ps.isActive()) {
2680                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2681                                                pr.info.uid, pr.processName);
2682                                    }
2683                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2684                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2685                                } else {
2686                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2687                                    if (ps == null || !ps.isActive()) {
2688                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2689                                                bstats.mapUid(st.uid), st.name);
2690                                    }
2691                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2692                                }
2693                            }
2694                            final int userTime = mProcessCpuTracker.getLastUserTime();
2695                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2696                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2697                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2698                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2699                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2700                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2701                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2702                        }
2703                    }
2704                }
2705
2706                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2707                    mLastWriteTime = now;
2708                    mBatteryStatsService.scheduleWriteToDisk();
2709                }
2710            }
2711        }
2712    }
2713
2714    @Override
2715    public void batteryNeedsCpuUpdate() {
2716        updateCpuStatsNow();
2717    }
2718
2719    @Override
2720    public void batteryPowerChanged(boolean onBattery) {
2721        // When plugging in, update the CPU stats first before changing
2722        // the plug state.
2723        updateCpuStatsNow();
2724        synchronized (this) {
2725            synchronized(mPidsSelfLocked) {
2726                mOnBattery = DEBUG_POWER ? true : onBattery;
2727            }
2728        }
2729    }
2730
2731    @Override
2732    public void batterySendBroadcast(Intent intent) {
2733        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2734                AppOpsManager.OP_NONE, null, false, false,
2735                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2736    }
2737
2738    /**
2739     * Initialize the application bind args. These are passed to each
2740     * process when the bindApplication() IPC is sent to the process. They're
2741     * lazily setup to make sure the services are running when they're asked for.
2742     */
2743    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2744        if (mAppBindArgs == null) {
2745            mAppBindArgs = new HashMap<>();
2746
2747            // Isolated processes won't get this optimization, so that we don't
2748            // violate the rules about which services they have access to.
2749            if (!isolated) {
2750                // Setup the application init args
2751                mAppBindArgs.put("package", ServiceManager.getService("package"));
2752                mAppBindArgs.put("window", ServiceManager.getService("window"));
2753                mAppBindArgs.put(Context.ALARM_SERVICE,
2754                        ServiceManager.getService(Context.ALARM_SERVICE));
2755            }
2756        }
2757        return mAppBindArgs;
2758    }
2759
2760    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2761        if (r == null || mFocusedActivity == r) {
2762            return false;
2763        }
2764
2765        if (!r.isFocusable()) {
2766            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
2767                    "setFocusedActivityLocked: unfocusable r=" + r);
2768            return false;
2769        }
2770
2771        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2772        final ActivityRecord last = mFocusedActivity;
2773        mFocusedActivity = r;
2774        if (r.task.isApplicationTask()) {
2775            if (mCurAppTimeTracker != r.appTimeTracker) {
2776                // We are switching app tracking.  Complete the current one.
2777                if (mCurAppTimeTracker != null) {
2778                    mCurAppTimeTracker.stop();
2779                    mHandler.obtainMessage(
2780                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2781                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2782                    mCurAppTimeTracker = null;
2783                }
2784                if (r.appTimeTracker != null) {
2785                    mCurAppTimeTracker = r.appTimeTracker;
2786                    startTimeTrackingFocusedActivityLocked();
2787                }
2788            } else {
2789                startTimeTrackingFocusedActivityLocked();
2790            }
2791        } else {
2792            r.appTimeTracker = null;
2793        }
2794        if (r.task.voiceInteractor != null) {
2795            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2796        } else {
2797            finishRunningVoiceLocked();
2798            if (last != null && last.task.voiceSession != null) {
2799                // We had been in a voice interaction session, but now focused has
2800                // move to something different.  Just finish the session, we can't
2801                // return to it and retain the proper state and synchronization with
2802                // the voice interaction service.
2803                finishVoiceTask(last.task.voiceSession);
2804            }
2805        }
2806        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2807            mWindowManager.setFocusedApp(r.appToken, true);
2808        }
2809        applyUpdateLockStateLocked(r);
2810        applyUpdateVrModeLocked(r);
2811        if (mFocusedActivity.userId != mLastFocusedUserId) {
2812            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2813            mHandler.obtainMessage(
2814                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2815            mLastFocusedUserId = mFocusedActivity.userId;
2816        }
2817
2818        EventLogTags.writeAmFocusedActivity(
2819                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2820                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2821                reason);
2822        return true;
2823    }
2824
2825    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2826        if (mFocusedActivity != goingAway) {
2827            return;
2828        }
2829
2830        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2831        if (focusedStack != null) {
2832            final ActivityRecord top = focusedStack.topActivity();
2833            if (top != null && top.userId != mLastFocusedUserId) {
2834                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2835                mHandler.sendMessage(
2836                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2837                mLastFocusedUserId = top.userId;
2838            }
2839        }
2840
2841        // Try to move focus to another activity if possible.
2842        if (setFocusedActivityLocked(
2843                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2844            return;
2845        }
2846
2847        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2848                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2849        mFocusedActivity = null;
2850        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2851    }
2852
2853    @Override
2854    public void setFocusedStack(int stackId) {
2855        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2856        synchronized (ActivityManagerService.this) {
2857            ActivityStack stack = mStackSupervisor.getStack(stackId);
2858            if (stack != null) {
2859                ActivityRecord r = stack.topRunningActivityLocked();
2860                if (r != null) {
2861                    setFocusedActivityLocked(r, "setFocusedStack");
2862                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2863                }
2864            }
2865        }
2866    }
2867
2868    @Override
2869    public void setFocusedTask(int taskId) {
2870        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2871        long callingId = Binder.clearCallingIdentity();
2872        try {
2873            synchronized (ActivityManagerService.this) {
2874                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2875                if (task != null) {
2876                    ActivityRecord r = task.topRunningActivityLocked();
2877                    if (r != null) {
2878                        setFocusedActivityLocked(r, "setFocusedTask");
2879                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
2880                    }
2881                }
2882            }
2883        } finally {
2884            Binder.restoreCallingIdentity(callingId);
2885        }
2886    }
2887
2888    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2889    @Override
2890    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2891        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2892        synchronized (this) {
2893            if (listener != null) {
2894                mTaskStackListeners.register(listener);
2895            }
2896        }
2897    }
2898
2899    @Override
2900    public void notifyActivityDrawn(IBinder token) {
2901        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2902        synchronized (this) {
2903            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2904            if (r != null) {
2905                r.task.stack.notifyActivityDrawnLocked(r);
2906            }
2907        }
2908    }
2909
2910    final void applyUpdateLockStateLocked(ActivityRecord r) {
2911        // Modifications to the UpdateLock state are done on our handler, outside
2912        // the activity manager's locks.  The new state is determined based on the
2913        // state *now* of the relevant activity record.  The object is passed to
2914        // the handler solely for logging detail, not to be consulted/modified.
2915        final boolean nextState = r != null && r.immersive;
2916        mHandler.sendMessage(
2917                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2918    }
2919
2920    final void applyUpdateVrModeLocked(ActivityRecord r) {
2921        mHandler.sendMessage(
2922                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2923    }
2924
2925    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2926        Message msg = Message.obtain();
2927        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2928        msg.obj = r.task.askedCompatMode ? null : r;
2929        mUiHandler.sendMessage(msg);
2930    }
2931
2932    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2933            String what, Object obj, ProcessRecord srcApp) {
2934        app.lastActivityTime = now;
2935
2936        if (app.activities.size() > 0) {
2937            // Don't want to touch dependent processes that are hosting activities.
2938            return index;
2939        }
2940
2941        int lrui = mLruProcesses.lastIndexOf(app);
2942        if (lrui < 0) {
2943            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2944                    + what + " " + obj + " from " + srcApp);
2945            return index;
2946        }
2947
2948        if (lrui >= index) {
2949            // Don't want to cause this to move dependent processes *back* in the
2950            // list as if they were less frequently used.
2951            return index;
2952        }
2953
2954        if (lrui >= mLruProcessActivityStart) {
2955            // Don't want to touch dependent processes that are hosting activities.
2956            return index;
2957        }
2958
2959        mLruProcesses.remove(lrui);
2960        if (index > 0) {
2961            index--;
2962        }
2963        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2964                + " in LRU list: " + app);
2965        mLruProcesses.add(index, app);
2966        return index;
2967    }
2968
2969    private static void killProcessGroup(int uid, int pid) {
2970        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2971        Process.killProcessGroup(uid, pid);
2972        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2973    }
2974
2975    final void removeLruProcessLocked(ProcessRecord app) {
2976        int lrui = mLruProcesses.lastIndexOf(app);
2977        if (lrui >= 0) {
2978            if (!app.killed) {
2979                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2980                Process.killProcessQuiet(app.pid);
2981                killProcessGroup(app.info.uid, app.pid);
2982            }
2983            if (lrui <= mLruProcessActivityStart) {
2984                mLruProcessActivityStart--;
2985            }
2986            if (lrui <= mLruProcessServiceStart) {
2987                mLruProcessServiceStart--;
2988            }
2989            mLruProcesses.remove(lrui);
2990        }
2991    }
2992
2993    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2994            ProcessRecord client) {
2995        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2996                || app.treatLikeActivity;
2997        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2998        if (!activityChange && hasActivity) {
2999            // The process has activities, so we are only allowing activity-based adjustments
3000            // to move it.  It should be kept in the front of the list with other
3001            // processes that have activities, and we don't want those to change their
3002            // order except due to activity operations.
3003            return;
3004        }
3005
3006        mLruSeq++;
3007        final long now = SystemClock.uptimeMillis();
3008        app.lastActivityTime = now;
3009
3010        // First a quick reject: if the app is already at the position we will
3011        // put it, then there is nothing to do.
3012        if (hasActivity) {
3013            final int N = mLruProcesses.size();
3014            if (N > 0 && mLruProcesses.get(N-1) == app) {
3015                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3016                return;
3017            }
3018        } else {
3019            if (mLruProcessServiceStart > 0
3020                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3021                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3022                return;
3023            }
3024        }
3025
3026        int lrui = mLruProcesses.lastIndexOf(app);
3027
3028        if (app.persistent && lrui >= 0) {
3029            // We don't care about the position of persistent processes, as long as
3030            // they are in the list.
3031            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3032            return;
3033        }
3034
3035        /* In progress: compute new position first, so we can avoid doing work
3036           if the process is not actually going to move.  Not yet working.
3037        int addIndex;
3038        int nextIndex;
3039        boolean inActivity = false, inService = false;
3040        if (hasActivity) {
3041            // Process has activities, put it at the very tipsy-top.
3042            addIndex = mLruProcesses.size();
3043            nextIndex = mLruProcessServiceStart;
3044            inActivity = true;
3045        } else if (hasService) {
3046            // Process has services, put it at the top of the service list.
3047            addIndex = mLruProcessActivityStart;
3048            nextIndex = mLruProcessServiceStart;
3049            inActivity = true;
3050            inService = true;
3051        } else  {
3052            // Process not otherwise of interest, it goes to the top of the non-service area.
3053            addIndex = mLruProcessServiceStart;
3054            if (client != null) {
3055                int clientIndex = mLruProcesses.lastIndexOf(client);
3056                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3057                        + app);
3058                if (clientIndex >= 0 && addIndex > clientIndex) {
3059                    addIndex = clientIndex;
3060                }
3061            }
3062            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3063        }
3064
3065        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3066                + mLruProcessActivityStart + "): " + app);
3067        */
3068
3069        if (lrui >= 0) {
3070            if (lrui < mLruProcessActivityStart) {
3071                mLruProcessActivityStart--;
3072            }
3073            if (lrui < mLruProcessServiceStart) {
3074                mLruProcessServiceStart--;
3075            }
3076            /*
3077            if (addIndex > lrui) {
3078                addIndex--;
3079            }
3080            if (nextIndex > lrui) {
3081                nextIndex--;
3082            }
3083            */
3084            mLruProcesses.remove(lrui);
3085        }
3086
3087        /*
3088        mLruProcesses.add(addIndex, app);
3089        if (inActivity) {
3090            mLruProcessActivityStart++;
3091        }
3092        if (inService) {
3093            mLruProcessActivityStart++;
3094        }
3095        */
3096
3097        int nextIndex;
3098        if (hasActivity) {
3099            final int N = mLruProcesses.size();
3100            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3101                // Process doesn't have activities, but has clients with
3102                // activities...  move it up, but one below the top (the top
3103                // should always have a real activity).
3104                if (DEBUG_LRU) Slog.d(TAG_LRU,
3105                        "Adding to second-top of LRU activity list: " + app);
3106                mLruProcesses.add(N - 1, app);
3107                // To keep it from spamming the LRU list (by making a bunch of clients),
3108                // we will push down any other entries owned by the app.
3109                final int uid = app.info.uid;
3110                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3111                    ProcessRecord subProc = mLruProcesses.get(i);
3112                    if (subProc.info.uid == uid) {
3113                        // We want to push this one down the list.  If the process after
3114                        // it is for the same uid, however, don't do so, because we don't
3115                        // want them internally to be re-ordered.
3116                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3117                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3118                                    "Pushing uid " + uid + " swapping at " + i + ": "
3119                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3120                            ProcessRecord tmp = mLruProcesses.get(i);
3121                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3122                            mLruProcesses.set(i - 1, tmp);
3123                            i--;
3124                        }
3125                    } else {
3126                        // A gap, we can stop here.
3127                        break;
3128                    }
3129                }
3130            } else {
3131                // Process has activities, put it at the very tipsy-top.
3132                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3133                mLruProcesses.add(app);
3134            }
3135            nextIndex = mLruProcessServiceStart;
3136        } else if (hasService) {
3137            // Process has services, put it at the top of the service list.
3138            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3139            mLruProcesses.add(mLruProcessActivityStart, app);
3140            nextIndex = mLruProcessServiceStart;
3141            mLruProcessActivityStart++;
3142        } else  {
3143            // Process not otherwise of interest, it goes to the top of the non-service area.
3144            int index = mLruProcessServiceStart;
3145            if (client != null) {
3146                // If there is a client, don't allow the process to be moved up higher
3147                // in the list than that client.
3148                int clientIndex = mLruProcesses.lastIndexOf(client);
3149                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3150                        + " when updating " + app);
3151                if (clientIndex <= lrui) {
3152                    // Don't allow the client index restriction to push it down farther in the
3153                    // list than it already is.
3154                    clientIndex = lrui;
3155                }
3156                if (clientIndex >= 0 && index > clientIndex) {
3157                    index = clientIndex;
3158                }
3159            }
3160            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3161            mLruProcesses.add(index, app);
3162            nextIndex = index-1;
3163            mLruProcessActivityStart++;
3164            mLruProcessServiceStart++;
3165        }
3166
3167        // If the app is currently using a content provider or service,
3168        // bump those processes as well.
3169        for (int j=app.connections.size()-1; j>=0; j--) {
3170            ConnectionRecord cr = app.connections.valueAt(j);
3171            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3172                    && cr.binding.service.app != null
3173                    && cr.binding.service.app.lruSeq != mLruSeq
3174                    && !cr.binding.service.app.persistent) {
3175                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3176                        "service connection", cr, app);
3177            }
3178        }
3179        for (int j=app.conProviders.size()-1; j>=0; j--) {
3180            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3181            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3182                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3183                        "provider reference", cpr, app);
3184            }
3185        }
3186    }
3187
3188    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3189        if (uid == Process.SYSTEM_UID) {
3190            // The system gets to run in any process.  If there are multiple
3191            // processes with the same uid, just pick the first (this
3192            // should never happen).
3193            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3194            if (procs == null) return null;
3195            final int procCount = procs.size();
3196            for (int i = 0; i < procCount; i++) {
3197                final int procUid = procs.keyAt(i);
3198                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3199                    // Don't use an app process or different user process for system component.
3200                    continue;
3201                }
3202                return procs.valueAt(i);
3203            }
3204        }
3205        ProcessRecord proc = mProcessNames.get(processName, uid);
3206        if (false && proc != null && !keepIfLarge
3207                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3208                && proc.lastCachedPss >= 4000) {
3209            // Turn this condition on to cause killing to happen regularly, for testing.
3210            if (proc.baseProcessTracker != null) {
3211                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3212            }
3213            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3214        } else if (proc != null && !keepIfLarge
3215                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3216                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3217            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3218            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3219                if (proc.baseProcessTracker != null) {
3220                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3221                }
3222                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3223            }
3224        }
3225        return proc;
3226    }
3227
3228    void notifyPackageUse(String packageName) {
3229        IPackageManager pm = AppGlobals.getPackageManager();
3230        try {
3231            pm.notifyPackageUse(packageName);
3232        } catch (RemoteException e) {
3233        }
3234    }
3235
3236    boolean isNextTransitionForward() {
3237        int transit = mWindowManager.getPendingAppTransition();
3238        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3239                || transit == AppTransition.TRANSIT_TASK_OPEN
3240                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3241    }
3242
3243    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3244            String processName, String abiOverride, int uid, Runnable crashHandler) {
3245        synchronized(this) {
3246            ApplicationInfo info = new ApplicationInfo();
3247            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3248            // For isolated processes, the former contains the parent's uid and the latter the
3249            // actual uid of the isolated process.
3250            // In the special case introduced by this method (which is, starting an isolated
3251            // process directly from the SystemServer without an actual parent app process) the
3252            // closest thing to a parent's uid is SYSTEM_UID.
3253            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3254            // the |isolated| logic in the ProcessRecord constructor.
3255            info.uid = Process.SYSTEM_UID;
3256            info.processName = processName;
3257            info.className = entryPoint;
3258            info.packageName = "android";
3259            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3260                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3261                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3262                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3263                    crashHandler);
3264            return proc != null ? proc.pid : 0;
3265        }
3266    }
3267
3268    final ProcessRecord startProcessLocked(String processName,
3269            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3270            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3271            boolean isolated, boolean keepIfLarge) {
3272        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3273                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3274                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3275                null /* crashHandler */);
3276    }
3277
3278    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3279            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3280            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3281            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3282        long startTime = SystemClock.elapsedRealtime();
3283        ProcessRecord app;
3284        if (!isolated) {
3285            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3286            checkTime(startTime, "startProcess: after getProcessRecord");
3287
3288            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3289                // If we are in the background, then check to see if this process
3290                // is bad.  If so, we will just silently fail.
3291                if (mBadProcesses.get(info.processName, info.uid) != null) {
3292                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3293                            + "/" + info.processName);
3294                    return null;
3295                }
3296            } else {
3297                // When the user is explicitly starting a process, then clear its
3298                // crash count so that we won't make it bad until they see at
3299                // least one crash dialog again, and make the process good again
3300                // if it had been bad.
3301                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3302                        + "/" + info.processName);
3303                mProcessCrashTimes.remove(info.processName, info.uid);
3304                if (mBadProcesses.get(info.processName, info.uid) != null) {
3305                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3306                            UserHandle.getUserId(info.uid), info.uid,
3307                            info.processName);
3308                    mBadProcesses.remove(info.processName, info.uid);
3309                    if (app != null) {
3310                        app.bad = false;
3311                    }
3312                }
3313            }
3314        } else {
3315            // If this is an isolated process, it can't re-use an existing process.
3316            app = null;
3317        }
3318
3319        // app launch boost for big.little configurations
3320        // use cpusets to migrate freshly launched tasks to big cores
3321        synchronized(ActivityManagerService.this) {
3322            nativeMigrateToBoost();
3323            mIsBoosted = true;
3324            mBoostStartTime = SystemClock.uptimeMillis();
3325            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3326            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3327        }
3328
3329        // We don't have to do anything more if:
3330        // (1) There is an existing application record; and
3331        // (2) The caller doesn't think it is dead, OR there is no thread
3332        //     object attached to it so we know it couldn't have crashed; and
3333        // (3) There is a pid assigned to it, so it is either starting or
3334        //     already running.
3335        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3336                + " app=" + app + " knownToBeDead=" + knownToBeDead
3337                + " thread=" + (app != null ? app.thread : null)
3338                + " pid=" + (app != null ? app.pid : -1));
3339        if (app != null && app.pid > 0) {
3340            if (!knownToBeDead || app.thread == null) {
3341                // We already have the app running, or are waiting for it to
3342                // come up (we have a pid but not yet its thread), so keep it.
3343                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3344                // If this is a new package in the process, add the package to the list
3345                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3346                checkTime(startTime, "startProcess: done, added package to proc");
3347                return app;
3348            }
3349
3350            // An application record is attached to a previous process,
3351            // clean it up now.
3352            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3353            checkTime(startTime, "startProcess: bad proc running, killing");
3354            killProcessGroup(app.info.uid, app.pid);
3355            handleAppDiedLocked(app, true, true);
3356            checkTime(startTime, "startProcess: done killing old proc");
3357        }
3358
3359        String hostingNameStr = hostingName != null
3360                ? hostingName.flattenToShortString() : null;
3361
3362        if (app == null) {
3363            checkTime(startTime, "startProcess: creating new process record");
3364            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3365            if (app == null) {
3366                Slog.w(TAG, "Failed making new process record for "
3367                        + processName + "/" + info.uid + " isolated=" + isolated);
3368                return null;
3369            }
3370            app.crashHandler = crashHandler;
3371            checkTime(startTime, "startProcess: done creating new process record");
3372        } else {
3373            // If this is a new package in the process, add the package to the list
3374            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3375            checkTime(startTime, "startProcess: added package to existing proc");
3376        }
3377
3378        // If the system is not ready yet, then hold off on starting this
3379        // process until it is.
3380        if (!mProcessesReady
3381                && !isAllowedWhileBooting(info)
3382                && !allowWhileBooting) {
3383            if (!mProcessesOnHold.contains(app)) {
3384                mProcessesOnHold.add(app);
3385            }
3386            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3387                    "System not ready, putting on hold: " + app);
3388            checkTime(startTime, "startProcess: returning with proc on hold");
3389            return app;
3390        }
3391
3392        checkTime(startTime, "startProcess: stepping in to startProcess");
3393        startProcessLocked(
3394                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3395        checkTime(startTime, "startProcess: done starting proc!");
3396        return (app.pid != 0) ? app : null;
3397    }
3398
3399    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3400        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3401    }
3402
3403    private final void startProcessLocked(ProcessRecord app,
3404            String hostingType, String hostingNameStr) {
3405        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3406                null /* entryPoint */, null /* entryPointArgs */);
3407    }
3408
3409    private final void startProcessLocked(ProcessRecord app, String hostingType,
3410            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3411        long startTime = SystemClock.elapsedRealtime();
3412        if (app.pid > 0 && app.pid != MY_PID) {
3413            checkTime(startTime, "startProcess: removing from pids map");
3414            synchronized (mPidsSelfLocked) {
3415                mPidsSelfLocked.remove(app.pid);
3416                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3417            }
3418            checkTime(startTime, "startProcess: done removing from pids map");
3419            app.setPid(0);
3420        }
3421
3422        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3423                "startProcessLocked removing on hold: " + app);
3424        mProcessesOnHold.remove(app);
3425
3426        checkTime(startTime, "startProcess: starting to update cpu stats");
3427        updateCpuStats();
3428        checkTime(startTime, "startProcess: done updating cpu stats");
3429
3430        try {
3431            try {
3432                final int userId = UserHandle.getUserId(app.uid);
3433                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3434            } catch (RemoteException e) {
3435                throw e.rethrowAsRuntimeException();
3436            }
3437
3438            int uid = app.uid;
3439            int[] gids = null;
3440            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3441            if (!app.isolated) {
3442                int[] permGids = null;
3443                try {
3444                    checkTime(startTime, "startProcess: getting gids from package manager");
3445                    final IPackageManager pm = AppGlobals.getPackageManager();
3446                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3447                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3448                            MountServiceInternal.class);
3449                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3450                            app.info.packageName);
3451                } catch (RemoteException e) {
3452                    throw e.rethrowAsRuntimeException();
3453                }
3454
3455                /*
3456                 * Add shared application and profile GIDs so applications can share some
3457                 * resources like shared libraries and access user-wide resources
3458                 */
3459                if (ArrayUtils.isEmpty(permGids)) {
3460                    gids = new int[2];
3461                } else {
3462                    gids = new int[permGids.length + 2];
3463                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3464                }
3465                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3466                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3467            }
3468            checkTime(startTime, "startProcess: building args");
3469            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3470                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3471                        && mTopComponent != null
3472                        && app.processName.equals(mTopComponent.getPackageName())) {
3473                    uid = 0;
3474                }
3475                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3476                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3477                    uid = 0;
3478                }
3479            }
3480            int debugFlags = 0;
3481            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3482                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3483                // Also turn on CheckJNI for debuggable apps. It's quite
3484                // awkward to turn on otherwise.
3485                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3486            }
3487            // Run the app in safe mode if its manifest requests so or the
3488            // system is booted in safe mode.
3489            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3490                mSafeMode == true) {
3491                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3492            }
3493            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3494                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3495            }
3496            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3497            if ("true".equals(genDebugInfoProperty)) {
3498                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3499            }
3500            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3501                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3502            }
3503            if ("1".equals(SystemProperties.get("debug.assert"))) {
3504                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3505            }
3506
3507            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3508            if (requiredAbi == null) {
3509                requiredAbi = Build.SUPPORTED_ABIS[0];
3510            }
3511
3512            String instructionSet = null;
3513            if (app.info.primaryCpuAbi != null) {
3514                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3515            }
3516
3517            app.gids = gids;
3518            app.requiredAbi = requiredAbi;
3519            app.instructionSet = instructionSet;
3520
3521            // Start the process.  It will either succeed and return a result containing
3522            // the PID of the new process, or else throw a RuntimeException.
3523            boolean isActivityProcess = (entryPoint == null);
3524            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3525            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3526                    app.processName);
3527            checkTime(startTime, "startProcess: asking zygote to start proc");
3528            Process.ProcessStartResult startResult = Process.start(entryPoint,
3529                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3530                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3531                    app.info.dataDir, entryPointArgs);
3532            checkTime(startTime, "startProcess: returned from zygote!");
3533            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3534
3535            if (app.isolated) {
3536                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3537            }
3538            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3539            checkTime(startTime, "startProcess: done updating battery stats");
3540
3541            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3542                    UserHandle.getUserId(uid), startResult.pid, uid,
3543                    app.processName, hostingType,
3544                    hostingNameStr != null ? hostingNameStr : "");
3545
3546            if (app.persistent) {
3547                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3548            }
3549
3550            if (DEBUG_PROCESSES) {
3551                checkTime(startTime, "startProcess: building log message");
3552                StringBuilder buf = mStringBuilder;
3553                buf.setLength(0);
3554                buf.append("Start proc ");
3555                buf.append(startResult.pid);
3556                buf.append(':');
3557                buf.append(app.processName);
3558                buf.append('/');
3559                UserHandle.formatUid(buf, uid);
3560                if (!isActivityProcess) {
3561                    buf.append(" [");
3562                    buf.append(entryPoint);
3563                    buf.append("]");
3564                }
3565                buf.append(" for ");
3566                buf.append(hostingType);
3567                if (hostingNameStr != null) {
3568                    buf.append(" ");
3569                    buf.append(hostingNameStr);
3570                }
3571                Slog.i(TAG, buf.toString());
3572            }
3573            app.setPid(startResult.pid);
3574            app.usingWrapper = startResult.usingWrapper;
3575            app.removed = false;
3576            app.killed = false;
3577            app.killedByAm = false;
3578            checkTime(startTime, "startProcess: starting to update pids map");
3579            synchronized (mPidsSelfLocked) {
3580                this.mPidsSelfLocked.put(startResult.pid, app);
3581                if (isActivityProcess) {
3582                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3583                    msg.obj = app;
3584                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3585                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3586                }
3587            }
3588            checkTime(startTime, "startProcess: done updating pids map");
3589        } catch (RuntimeException e) {
3590            // XXX do better error recovery.
3591            app.setPid(0);
3592            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3593            if (app.isolated) {
3594                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3595            }
3596            Slog.e(TAG, "Failure starting process " + app.processName, e);
3597        }
3598    }
3599
3600    void updateUsageStats(ActivityRecord component, boolean resumed) {
3601        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3602                "updateUsageStats: comp=" + component + "res=" + resumed);
3603        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3604        if (resumed) {
3605            if (mUsageStatsService != null) {
3606                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3607                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3608            }
3609            synchronized (stats) {
3610                stats.noteActivityResumedLocked(component.app.uid);
3611            }
3612        } else {
3613            if (mUsageStatsService != null) {
3614                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3615                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3616            }
3617            synchronized (stats) {
3618                stats.noteActivityPausedLocked(component.app.uid);
3619            }
3620        }
3621    }
3622
3623    Intent getHomeIntent() {
3624        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3625        intent.setComponent(mTopComponent);
3626        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3627        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3628            intent.addCategory(Intent.CATEGORY_HOME);
3629        }
3630        return intent;
3631    }
3632
3633    boolean startHomeActivityLocked(int userId, String reason) {
3634        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3635                && mTopAction == null) {
3636            // We are running in factory test mode, but unable to find
3637            // the factory test app, so just sit around displaying the
3638            // error message and don't try to start anything.
3639            return false;
3640        }
3641        Intent intent = getHomeIntent();
3642        ActivityInfo aInfo =
3643            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3644        if (aInfo != null) {
3645            intent.setComponent(new ComponentName(
3646                    aInfo.applicationInfo.packageName, aInfo.name));
3647            // Don't do this if the home app is currently being
3648            // instrumented.
3649            aInfo = new ActivityInfo(aInfo);
3650            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3651            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3652                    aInfo.applicationInfo.uid, true);
3653            if (app == null || app.instrumentationClass == null) {
3654                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3655                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3656            }
3657        }
3658
3659        return true;
3660    }
3661
3662    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3663        ActivityInfo ai = null;
3664        ComponentName comp = intent.getComponent();
3665        try {
3666            if (comp != null) {
3667                // Factory test.
3668                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3669            } else {
3670                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3671                        intent,
3672                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3673                        flags, userId);
3674
3675                if (info != null) {
3676                    ai = info.activityInfo;
3677                }
3678            }
3679        } catch (RemoteException e) {
3680            // ignore
3681        }
3682
3683        return ai;
3684    }
3685
3686    /**
3687     * Starts the "new version setup screen" if appropriate.
3688     */
3689    void startSetupActivityLocked() {
3690        // Only do this once per boot.
3691        if (mCheckedForSetup) {
3692            return;
3693        }
3694
3695        // We will show this screen if the current one is a different
3696        // version than the last one shown, and we are not running in
3697        // low-level factory test mode.
3698        final ContentResolver resolver = mContext.getContentResolver();
3699        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3700                Settings.Global.getInt(resolver,
3701                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3702            mCheckedForSetup = true;
3703
3704            // See if we should be showing the platform update setup UI.
3705            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3706            List<ResolveInfo> ris = mContext.getPackageManager()
3707                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3708
3709            // We don't allow third party apps to replace this.
3710            ResolveInfo ri = null;
3711            for (int i=0; ris != null && i<ris.size(); i++) {
3712                if ((ris.get(i).activityInfo.applicationInfo.flags
3713                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3714                    ri = ris.get(i);
3715                    break;
3716                }
3717            }
3718
3719            if (ri != null) {
3720                String vers = ri.activityInfo.metaData != null
3721                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3722                        : null;
3723                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3724                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3725                            Intent.METADATA_SETUP_VERSION);
3726                }
3727                String lastVers = Settings.Secure.getString(
3728                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3729                if (vers != null && !vers.equals(lastVers)) {
3730                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3731                    intent.setComponent(new ComponentName(
3732                            ri.activityInfo.packageName, ri.activityInfo.name));
3733                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3734                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3735                            null, 0, 0, 0, null, false, false, null, null, null);
3736                }
3737            }
3738        }
3739    }
3740
3741    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3742        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3743    }
3744
3745    void enforceNotIsolatedCaller(String caller) {
3746        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3747            throw new SecurityException("Isolated process not allowed to call " + caller);
3748        }
3749    }
3750
3751    void enforceShellRestriction(String restriction, int userHandle) {
3752        if (Binder.getCallingUid() == Process.SHELL_UID) {
3753            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3754                throw new SecurityException("Shell does not have permission to access user "
3755                        + userHandle);
3756            }
3757        }
3758    }
3759
3760    @Override
3761    public int getFrontActivityScreenCompatMode() {
3762        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3763        synchronized (this) {
3764            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3765        }
3766    }
3767
3768    @Override
3769    public void setFrontActivityScreenCompatMode(int mode) {
3770        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3771                "setFrontActivityScreenCompatMode");
3772        synchronized (this) {
3773            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3774        }
3775    }
3776
3777    @Override
3778    public int getPackageScreenCompatMode(String packageName) {
3779        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3780        synchronized (this) {
3781            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3782        }
3783    }
3784
3785    @Override
3786    public void setPackageScreenCompatMode(String packageName, int mode) {
3787        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3788                "setPackageScreenCompatMode");
3789        synchronized (this) {
3790            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3791        }
3792    }
3793
3794    @Override
3795    public boolean getPackageAskScreenCompat(String packageName) {
3796        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3797        synchronized (this) {
3798            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3799        }
3800    }
3801
3802    @Override
3803    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3804        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3805                "setPackageAskScreenCompat");
3806        synchronized (this) {
3807            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3808        }
3809    }
3810
3811    private boolean hasUsageStatsPermission(String callingPackage) {
3812        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3813                Binder.getCallingUid(), callingPackage);
3814        if (mode == AppOpsManager.MODE_DEFAULT) {
3815            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3816                    == PackageManager.PERMISSION_GRANTED;
3817        }
3818        return mode == AppOpsManager.MODE_ALLOWED;
3819    }
3820
3821    @Override
3822    public int getPackageProcessState(String packageName, String callingPackage) {
3823        if (!hasUsageStatsPermission(callingPackage)) {
3824            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3825                    "getPackageProcessState");
3826        }
3827
3828        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3829        synchronized (this) {
3830            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3831                final ProcessRecord proc = mLruProcesses.get(i);
3832                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3833                        || procState > proc.setProcState) {
3834                    boolean found = false;
3835                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3836                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3837                            procState = proc.setProcState;
3838                            found = true;
3839                        }
3840                    }
3841                    if (proc.pkgDeps != null && !found) {
3842                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3843                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3844                                procState = proc.setProcState;
3845                                break;
3846                            }
3847                        }
3848                    }
3849                }
3850            }
3851        }
3852        return procState;
3853    }
3854
3855    @Override
3856    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3857        synchronized (this) {
3858            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3859            if (app == null) {
3860                return false;
3861            }
3862            if (app.trimMemoryLevel < level && app.thread != null &&
3863                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3864                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3865                try {
3866                    app.thread.scheduleTrimMemory(level);
3867                    app.trimMemoryLevel = level;
3868                    return true;
3869                } catch (RemoteException e) {
3870                    // Fallthrough to failure case.
3871                }
3872            }
3873        }
3874        return false;
3875    }
3876
3877    private void dispatchProcessesChanged() {
3878        int N;
3879        synchronized (this) {
3880            N = mPendingProcessChanges.size();
3881            if (mActiveProcessChanges.length < N) {
3882                mActiveProcessChanges = new ProcessChangeItem[N];
3883            }
3884            mPendingProcessChanges.toArray(mActiveProcessChanges);
3885            mPendingProcessChanges.clear();
3886            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3887                    "*** Delivering " + N + " process changes");
3888        }
3889
3890        int i = mProcessObservers.beginBroadcast();
3891        while (i > 0) {
3892            i--;
3893            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3894            if (observer != null) {
3895                try {
3896                    for (int j=0; j<N; j++) {
3897                        ProcessChangeItem item = mActiveProcessChanges[j];
3898                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3899                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3900                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3901                                    + item.uid + ": " + item.foregroundActivities);
3902                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3903                                    item.foregroundActivities);
3904                        }
3905                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3906                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3907                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3908                                    + ": " + item.processState);
3909                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3910                        }
3911                    }
3912                } catch (RemoteException e) {
3913                }
3914            }
3915        }
3916        mProcessObservers.finishBroadcast();
3917
3918        synchronized (this) {
3919            for (int j=0; j<N; j++) {
3920                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3921            }
3922        }
3923    }
3924
3925    private void dispatchProcessDied(int pid, int uid) {
3926        int i = mProcessObservers.beginBroadcast();
3927        while (i > 0) {
3928            i--;
3929            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3930            if (observer != null) {
3931                try {
3932                    observer.onProcessDied(pid, uid);
3933                } catch (RemoteException e) {
3934                }
3935            }
3936        }
3937        mProcessObservers.finishBroadcast();
3938    }
3939
3940    private void dispatchUidsChanged() {
3941        int N;
3942        synchronized (this) {
3943            N = mPendingUidChanges.size();
3944            if (mActiveUidChanges.length < N) {
3945                mActiveUidChanges = new UidRecord.ChangeItem[N];
3946            }
3947            for (int i=0; i<N; i++) {
3948                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3949                mActiveUidChanges[i] = change;
3950                if (change.uidRecord != null) {
3951                    change.uidRecord.pendingChange = null;
3952                    change.uidRecord = null;
3953                }
3954            }
3955            mPendingUidChanges.clear();
3956            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3957                    "*** Delivering " + N + " uid changes");
3958        }
3959
3960        if (mLocalPowerManager != null) {
3961            for (int j=0; j<N; j++) {
3962                UidRecord.ChangeItem item = mActiveUidChanges[j];
3963                if (item.change == UidRecord.CHANGE_GONE
3964                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3965                    mLocalPowerManager.uidGone(item.uid);
3966                } else {
3967                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3968                }
3969            }
3970        }
3971
3972        int i = mUidObservers.beginBroadcast();
3973        while (i > 0) {
3974            i--;
3975            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3976            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3977            if (observer != null) {
3978                try {
3979                    for (int j=0; j<N; j++) {
3980                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3981                        final int change = item.change;
3982                        UidRecord validateUid = null;
3983                        if (VALIDATE_UID_STATES && i == 0) {
3984                            validateUid = mValidateUids.get(item.uid);
3985                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3986                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3987                                validateUid = new UidRecord(item.uid);
3988                                mValidateUids.put(item.uid, validateUid);
3989                            }
3990                        }
3991                        if (change == UidRecord.CHANGE_IDLE
3992                                || change == UidRecord.CHANGE_GONE_IDLE) {
3993                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3994                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3995                                        "UID idle uid=" + item.uid);
3996                                observer.onUidIdle(item.uid);
3997                            }
3998                            if (VALIDATE_UID_STATES && i == 0) {
3999                                if (validateUid != null) {
4000                                    validateUid.idle = true;
4001                                }
4002                            }
4003                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4004                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4005                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4006                                        "UID active uid=" + item.uid);
4007                                observer.onUidActive(item.uid);
4008                            }
4009                            if (VALIDATE_UID_STATES && i == 0) {
4010                                validateUid.idle = false;
4011                            }
4012                        }
4013                        if (change == UidRecord.CHANGE_GONE
4014                                || change == UidRecord.CHANGE_GONE_IDLE) {
4015                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4016                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4017                                        "UID gone uid=" + item.uid);
4018                                observer.onUidGone(item.uid);
4019                            }
4020                            if (VALIDATE_UID_STATES && i == 0) {
4021                                if (validateUid != null) {
4022                                    mValidateUids.remove(item.uid);
4023                                }
4024                            }
4025                        } else {
4026                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4027                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4028                                        "UID CHANGED uid=" + item.uid
4029                                                + ": " + item.processState);
4030                                observer.onUidStateChanged(item.uid, item.processState);
4031                            }
4032                            if (VALIDATE_UID_STATES && i == 0) {
4033                                validateUid.curProcState = validateUid.setProcState
4034                                        = item.processState;
4035                            }
4036                        }
4037                    }
4038                } catch (RemoteException e) {
4039                }
4040            }
4041        }
4042        mUidObservers.finishBroadcast();
4043
4044        synchronized (this) {
4045            for (int j=0; j<N; j++) {
4046                mAvailUidChanges.add(mActiveUidChanges[j]);
4047            }
4048        }
4049    }
4050
4051    @Override
4052    public final int startActivity(IApplicationThread caller, String callingPackage,
4053            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4054            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4055        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4056                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4057                UserHandle.getCallingUserId());
4058    }
4059
4060    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4061        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4062        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4063                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4064                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4065
4066        // TODO: Switch to user app stacks here.
4067        String mimeType = intent.getType();
4068        final Uri data = intent.getData();
4069        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4070            mimeType = getProviderMimeType(data, userId);
4071        }
4072        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4073
4074        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4075        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4076                null, 0, 0, null, null, null, null, false, userId, container, null);
4077    }
4078
4079    @Override
4080    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4081            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4082            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4083        enforceNotIsolatedCaller("startActivity");
4084        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4085                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4086        // TODO: Switch to user app stacks here.
4087        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4088                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4089                profilerInfo, null, null, bOptions, false, userId, null, null);
4090    }
4091
4092    @Override
4093    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4094            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4095            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4096            int userId) {
4097
4098        // This is very dangerous -- it allows you to perform a start activity (including
4099        // permission grants) as any app that may launch one of your own activities.  So
4100        // we will only allow this to be done from activities that are part of the core framework,
4101        // and then only when they are running as the system.
4102        final ActivityRecord sourceRecord;
4103        final int targetUid;
4104        final String targetPackage;
4105        synchronized (this) {
4106            if (resultTo == null) {
4107                throw new SecurityException("Must be called from an activity");
4108            }
4109            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4110            if (sourceRecord == null) {
4111                throw new SecurityException("Called with bad activity token: " + resultTo);
4112            }
4113            if (!sourceRecord.info.packageName.equals("android")) {
4114                throw new SecurityException(
4115                        "Must be called from an activity that is declared in the android package");
4116            }
4117            if (sourceRecord.app == null) {
4118                throw new SecurityException("Called without a process attached to activity");
4119            }
4120            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4121                // This is still okay, as long as this activity is running under the
4122                // uid of the original calling activity.
4123                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4124                    throw new SecurityException(
4125                            "Calling activity in uid " + sourceRecord.app.uid
4126                                    + " must be system uid or original calling uid "
4127                                    + sourceRecord.launchedFromUid);
4128                }
4129            }
4130            if (ignoreTargetSecurity) {
4131                if (intent.getComponent() == null) {
4132                    throw new SecurityException(
4133                            "Component must be specified with ignoreTargetSecurity");
4134                }
4135                if (intent.getSelector() != null) {
4136                    throw new SecurityException(
4137                            "Selector not allowed with ignoreTargetSecurity");
4138                }
4139            }
4140            targetUid = sourceRecord.launchedFromUid;
4141            targetPackage = sourceRecord.launchedFromPackage;
4142        }
4143
4144        if (userId == UserHandle.USER_NULL) {
4145            userId = UserHandle.getUserId(sourceRecord.app.uid);
4146        }
4147
4148        // TODO: Switch to user app stacks here.
4149        try {
4150            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4151                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4152                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4153            return ret;
4154        } catch (SecurityException e) {
4155            // XXX need to figure out how to propagate to original app.
4156            // A SecurityException here is generally actually a fault of the original
4157            // calling activity (such as a fairly granting permissions), so propagate it
4158            // back to them.
4159            /*
4160            StringBuilder msg = new StringBuilder();
4161            msg.append("While launching");
4162            msg.append(intent.toString());
4163            msg.append(": ");
4164            msg.append(e.getMessage());
4165            */
4166            throw e;
4167        }
4168    }
4169
4170    @Override
4171    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4172            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4173            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4174        enforceNotIsolatedCaller("startActivityAndWait");
4175        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4176                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4177        WaitResult res = new WaitResult();
4178        // TODO: Switch to user app stacks here.
4179        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4180                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4181                bOptions, false, userId, null, null);
4182        return res;
4183    }
4184
4185    @Override
4186    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4187            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4188            int startFlags, Configuration config, Bundle bOptions, int userId) {
4189        enforceNotIsolatedCaller("startActivityWithConfig");
4190        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4191                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4192        // TODO: Switch to user app stacks here.
4193        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4194                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4195                null, null, config, bOptions, false, userId, null, null);
4196        return ret;
4197    }
4198
4199    @Override
4200    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4201            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4202            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4203            throws TransactionTooLargeException {
4204        enforceNotIsolatedCaller("startActivityIntentSender");
4205        // Refuse possible leaked file descriptors
4206        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4207            throw new IllegalArgumentException("File descriptors passed in Intent");
4208        }
4209
4210        IIntentSender sender = intent.getTarget();
4211        if (!(sender instanceof PendingIntentRecord)) {
4212            throw new IllegalArgumentException("Bad PendingIntent object");
4213        }
4214
4215        PendingIntentRecord pir = (PendingIntentRecord)sender;
4216
4217        synchronized (this) {
4218            // If this is coming from the currently resumed activity, it is
4219            // effectively saying that app switches are allowed at this point.
4220            final ActivityStack stack = getFocusedStack();
4221            if (stack.mResumedActivity != null &&
4222                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4223                mAppSwitchesAllowedTime = 0;
4224            }
4225        }
4226        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4227                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4228        return ret;
4229    }
4230
4231    @Override
4232    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4233            Intent intent, String resolvedType, IVoiceInteractionSession session,
4234            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4235            Bundle bOptions, int userId) {
4236        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4237                != PackageManager.PERMISSION_GRANTED) {
4238            String msg = "Permission Denial: startVoiceActivity() from pid="
4239                    + Binder.getCallingPid()
4240                    + ", uid=" + Binder.getCallingUid()
4241                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4242            Slog.w(TAG, msg);
4243            throw new SecurityException(msg);
4244        }
4245        if (session == null || interactor == null) {
4246            throw new NullPointerException("null session or interactor");
4247        }
4248        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4249                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4250        // TODO: Switch to user app stacks here.
4251        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4252                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4253                null, bOptions, false, userId, null, null);
4254    }
4255
4256    @Override
4257    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4258        synchronized (this) {
4259            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4260                if (keepAwake) {
4261                    mVoiceWakeLock.acquire();
4262                } else {
4263                    mVoiceWakeLock.release();
4264                }
4265            }
4266        }
4267    }
4268
4269    @Override
4270    public boolean startNextMatchingActivity(IBinder callingActivity,
4271            Intent intent, Bundle bOptions) {
4272        // Refuse possible leaked file descriptors
4273        if (intent != null && intent.hasFileDescriptors() == true) {
4274            throw new IllegalArgumentException("File descriptors passed in Intent");
4275        }
4276        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4277
4278        synchronized (this) {
4279            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4280            if (r == null) {
4281                ActivityOptions.abort(options);
4282                return false;
4283            }
4284            if (r.app == null || r.app.thread == null) {
4285                // The caller is not running...  d'oh!
4286                ActivityOptions.abort(options);
4287                return false;
4288            }
4289            intent = new Intent(intent);
4290            // The caller is not allowed to change the data.
4291            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4292            // And we are resetting to find the next component...
4293            intent.setComponent(null);
4294
4295            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4296
4297            ActivityInfo aInfo = null;
4298            try {
4299                List<ResolveInfo> resolves =
4300                    AppGlobals.getPackageManager().queryIntentActivities(
4301                            intent, r.resolvedType,
4302                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4303                            UserHandle.getCallingUserId());
4304
4305                // Look for the original activity in the list...
4306                final int N = resolves != null ? resolves.size() : 0;
4307                for (int i=0; i<N; i++) {
4308                    ResolveInfo rInfo = resolves.get(i);
4309                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4310                            && rInfo.activityInfo.name.equals(r.info.name)) {
4311                        // We found the current one...  the next matching is
4312                        // after it.
4313                        i++;
4314                        if (i<N) {
4315                            aInfo = resolves.get(i).activityInfo;
4316                        }
4317                        if (debug) {
4318                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4319                                    + "/" + r.info.name);
4320                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4321                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4322                        }
4323                        break;
4324                    }
4325                }
4326            } catch (RemoteException e) {
4327            }
4328
4329            if (aInfo == null) {
4330                // Nobody who is next!
4331                ActivityOptions.abort(options);
4332                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4333                return false;
4334            }
4335
4336            intent.setComponent(new ComponentName(
4337                    aInfo.applicationInfo.packageName, aInfo.name));
4338            intent.setFlags(intent.getFlags()&~(
4339                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4340                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4341                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4342                    Intent.FLAG_ACTIVITY_NEW_TASK));
4343
4344            // Okay now we need to start the new activity, replacing the
4345            // currently running activity.  This is a little tricky because
4346            // we want to start the new one as if the current one is finished,
4347            // but not finish the current one first so that there is no flicker.
4348            // And thus...
4349            final boolean wasFinishing = r.finishing;
4350            r.finishing = true;
4351
4352            // Propagate reply information over to the new activity.
4353            final ActivityRecord resultTo = r.resultTo;
4354            final String resultWho = r.resultWho;
4355            final int requestCode = r.requestCode;
4356            r.resultTo = null;
4357            if (resultTo != null) {
4358                resultTo.removeResultsLocked(r, resultWho, requestCode);
4359            }
4360
4361            final long origId = Binder.clearCallingIdentity();
4362            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4363                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4364                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4365                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4366                    false, false, null, null, null);
4367            Binder.restoreCallingIdentity(origId);
4368
4369            r.finishing = wasFinishing;
4370            if (res != ActivityManager.START_SUCCESS) {
4371                return false;
4372            }
4373            return true;
4374        }
4375    }
4376
4377    @Override
4378    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4379        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4380            String msg = "Permission Denial: startActivityFromRecents called without " +
4381                    START_TASKS_FROM_RECENTS;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385        final long origId = Binder.clearCallingIdentity();
4386        try {
4387            return startActivityFromRecentsInner(taskId, bOptions);
4388        } finally {
4389            Binder.restoreCallingIdentity(origId);
4390        }
4391    }
4392
4393    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4394        final TaskRecord task;
4395        final int callingUid;
4396        final String callingPackage;
4397        final Intent intent;
4398        final int userId;
4399        synchronized (this) {
4400            final ActivityOptions activityOptions = (bOptions != null)
4401                    ? new ActivityOptions(bOptions) : null;
4402            final int launchStackId = (activityOptions != null)
4403                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4404
4405            if (launchStackId == HOME_STACK_ID) {
4406                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4407                        + taskId + " can't be launch in the home stack.");
4408            }
4409
4410            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4411            if (task == null) {
4412                throw new IllegalArgumentException(
4413                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4414            }
4415
4416            if (launchStackId != INVALID_STACK_ID) {
4417                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4418                    mWindowManager.setDockedStackCreateState(
4419                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4420                }
4421                if (task.stack.mStackId != launchStackId) {
4422                    mStackSupervisor.moveTaskToStackLocked(
4423                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4424                            ANIMATE);
4425                }
4426            }
4427
4428            if (task.getRootActivity() != null) {
4429                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4430                return ActivityManager.START_TASK_TO_FRONT;
4431            }
4432            callingUid = task.mCallingUid;
4433            callingPackage = task.mCallingPackage;
4434            intent = task.intent;
4435            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4436            userId = task.userId;
4437        }
4438        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4439                bOptions, userId, null, task);
4440    }
4441
4442    final int startActivityInPackage(int uid, String callingPackage,
4443            Intent intent, String resolvedType, IBinder resultTo,
4444            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4445            IActivityContainer container, TaskRecord inTask) {
4446
4447        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4448                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4449
4450        // TODO: Switch to user app stacks here.
4451        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4452                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4453                null, null, null, bOptions, false, userId, container, inTask);
4454        return ret;
4455    }
4456
4457    @Override
4458    public final int startActivities(IApplicationThread caller, String callingPackage,
4459            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4460            int userId) {
4461        enforceNotIsolatedCaller("startActivities");
4462        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4463                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4464        // TODO: Switch to user app stacks here.
4465        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4466                resolvedTypes, resultTo, bOptions, userId);
4467        return ret;
4468    }
4469
4470    final int startActivitiesInPackage(int uid, String callingPackage,
4471            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4472            Bundle bOptions, int userId) {
4473
4474        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4475                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4476        // TODO: Switch to user app stacks here.
4477        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4478                resultTo, bOptions, userId);
4479        return ret;
4480    }
4481
4482    @Override
4483    public void reportActivityFullyDrawn(IBinder token) {
4484        synchronized (this) {
4485            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4486            if (r == null) {
4487                return;
4488            }
4489            r.reportFullyDrawnLocked();
4490        }
4491    }
4492
4493    @Override
4494    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4495        synchronized (this) {
4496            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4497            if (r == null) {
4498                return;
4499            }
4500            TaskRecord task = r.task;
4501            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4502                // Fixed screen orientation isn't supported when activities aren't in full screen
4503                // mode.
4504                return;
4505            }
4506            final long origId = Binder.clearCallingIdentity();
4507            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4508            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4509                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4510            if (config != null) {
4511                r.frozenBeforeDestroy = true;
4512                if (!updateConfigurationLocked(config, r, false)) {
4513                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4514                }
4515            }
4516            Binder.restoreCallingIdentity(origId);
4517        }
4518    }
4519
4520    @Override
4521    public int getRequestedOrientation(IBinder token) {
4522        synchronized (this) {
4523            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4524            if (r == null) {
4525                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4526            }
4527            return mWindowManager.getAppOrientation(r.appToken);
4528        }
4529    }
4530
4531    /**
4532     * This is the internal entry point for handling Activity.finish().
4533     *
4534     * @param token The Binder token referencing the Activity we want to finish.
4535     * @param resultCode Result code, if any, from this Activity.
4536     * @param resultData Result data (Intent), if any, from this Activity.
4537     * @param finishTask Whether to finish the task associated with this Activity.
4538     *
4539     * @return Returns true if the activity successfully finished, or false if it is still running.
4540     */
4541    @Override
4542    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4543            int finishTask) {
4544        // Refuse possible leaked file descriptors
4545        if (resultData != null && resultData.hasFileDescriptors() == true) {
4546            throw new IllegalArgumentException("File descriptors passed in Intent");
4547        }
4548
4549        synchronized(this) {
4550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4551            if (r == null) {
4552                return true;
4553            }
4554            // Keep track of the root activity of the task before we finish it
4555            TaskRecord tr = r.task;
4556            ActivityRecord rootR = tr.getRootActivity();
4557            if (rootR == null) {
4558                Slog.w(TAG, "Finishing task with all activities already finished");
4559            }
4560            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4561            // finish.
4562            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4563                    mStackSupervisor.isLastLockedTask(tr)) {
4564                Slog.i(TAG, "Not finishing task in lock task mode");
4565                mStackSupervisor.showLockTaskToast();
4566                return false;
4567            }
4568            if (mController != null) {
4569                // Find the first activity that is not finishing.
4570                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4571                if (next != null) {
4572                    // ask watcher if this is allowed
4573                    boolean resumeOK = true;
4574                    try {
4575                        resumeOK = mController.activityResuming(next.packageName);
4576                    } catch (RemoteException e) {
4577                        mController = null;
4578                        Watchdog.getInstance().setActivityController(null);
4579                    }
4580
4581                    if (!resumeOK) {
4582                        Slog.i(TAG, "Not finishing activity because controller resumed");
4583                        return false;
4584                    }
4585                }
4586            }
4587            final long origId = Binder.clearCallingIdentity();
4588            try {
4589                boolean res;
4590                final boolean finishWithRootActivity =
4591                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4592                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4593                        || (finishWithRootActivity && r == rootR)) {
4594                    // If requested, remove the task that is associated to this activity only if it
4595                    // was the root activity in the task. The result code and data is ignored
4596                    // because we don't support returning them across task boundaries. Also, to
4597                    // keep backwards compatibility we remove the task from recents when finishing
4598                    // task with root activity.
4599                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4600                    if (!res) {
4601                        Slog.i(TAG, "Removing task failed to finish activity");
4602                    }
4603                } else {
4604                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4605                            resultData, "app-request", true);
4606                    if (!res) {
4607                        Slog.i(TAG, "Failed to finish by app-request");
4608                    }
4609                }
4610                return res;
4611            } finally {
4612                Binder.restoreCallingIdentity(origId);
4613            }
4614        }
4615    }
4616
4617    @Override
4618    public final void finishHeavyWeightApp() {
4619        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4620                != PackageManager.PERMISSION_GRANTED) {
4621            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4622                    + Binder.getCallingPid()
4623                    + ", uid=" + Binder.getCallingUid()
4624                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4625            Slog.w(TAG, msg);
4626            throw new SecurityException(msg);
4627        }
4628
4629        synchronized(this) {
4630            if (mHeavyWeightProcess == null) {
4631                return;
4632            }
4633
4634            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4635            for (int i = 0; i < activities.size(); i++) {
4636                ActivityRecord r = activities.get(i);
4637                if (!r.finishing && r.isInStackLocked()) {
4638                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4639                            null, "finish-heavy", true);
4640                }
4641            }
4642
4643            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4644                    mHeavyWeightProcess.userId, 0));
4645            mHeavyWeightProcess = null;
4646        }
4647    }
4648
4649    @Override
4650    public void crashApplication(int uid, int initialPid, String packageName,
4651            String message) {
4652        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4653                != PackageManager.PERMISSION_GRANTED) {
4654            String msg = "Permission Denial: crashApplication() from pid="
4655                    + Binder.getCallingPid()
4656                    + ", uid=" + Binder.getCallingUid()
4657                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4658            Slog.w(TAG, msg);
4659            throw new SecurityException(msg);
4660        }
4661
4662        synchronized(this) {
4663            ProcessRecord proc = null;
4664
4665            // Figure out which process to kill.  We don't trust that initialPid
4666            // still has any relation to current pids, so must scan through the
4667            // list.
4668            synchronized (mPidsSelfLocked) {
4669                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4670                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4671                    if (p.uid != uid) {
4672                        continue;
4673                    }
4674                    if (p.pid == initialPid) {
4675                        proc = p;
4676                        break;
4677                    }
4678                    if (p.pkgList.containsKey(packageName)) {
4679                        proc = p;
4680                    }
4681                }
4682            }
4683
4684            if (proc == null) {
4685                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4686                        + " initialPid=" + initialPid
4687                        + " packageName=" + packageName);
4688                return;
4689            }
4690
4691            if (proc.thread != null) {
4692                if (proc.pid == Process.myPid()) {
4693                    Log.w(TAG, "crashApplication: trying to crash self!");
4694                    return;
4695                }
4696                long ident = Binder.clearCallingIdentity();
4697                try {
4698                    proc.thread.scheduleCrash(message);
4699                } catch (RemoteException e) {
4700                }
4701                Binder.restoreCallingIdentity(ident);
4702            }
4703        }
4704    }
4705
4706    @Override
4707    public final void finishSubActivity(IBinder token, String resultWho,
4708            int requestCode) {
4709        synchronized(this) {
4710            final long origId = Binder.clearCallingIdentity();
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r != null) {
4713                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4714            }
4715            Binder.restoreCallingIdentity(origId);
4716        }
4717    }
4718
4719    @Override
4720    public boolean finishActivityAffinity(IBinder token) {
4721        synchronized(this) {
4722            final long origId = Binder.clearCallingIdentity();
4723            try {
4724                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4725                if (r == null) {
4726                    return false;
4727                }
4728
4729                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4730                // can finish.
4731                final TaskRecord task = r.task;
4732                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4733                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4734                    mStackSupervisor.showLockTaskToast();
4735                    return false;
4736                }
4737                return task.stack.finishActivityAffinityLocked(r);
4738            } finally {
4739                Binder.restoreCallingIdentity(origId);
4740            }
4741        }
4742    }
4743
4744    @Override
4745    public void finishVoiceTask(IVoiceInteractionSession session) {
4746        synchronized(this) {
4747            final long origId = Binder.clearCallingIdentity();
4748            try {
4749                mStackSupervisor.finishVoiceTask(session);
4750            } finally {
4751                Binder.restoreCallingIdentity(origId);
4752            }
4753        }
4754
4755    }
4756
4757    @Override
4758    public boolean releaseActivityInstance(IBinder token) {
4759        synchronized(this) {
4760            final long origId = Binder.clearCallingIdentity();
4761            try {
4762                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4763                if (r == null) {
4764                    return false;
4765                }
4766                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4767            } finally {
4768                Binder.restoreCallingIdentity(origId);
4769            }
4770        }
4771    }
4772
4773    @Override
4774    public void releaseSomeActivities(IApplicationThread appInt) {
4775        synchronized(this) {
4776            final long origId = Binder.clearCallingIdentity();
4777            try {
4778                ProcessRecord app = getRecordForAppLocked(appInt);
4779                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4780            } finally {
4781                Binder.restoreCallingIdentity(origId);
4782            }
4783        }
4784    }
4785
4786    @Override
4787    public boolean willActivityBeVisible(IBinder token) {
4788        synchronized(this) {
4789            ActivityStack stack = ActivityRecord.getStackLocked(token);
4790            if (stack != null) {
4791                return stack.willActivityBeVisibleLocked(token);
4792            }
4793            return false;
4794        }
4795    }
4796
4797    @Override
4798    public void overridePendingTransition(IBinder token, String packageName,
4799            int enterAnim, int exitAnim) {
4800        synchronized(this) {
4801            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4802            if (self == null) {
4803                return;
4804            }
4805
4806            final long origId = Binder.clearCallingIdentity();
4807
4808            if (self.state == ActivityState.RESUMED
4809                    || self.state == ActivityState.PAUSING) {
4810                mWindowManager.overridePendingAppTransition(packageName,
4811                        enterAnim, exitAnim, null);
4812            }
4813
4814            Binder.restoreCallingIdentity(origId);
4815        }
4816    }
4817
4818    /**
4819     * Main function for removing an existing process from the activity manager
4820     * as a result of that process going away.  Clears out all connections
4821     * to the process.
4822     */
4823    private final void handleAppDiedLocked(ProcessRecord app,
4824            boolean restarting, boolean allowRestart) {
4825        int pid = app.pid;
4826        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4827        if (!kept && !restarting) {
4828            removeLruProcessLocked(app);
4829            if (pid > 0) {
4830                ProcessList.remove(pid);
4831            }
4832        }
4833
4834        if (mProfileProc == app) {
4835            clearProfilerLocked();
4836        }
4837
4838        // Remove this application's activities from active lists.
4839        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4840
4841        app.activities.clear();
4842
4843        if (app.instrumentationClass != null) {
4844            Slog.w(TAG, "Crash of app " + app.processName
4845                  + " running instrumentation " + app.instrumentationClass);
4846            Bundle info = new Bundle();
4847            info.putString("shortMsg", "Process crashed.");
4848            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4849        }
4850
4851        if (!restarting && hasVisibleActivities
4852                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4853            // If there was nothing to resume, and we are not already restarting this process, but
4854            // there is a visible activity that is hosted by the process...  then make sure all
4855            // visible activities are running, taking care of restarting this process.
4856            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4857        }
4858    }
4859
4860    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4861        IBinder threadBinder = thread.asBinder();
4862        // Find the application record.
4863        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4864            ProcessRecord rec = mLruProcesses.get(i);
4865            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4866                return i;
4867            }
4868        }
4869        return -1;
4870    }
4871
4872    final ProcessRecord getRecordForAppLocked(
4873            IApplicationThread thread) {
4874        if (thread == null) {
4875            return null;
4876        }
4877
4878        int appIndex = getLRURecordIndexForAppLocked(thread);
4879        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4880    }
4881
4882    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4883        // If there are no longer any background processes running,
4884        // and the app that died was not running instrumentation,
4885        // then tell everyone we are now low on memory.
4886        boolean haveBg = false;
4887        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4888            ProcessRecord rec = mLruProcesses.get(i);
4889            if (rec.thread != null
4890                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4891                haveBg = true;
4892                break;
4893            }
4894        }
4895
4896        if (!haveBg) {
4897            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4898            if (doReport) {
4899                long now = SystemClock.uptimeMillis();
4900                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4901                    doReport = false;
4902                } else {
4903                    mLastMemUsageReportTime = now;
4904                }
4905            }
4906            final ArrayList<ProcessMemInfo> memInfos
4907                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4908            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4909            long now = SystemClock.uptimeMillis();
4910            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4911                ProcessRecord rec = mLruProcesses.get(i);
4912                if (rec == dyingProc || rec.thread == null) {
4913                    continue;
4914                }
4915                if (doReport) {
4916                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4917                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4918                }
4919                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4920                    // The low memory report is overriding any current
4921                    // state for a GC request.  Make sure to do
4922                    // heavy/important/visible/foreground processes first.
4923                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4924                        rec.lastRequestedGc = 0;
4925                    } else {
4926                        rec.lastRequestedGc = rec.lastLowMemory;
4927                    }
4928                    rec.reportLowMemory = true;
4929                    rec.lastLowMemory = now;
4930                    mProcessesToGc.remove(rec);
4931                    addProcessToGcListLocked(rec);
4932                }
4933            }
4934            if (doReport) {
4935                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4936                mHandler.sendMessage(msg);
4937            }
4938            scheduleAppGcsLocked();
4939        }
4940    }
4941
4942    final void appDiedLocked(ProcessRecord app) {
4943       appDiedLocked(app, app.pid, app.thread, false);
4944    }
4945
4946    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4947            boolean fromBinderDied) {
4948        // First check if this ProcessRecord is actually active for the pid.
4949        synchronized (mPidsSelfLocked) {
4950            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4951            if (curProc != app) {
4952                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4953                return;
4954            }
4955        }
4956
4957        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4958        synchronized (stats) {
4959            stats.noteProcessDiedLocked(app.info.uid, pid);
4960        }
4961
4962        if (!app.killed) {
4963            if (!fromBinderDied) {
4964                Process.killProcessQuiet(pid);
4965            }
4966            killProcessGroup(app.info.uid, pid);
4967            app.killed = true;
4968        }
4969
4970        // Clean up already done if the process has been re-started.
4971        if (app.pid == pid && app.thread != null &&
4972                app.thread.asBinder() == thread.asBinder()) {
4973            boolean doLowMem = app.instrumentationClass == null;
4974            boolean doOomAdj = doLowMem;
4975            if (!app.killedByAm) {
4976                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4977                        + ") has died");
4978                mAllowLowerMemLevel = true;
4979            } else {
4980                // Note that we always want to do oom adj to update our state with the
4981                // new number of procs.
4982                mAllowLowerMemLevel = false;
4983                doLowMem = false;
4984            }
4985            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4986            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4987                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4988            handleAppDiedLocked(app, false, true);
4989
4990            if (doOomAdj) {
4991                updateOomAdjLocked();
4992            }
4993            if (doLowMem) {
4994                doLowMemReportIfNeededLocked(app);
4995            }
4996        } else if (app.pid != pid) {
4997            // A new process has already been started.
4998            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4999                    + ") has died and restarted (pid " + app.pid + ").");
5000            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5001        } else if (DEBUG_PROCESSES) {
5002            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5003                    + thread.asBinder());
5004        }
5005    }
5006
5007    /**
5008     * If a stack trace dump file is configured, dump process stack traces.
5009     * @param clearTraces causes the dump file to be erased prior to the new
5010     *    traces being written, if true; when false, the new traces will be
5011     *    appended to any existing file content.
5012     * @param firstPids of dalvik VM processes to dump stack traces for first
5013     * @param lastPids of dalvik VM processes to dump stack traces for last
5014     * @param nativeProcs optional list of native process names to dump stack crawls
5015     * @return file containing stack traces, or null if no dump file is configured
5016     */
5017    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5018            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5019        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5020        if (tracesPath == null || tracesPath.length() == 0) {
5021            return null;
5022        }
5023
5024        File tracesFile = new File(tracesPath);
5025        try {
5026            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5027            tracesFile.createNewFile();
5028            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5029        } catch (IOException e) {
5030            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5031            return null;
5032        }
5033
5034        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5035        return tracesFile;
5036    }
5037
5038    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5039            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5040        // Use a FileObserver to detect when traces finish writing.
5041        // The order of traces is considered important to maintain for legibility.
5042        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5043            @Override
5044            public synchronized void onEvent(int event, String path) { notify(); }
5045        };
5046
5047        try {
5048            observer.startWatching();
5049
5050            // First collect all of the stacks of the most important pids.
5051            if (firstPids != null) {
5052                try {
5053                    int num = firstPids.size();
5054                    for (int i = 0; i < num; i++) {
5055                        synchronized (observer) {
5056                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5057                            observer.wait(200);  // Wait for write-close, give up after 200msec
5058                        }
5059                    }
5060                } catch (InterruptedException e) {
5061                    Slog.wtf(TAG, e);
5062                }
5063            }
5064
5065            // Next collect the stacks of the native pids
5066            if (nativeProcs != null) {
5067                int[] pids = Process.getPidsForCommands(nativeProcs);
5068                if (pids != null) {
5069                    for (int pid : pids) {
5070                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5071                    }
5072                }
5073            }
5074
5075            // Lastly, measure CPU usage.
5076            if (processCpuTracker != null) {
5077                processCpuTracker.init();
5078                System.gc();
5079                processCpuTracker.update();
5080                try {
5081                    synchronized (processCpuTracker) {
5082                        processCpuTracker.wait(500); // measure over 1/2 second.
5083                    }
5084                } catch (InterruptedException e) {
5085                }
5086                processCpuTracker.update();
5087
5088                // We'll take the stack crawls of just the top apps using CPU.
5089                final int N = processCpuTracker.countWorkingStats();
5090                int numProcs = 0;
5091                for (int i=0; i<N && numProcs<5; i++) {
5092                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5093                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5094                        numProcs++;
5095                        try {
5096                            synchronized (observer) {
5097                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5098                                observer.wait(200);  // Wait for write-close, give up after 200msec
5099                            }
5100                        } catch (InterruptedException e) {
5101                            Slog.wtf(TAG, e);
5102                        }
5103
5104                    }
5105                }
5106            }
5107        } finally {
5108            observer.stopWatching();
5109        }
5110    }
5111
5112    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5113        if (true || IS_USER_BUILD) {
5114            return;
5115        }
5116        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5117        if (tracesPath == null || tracesPath.length() == 0) {
5118            return;
5119        }
5120
5121        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5122        StrictMode.allowThreadDiskWrites();
5123        try {
5124            final File tracesFile = new File(tracesPath);
5125            final File tracesDir = tracesFile.getParentFile();
5126            final File tracesTmp = new File(tracesDir, "__tmp__");
5127            try {
5128                if (tracesFile.exists()) {
5129                    tracesTmp.delete();
5130                    tracesFile.renameTo(tracesTmp);
5131                }
5132                StringBuilder sb = new StringBuilder();
5133                Time tobj = new Time();
5134                tobj.set(System.currentTimeMillis());
5135                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5136                sb.append(": ");
5137                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5138                sb.append(" since ");
5139                sb.append(msg);
5140                FileOutputStream fos = new FileOutputStream(tracesFile);
5141                fos.write(sb.toString().getBytes());
5142                if (app == null) {
5143                    fos.write("\n*** No application process!".getBytes());
5144                }
5145                fos.close();
5146                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5147            } catch (IOException e) {
5148                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5149                return;
5150            }
5151
5152            if (app != null) {
5153                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5154                firstPids.add(app.pid);
5155                dumpStackTraces(tracesPath, firstPids, null, null, null);
5156            }
5157
5158            File lastTracesFile = null;
5159            File curTracesFile = null;
5160            for (int i=9; i>=0; i--) {
5161                String name = String.format(Locale.US, "slow%02d.txt", i);
5162                curTracesFile = new File(tracesDir, name);
5163                if (curTracesFile.exists()) {
5164                    if (lastTracesFile != null) {
5165                        curTracesFile.renameTo(lastTracesFile);
5166                    } else {
5167                        curTracesFile.delete();
5168                    }
5169                }
5170                lastTracesFile = curTracesFile;
5171            }
5172            tracesFile.renameTo(curTracesFile);
5173            if (tracesTmp.exists()) {
5174                tracesTmp.renameTo(tracesFile);
5175            }
5176        } finally {
5177            StrictMode.setThreadPolicy(oldPolicy);
5178        }
5179    }
5180
5181    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5182            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5183        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5184        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5185
5186        if (mController != null) {
5187            try {
5188                // 0 == continue, -1 = kill process immediately
5189                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5190                if (res < 0 && app.pid != MY_PID) {
5191                    app.kill("anr", true);
5192                }
5193            } catch (RemoteException e) {
5194                mController = null;
5195                Watchdog.getInstance().setActivityController(null);
5196            }
5197        }
5198
5199        long anrTime = SystemClock.uptimeMillis();
5200        if (MONITOR_CPU_USAGE) {
5201            updateCpuStatsNow();
5202        }
5203
5204        synchronized (this) {
5205            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5206            if (mShuttingDown) {
5207                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5208                return;
5209            } else if (app.notResponding) {
5210                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5211                return;
5212            } else if (app.crashing) {
5213                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5214                return;
5215            }
5216
5217            // In case we come through here for the same app before completing
5218            // this one, mark as anring now so we will bail out.
5219            app.notResponding = true;
5220
5221            // Log the ANR to the event log.
5222            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5223                    app.processName, app.info.flags, annotation);
5224
5225            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5226            firstPids.add(app.pid);
5227
5228            int parentPid = app.pid;
5229            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5230            if (parentPid != app.pid) firstPids.add(parentPid);
5231
5232            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5233
5234            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5235                ProcessRecord r = mLruProcesses.get(i);
5236                if (r != null && r.thread != null) {
5237                    int pid = r.pid;
5238                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5239                        if (r.persistent) {
5240                            firstPids.add(pid);
5241                        } else {
5242                            lastPids.put(pid, Boolean.TRUE);
5243                        }
5244                    }
5245                }
5246            }
5247        }
5248
5249        // Log the ANR to the main log.
5250        StringBuilder info = new StringBuilder();
5251        info.setLength(0);
5252        info.append("ANR in ").append(app.processName);
5253        if (activity != null && activity.shortComponentName != null) {
5254            info.append(" (").append(activity.shortComponentName).append(")");
5255        }
5256        info.append("\n");
5257        info.append("PID: ").append(app.pid).append("\n");
5258        if (annotation != null) {
5259            info.append("Reason: ").append(annotation).append("\n");
5260        }
5261        if (parent != null && parent != activity) {
5262            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5263        }
5264
5265        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5266
5267        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5268                NATIVE_STACKS_OF_INTEREST);
5269
5270        String cpuInfo = null;
5271        if (MONITOR_CPU_USAGE) {
5272            updateCpuStatsNow();
5273            synchronized (mProcessCpuTracker) {
5274                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5275            }
5276            info.append(processCpuTracker.printCurrentLoad());
5277            info.append(cpuInfo);
5278        }
5279
5280        info.append(processCpuTracker.printCurrentState(anrTime));
5281
5282        Slog.e(TAG, info.toString());
5283        if (tracesFile == null) {
5284            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5285            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5286        }
5287
5288        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5289                cpuInfo, tracesFile, null);
5290
5291        if (mController != null) {
5292            try {
5293                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5294                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5295                if (res != 0) {
5296                    if (res < 0 && app.pid != MY_PID) {
5297                        app.kill("anr", true);
5298                    } else {
5299                        synchronized (this) {
5300                            mServices.scheduleServiceTimeoutLocked(app);
5301                        }
5302                    }
5303                    return;
5304                }
5305            } catch (RemoteException e) {
5306                mController = null;
5307                Watchdog.getInstance().setActivityController(null);
5308            }
5309        }
5310
5311        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5312        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5313                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5314
5315        synchronized (this) {
5316            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5317
5318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5319                app.kill("bg anr", true);
5320                return;
5321            }
5322
5323            // Set the app's notResponding state, and look up the errorReportReceiver
5324            makeAppNotRespondingLocked(app,
5325                    activity != null ? activity.shortComponentName : null,
5326                    annotation != null ? "ANR " + annotation : "ANR",
5327                    info.toString());
5328
5329            // Bring up the infamous App Not Responding dialog
5330            Message msg = Message.obtain();
5331            HashMap<String, Object> map = new HashMap<String, Object>();
5332            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5333            msg.obj = map;
5334            msg.arg1 = aboveSystem ? 1 : 0;
5335            map.put("app", app);
5336            if (activity != null) {
5337                map.put("activity", activity);
5338            }
5339
5340            mUiHandler.sendMessage(msg);
5341        }
5342    }
5343
5344    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5345        if (!mLaunchWarningShown) {
5346            mLaunchWarningShown = true;
5347            mUiHandler.post(new Runnable() {
5348                @Override
5349                public void run() {
5350                    synchronized (ActivityManagerService.this) {
5351                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5352                        d.show();
5353                        mUiHandler.postDelayed(new Runnable() {
5354                            @Override
5355                            public void run() {
5356                                synchronized (ActivityManagerService.this) {
5357                                    d.dismiss();
5358                                    mLaunchWarningShown = false;
5359                                }
5360                            }
5361                        }, 4000);
5362                    }
5363                }
5364            });
5365        }
5366    }
5367
5368    @Override
5369    public boolean clearApplicationUserData(final String packageName,
5370            final IPackageDataObserver observer, int userId) {
5371        enforceNotIsolatedCaller("clearApplicationUserData");
5372        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5373            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5374        }
5375        int uid = Binder.getCallingUid();
5376        int pid = Binder.getCallingPid();
5377        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5378                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5379        long callingId = Binder.clearCallingIdentity();
5380        try {
5381            IPackageManager pm = AppGlobals.getPackageManager();
5382            int pkgUid = -1;
5383            synchronized(this) {
5384                try {
5385                    pkgUid = pm.getPackageUid(packageName, userId);
5386                } catch (RemoteException e) {
5387                }
5388                if (pkgUid == -1) {
5389                    Slog.w(TAG, "Invalid packageName: " + packageName);
5390                    if (observer != null) {
5391                        try {
5392                            observer.onRemoveCompleted(packageName, false);
5393                        } catch (RemoteException e) {
5394                            Slog.i(TAG, "Observer no longer exists.");
5395                        }
5396                    }
5397                    return false;
5398                }
5399                if (uid == pkgUid || checkComponentPermission(
5400                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5401                        pid, uid, -1, true)
5402                        == PackageManager.PERMISSION_GRANTED) {
5403                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5404                } else {
5405                    throw new SecurityException("PID " + pid + " does not have permission "
5406                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5407                                    + " of package " + packageName);
5408                }
5409
5410                // Remove all tasks match the cleared application package and user
5411                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5412                    final TaskRecord tr = mRecentTasks.get(i);
5413                    final String taskPackageName =
5414                            tr.getBaseIntent().getComponent().getPackageName();
5415                    if (tr.userId != userId) continue;
5416                    if (!taskPackageName.equals(packageName)) continue;
5417                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5418                }
5419            }
5420
5421            try {
5422                // Clear application user data
5423                pm.clearApplicationUserData(packageName, observer, userId);
5424
5425                synchronized(this) {
5426                    // Remove all permissions granted from/to this package
5427                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5428                }
5429
5430                // Remove all zen rules created by this package; revoke it's zen access.
5431                INotificationManager inm = NotificationManager.getService();
5432                inm.removeAutomaticZenRules(packageName);
5433                inm.setNotificationPolicyAccessGranted(packageName, false);
5434
5435                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5436                        Uri.fromParts("package", packageName, null));
5437                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5438                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5439                        null, null, 0, null, null, null, null, false, false, userId);
5440            } catch (RemoteException e) {
5441            }
5442        } finally {
5443            Binder.restoreCallingIdentity(callingId);
5444        }
5445        return true;
5446    }
5447
5448    @Override
5449    public void killBackgroundProcesses(final String packageName, int userId) {
5450        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5451                != PackageManager.PERMISSION_GRANTED &&
5452                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5453                        != PackageManager.PERMISSION_GRANTED) {
5454            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5455                    + Binder.getCallingPid()
5456                    + ", uid=" + Binder.getCallingUid()
5457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5458            Slog.w(TAG, msg);
5459            throw new SecurityException(msg);
5460        }
5461
5462        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5463                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5464        long callingId = Binder.clearCallingIdentity();
5465        try {
5466            IPackageManager pm = AppGlobals.getPackageManager();
5467            synchronized(this) {
5468                int appId = -1;
5469                try {
5470                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
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, user);
5557                    } catch (RemoteException e) {
5558                    }
5559                    if (pkgUid == -1) {
5560                        Slog.w(TAG, "Invalid packageName: " + packageName);
5561                        continue;
5562                    }
5563                    try {
5564                        pm.setPackageStoppedState(packageName, true, user);
5565                    } catch (RemoteException e) {
5566                    } catch (IllegalArgumentException e) {
5567                        Slog.w(TAG, "Failed trying to unstop package "
5568                                + packageName + ": " + e);
5569                    }
5570                    if (mUserController.isUserRunningLocked(user, 0)) {
5571                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5572                    }
5573                }
5574            }
5575        } finally {
5576            Binder.restoreCallingIdentity(callingId);
5577        }
5578    }
5579
5580    @Override
5581    public void addPackageDependency(String packageName) {
5582        synchronized (this) {
5583            int callingPid = Binder.getCallingPid();
5584            if (callingPid == Process.myPid()) {
5585                //  Yeah, um, no.
5586                return;
5587            }
5588            ProcessRecord proc;
5589            synchronized (mPidsSelfLocked) {
5590                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5591            }
5592            if (proc != null) {
5593                if (proc.pkgDeps == null) {
5594                    proc.pkgDeps = new ArraySet<String>(1);
5595                }
5596                proc.pkgDeps.add(packageName);
5597            }
5598        }
5599    }
5600
5601    /*
5602     * The pkg name and app id have to be specified.
5603     */
5604    @Override
5605    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5606        if (pkg == null) {
5607            return;
5608        }
5609        // Make sure the uid is valid.
5610        if (appid < 0) {
5611            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5612            return;
5613        }
5614        int callerUid = Binder.getCallingUid();
5615        // Only the system server can kill an application
5616        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5617            // Post an aysnc message to kill the application
5618            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5619            msg.arg1 = appid;
5620            msg.arg2 = 0;
5621            Bundle bundle = new Bundle();
5622            bundle.putString("pkg", pkg);
5623            bundle.putString("reason", reason);
5624            msg.obj = bundle;
5625            mHandler.sendMessage(msg);
5626        } else {
5627            throw new SecurityException(callerUid + " cannot kill pkg: " +
5628                    pkg);
5629        }
5630    }
5631
5632    @Override
5633    public void closeSystemDialogs(String reason) {
5634        enforceNotIsolatedCaller("closeSystemDialogs");
5635
5636        final int pid = Binder.getCallingPid();
5637        final int uid = Binder.getCallingUid();
5638        final long origId = Binder.clearCallingIdentity();
5639        try {
5640            synchronized (this) {
5641                // Only allow this from foreground processes, so that background
5642                // applications can't abuse it to prevent system UI from being shown.
5643                if (uid >= Process.FIRST_APPLICATION_UID) {
5644                    ProcessRecord proc;
5645                    synchronized (mPidsSelfLocked) {
5646                        proc = mPidsSelfLocked.get(pid);
5647                    }
5648                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5649                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5650                                + " from background process " + proc);
5651                        return;
5652                    }
5653                }
5654                closeSystemDialogsLocked(reason);
5655            }
5656        } finally {
5657            Binder.restoreCallingIdentity(origId);
5658        }
5659    }
5660
5661    void closeSystemDialogsLocked(String reason) {
5662        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5663        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5664                | Intent.FLAG_RECEIVER_FOREGROUND);
5665        if (reason != null) {
5666            intent.putExtra("reason", reason);
5667        }
5668        mWindowManager.closeSystemDialogs(reason);
5669
5670        mStackSupervisor.closeSystemDialogsLocked();
5671
5672        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5673                AppOpsManager.OP_NONE, null, false, false,
5674                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5675    }
5676
5677    @Override
5678    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5679        enforceNotIsolatedCaller("getProcessMemoryInfo");
5680        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5681        for (int i=pids.length-1; i>=0; i--) {
5682            ProcessRecord proc;
5683            int oomAdj;
5684            synchronized (this) {
5685                synchronized (mPidsSelfLocked) {
5686                    proc = mPidsSelfLocked.get(pids[i]);
5687                    oomAdj = proc != null ? proc.setAdj : 0;
5688                }
5689            }
5690            infos[i] = new Debug.MemoryInfo();
5691            Debug.getMemoryInfo(pids[i], infos[i]);
5692            if (proc != null) {
5693                synchronized (this) {
5694                    if (proc.thread != null && proc.setAdj == oomAdj) {
5695                        // Record this for posterity if the process has been stable.
5696                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5697                                infos[i].getTotalUss(), false, proc.pkgList);
5698                    }
5699                }
5700            }
5701        }
5702        return infos;
5703    }
5704
5705    @Override
5706    public long[] getProcessPss(int[] pids) {
5707        enforceNotIsolatedCaller("getProcessPss");
5708        long[] pss = new long[pids.length];
5709        for (int i=pids.length-1; i>=0; i--) {
5710            ProcessRecord proc;
5711            int oomAdj;
5712            synchronized (this) {
5713                synchronized (mPidsSelfLocked) {
5714                    proc = mPidsSelfLocked.get(pids[i]);
5715                    oomAdj = proc != null ? proc.setAdj : 0;
5716                }
5717            }
5718            long[] tmpUss = new long[1];
5719            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5720            if (proc != null) {
5721                synchronized (this) {
5722                    if (proc.thread != null && proc.setAdj == oomAdj) {
5723                        // Record this for posterity if the process has been stable.
5724                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5725                    }
5726                }
5727            }
5728        }
5729        return pss;
5730    }
5731
5732    @Override
5733    public void killApplicationProcess(String processName, int uid) {
5734        if (processName == null) {
5735            return;
5736        }
5737
5738        int callerUid = Binder.getCallingUid();
5739        // Only the system server can kill an application
5740        if (callerUid == Process.SYSTEM_UID) {
5741            synchronized (this) {
5742                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5743                if (app != null && app.thread != null) {
5744                    try {
5745                        app.thread.scheduleSuicide();
5746                    } catch (RemoteException e) {
5747                        // If the other end already died, then our work here is done.
5748                    }
5749                } else {
5750                    Slog.w(TAG, "Process/uid not found attempting kill of "
5751                            + processName + " / " + uid);
5752                }
5753            }
5754        } else {
5755            throw new SecurityException(callerUid + " cannot kill app process: " +
5756                    processName);
5757        }
5758    }
5759
5760    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5761        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5762                false, true, false, false, UserHandle.getUserId(uid), reason);
5763        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5764                Uri.fromParts("package", packageName, null));
5765        if (!mProcessesReady) {
5766            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5767                    | Intent.FLAG_RECEIVER_FOREGROUND);
5768        }
5769        intent.putExtra(Intent.EXTRA_UID, uid);
5770        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5771        broadcastIntentLocked(null, null, intent,
5772                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5773                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5774    }
5775
5776
5777    private final boolean killPackageProcessesLocked(String packageName, int appId,
5778            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5779            boolean doit, boolean evenPersistent, boolean killPackageApp, String reason) {
5780        ArrayList<ProcessRecord> procs = new ArrayList<>();
5781
5782        // Remove all processes this package may have touched: all with the
5783        // same UID (except for the system or root user), and all whose name
5784        // matches the package name.
5785        final int NP = mProcessNames.getMap().size();
5786        for (int ip=0; ip<NP; ip++) {
5787            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5788            final int NA = apps.size();
5789            for (int ia=0; ia<NA; ia++) {
5790                ProcessRecord app = apps.valueAt(ia);
5791                if (app.persistent && !evenPersistent) {
5792                    // we don't kill persistent processes
5793                    continue;
5794                }
5795                if (app.removed) {
5796                    if (doit) {
5797                        procs.add(app);
5798                    }
5799                    continue;
5800                }
5801
5802                // Skip process if it doesn't meet our oom adj requirement.
5803                if (app.setAdj < minOomAdj) {
5804                    continue;
5805                }
5806
5807                // If no package is specified, we call all processes under the
5808                // give user id.
5809                if (packageName == null) {
5810                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5811                        continue;
5812                    }
5813                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5814                        continue;
5815                    }
5816                // Package has been specified, we want to hit all processes
5817                // that match it.  We need to qualify this by the processes
5818                // that are running under the specified app and user ID.
5819                } else {
5820                    final boolean isDep = app.pkgDeps != null
5821                            && app.pkgDeps.contains(packageName);
5822                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5823                        continue;
5824                    }
5825                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5826                        continue;
5827                    }
5828                    if ((!killPackageApp || !app.pkgList.containsKey(packageName)) && !isDep) {
5829                        continue;
5830                    }
5831                }
5832
5833                // Process has passed all conditions, kill it!
5834                if (!doit) {
5835                    return true;
5836                }
5837                app.removed = true;
5838                procs.add(app);
5839            }
5840        }
5841
5842        int N = procs.size();
5843        for (int i=0; i<N; i++) {
5844            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5845        }
5846        updateOomAdjLocked();
5847        return N > 0;
5848    }
5849
5850    private void cleanupDisabledPackageComponentsLocked(
5851            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5852
5853        Set<String> disabledClasses = null;
5854        boolean packageDisabled = false;
5855        IPackageManager pm = AppGlobals.getPackageManager();
5856
5857        if (changedClasses == null) {
5858            // Nothing changed...
5859            return;
5860        }
5861
5862        // Determine enable/disable state of the package and its components.
5863        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5864        for (int i = changedClasses.length - 1; i >= 0; i--) {
5865            final String changedClass = changedClasses[i];
5866
5867            if (changedClass.equals(packageName)) {
5868                try {
5869                    // Entire package setting changed
5870                    enabled = pm.getApplicationEnabledSetting(packageName,
5871                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5872                } catch (Exception e) {
5873                    // No such package/component; probably racing with uninstall.  In any
5874                    // event it means we have nothing further to do here.
5875                    return;
5876                }
5877                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5878                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5879                if (packageDisabled) {
5880                    // Entire package is disabled.
5881                    // No need to continue to check component states.
5882                    disabledClasses = null;
5883                    break;
5884                }
5885            } else {
5886                try {
5887                    enabled = pm.getComponentEnabledSetting(
5888                            new ComponentName(packageName, changedClass),
5889                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5890                } catch (Exception e) {
5891                    // As above, probably racing with uninstall.
5892                    return;
5893                }
5894                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5895                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5896                    if (disabledClasses == null) {
5897                        disabledClasses = new ArraySet<>(changedClasses.length);
5898                    }
5899                    disabledClasses.add(changedClass);
5900                }
5901            }
5902        }
5903
5904        if (!packageDisabled && disabledClasses == null) {
5905            // Nothing to do here...
5906            return;
5907        }
5908
5909        // Clean-up disabled activities.
5910        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5911                packageName, disabledClasses, true, false, userId) && mBooted) {
5912            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5913            mStackSupervisor.scheduleIdleLocked();
5914        }
5915
5916        // Clean-up disabled tasks
5917        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5918
5919        // Clean-up disabled services.
5920        mServices.bringDownDisabledPackageServicesLocked(
5921                packageName, disabledClasses, userId, false, killProcess, true);
5922
5923        // Clean-up disabled providers.
5924        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5925        mProviderMap.collectPackageProvidersLocked(
5926                packageName, disabledClasses, true, false, userId, providers);
5927        for (int i = providers.size() - 1; i >= 0; i--) {
5928            removeDyingProviderLocked(null, providers.get(i), true);
5929        }
5930
5931        // Clean-up disabled broadcast receivers.
5932        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5933            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5934                    packageName, disabledClasses, userId, true);
5935        }
5936
5937    }
5938
5939    final boolean forceStopPackageLocked(String packageName, int appId,
5940            boolean callerWillRestart, boolean purgeCache, boolean doit,
5941            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5942        int i;
5943
5944        if (userId == UserHandle.USER_ALL && packageName == null) {
5945            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5946        }
5947
5948        if (appId < 0 && packageName != null) {
5949            try {
5950                appId = UserHandle.getAppId(
5951                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5952            } catch (RemoteException e) {
5953            }
5954        }
5955
5956        if (doit) {
5957            if (packageName != null) {
5958                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5959                        + " user=" + userId + ": " + reason);
5960            } else {
5961                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5962            }
5963
5964            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5965            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5966                SparseArray<Long> ba = pmap.valueAt(ip);
5967                for (i = ba.size() - 1; i >= 0; i--) {
5968                    boolean remove = false;
5969                    final int entUid = ba.keyAt(i);
5970                    if (packageName != null) {
5971                        if (userId == UserHandle.USER_ALL) {
5972                            if (UserHandle.getAppId(entUid) == appId) {
5973                                remove = true;
5974                            }
5975                        } else {
5976                            if (entUid == UserHandle.getUid(userId, appId)) {
5977                                remove = true;
5978                            }
5979                        }
5980                    } else if (UserHandle.getUserId(entUid) == userId) {
5981                        remove = true;
5982                    }
5983                    if (remove) {
5984                        ba.removeAt(i);
5985                    }
5986                }
5987                if (ba.size() == 0) {
5988                    pmap.removeAt(ip);
5989                }
5990            }
5991        }
5992
5993        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5994                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, true,
5995                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5996
5997        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5998                packageName, null, doit, evenPersistent, userId)) {
5999            if (!doit) {
6000                return true;
6001            }
6002            didSomething = true;
6003        }
6004
6005        if (mServices.bringDownDisabledPackageServicesLocked(
6006                packageName, null, userId, evenPersistent, true, doit)) {
6007            if (!doit) {
6008                return true;
6009            }
6010            didSomething = true;
6011        }
6012
6013        if (packageName == null) {
6014            // Remove all sticky broadcasts from this user.
6015            mStickyBroadcasts.remove(userId);
6016        }
6017
6018        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6019        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6020                userId, providers)) {
6021            if (!doit) {
6022                return true;
6023            }
6024            didSomething = true;
6025        }
6026        for (i = providers.size() - 1; i >= 0; i--) {
6027            removeDyingProviderLocked(null, providers.get(i), true);
6028        }
6029
6030        // Remove transient permissions granted from/to this package/user
6031        removeUriPermissionsForPackageLocked(packageName, userId, false);
6032
6033        if (doit) {
6034            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6035                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6036                        packageName, null, userId, doit);
6037            }
6038        }
6039
6040        if (packageName == null || uninstalling) {
6041            // Remove pending intents.  For now we only do this when force
6042            // stopping users, because we have some problems when doing this
6043            // for packages -- app widgets are not currently cleaned up for
6044            // such packages, so they can be left with bad pending intents.
6045            if (mIntentSenderRecords.size() > 0) {
6046                Iterator<WeakReference<PendingIntentRecord>> it
6047                        = mIntentSenderRecords.values().iterator();
6048                while (it.hasNext()) {
6049                    WeakReference<PendingIntentRecord> wpir = it.next();
6050                    if (wpir == null) {
6051                        it.remove();
6052                        continue;
6053                    }
6054                    PendingIntentRecord pir = wpir.get();
6055                    if (pir == null) {
6056                        it.remove();
6057                        continue;
6058                    }
6059                    if (packageName == null) {
6060                        // Stopping user, remove all objects for the user.
6061                        if (pir.key.userId != userId) {
6062                            // Not the same user, skip it.
6063                            continue;
6064                        }
6065                    } else {
6066                        if (UserHandle.getAppId(pir.uid) != appId) {
6067                            // Different app id, skip it.
6068                            continue;
6069                        }
6070                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6071                            // Different user, skip it.
6072                            continue;
6073                        }
6074                        if (!pir.key.packageName.equals(packageName)) {
6075                            // Different package, skip it.
6076                            continue;
6077                        }
6078                    }
6079                    if (!doit) {
6080                        return true;
6081                    }
6082                    didSomething = true;
6083                    it.remove();
6084                    pir.canceled = true;
6085                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6086                        pir.key.activity.pendingResults.remove(pir.ref);
6087                    }
6088                }
6089            }
6090        }
6091
6092        if (doit) {
6093            if (purgeCache && packageName != null) {
6094                AttributeCache ac = AttributeCache.instance();
6095                if (ac != null) {
6096                    ac.removePackage(packageName);
6097                }
6098            }
6099            if (mBooted) {
6100                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6101                mStackSupervisor.scheduleIdleLocked();
6102            }
6103        }
6104
6105        return didSomething;
6106    }
6107
6108    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6109        ProcessRecord old = mProcessNames.remove(name, uid);
6110        if (old != null) {
6111            old.uidRecord.numProcs--;
6112            if (old.uidRecord.numProcs == 0) {
6113                // No more processes using this uid, tell clients it is gone.
6114                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6115                        "No more processes in " + old.uidRecord);
6116                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6117                mActiveUids.remove(uid);
6118                mBatteryStatsService.noteUidProcessState(uid,
6119                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6120            }
6121            old.uidRecord = null;
6122        }
6123        mIsolatedProcesses.remove(uid);
6124        return old;
6125    }
6126
6127    private final void addProcessNameLocked(ProcessRecord proc) {
6128        // We shouldn't already have a process under this name, but just in case we
6129        // need to clean up whatever may be there now.
6130        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6131        if (old == proc && proc.persistent) {
6132            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6133            Slog.w(TAG, "Re-adding persistent process " + proc);
6134        } else if (old != null) {
6135            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6136        }
6137        UidRecord uidRec = mActiveUids.get(proc.uid);
6138        if (uidRec == null) {
6139            uidRec = new UidRecord(proc.uid);
6140            // This is the first appearance of the uid, report it now!
6141            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6142                    "Creating new process uid: " + uidRec);
6143            mActiveUids.put(proc.uid, uidRec);
6144            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6145            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6146        }
6147        proc.uidRecord = uidRec;
6148        uidRec.numProcs++;
6149        mProcessNames.put(proc.processName, proc.uid, proc);
6150        if (proc.isolated) {
6151            mIsolatedProcesses.put(proc.uid, proc);
6152        }
6153    }
6154
6155    private final boolean removeProcessLocked(ProcessRecord app,
6156            boolean callerWillRestart, boolean allowRestart, String reason) {
6157        final String name = app.processName;
6158        final int uid = app.uid;
6159        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6160            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6161
6162        removeProcessNameLocked(name, uid);
6163        if (mHeavyWeightProcess == app) {
6164            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6165                    mHeavyWeightProcess.userId, 0));
6166            mHeavyWeightProcess = null;
6167        }
6168        boolean needRestart = false;
6169        if (app.pid > 0 && app.pid != MY_PID) {
6170            int pid = app.pid;
6171            synchronized (mPidsSelfLocked) {
6172                mPidsSelfLocked.remove(pid);
6173                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6174            }
6175            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6176            if (app.isolated) {
6177                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6178            }
6179            boolean willRestart = false;
6180            if (app.persistent && !app.isolated) {
6181                if (!callerWillRestart) {
6182                    willRestart = true;
6183                } else {
6184                    needRestart = true;
6185                }
6186            }
6187            app.kill(reason, true);
6188            handleAppDiedLocked(app, willRestart, allowRestart);
6189            if (willRestart) {
6190                removeLruProcessLocked(app);
6191                addAppLocked(app.info, false, null /* ABI override */);
6192            }
6193        } else {
6194            mRemovedProcesses.add(app);
6195        }
6196
6197        return needRestart;
6198    }
6199
6200    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6201        cleanupAppInLaunchingProvidersLocked(app, true);
6202        removeProcessLocked(app, false, true, "timeout publishing content providers");
6203    }
6204
6205    private final void processStartTimedOutLocked(ProcessRecord app) {
6206        final int pid = app.pid;
6207        boolean gone = false;
6208        synchronized (mPidsSelfLocked) {
6209            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6210            if (knownApp != null && knownApp.thread == null) {
6211                mPidsSelfLocked.remove(pid);
6212                gone = true;
6213            }
6214        }
6215
6216        if (gone) {
6217            Slog.w(TAG, "Process " + app + " failed to attach");
6218            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6219                    pid, app.uid, app.processName);
6220            removeProcessNameLocked(app.processName, app.uid);
6221            if (mHeavyWeightProcess == app) {
6222                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6223                        mHeavyWeightProcess.userId, 0));
6224                mHeavyWeightProcess = null;
6225            }
6226            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6227            if (app.isolated) {
6228                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6229            }
6230            // Take care of any launching providers waiting for this process.
6231            cleanupAppInLaunchingProvidersLocked(app, true);
6232            // Take care of any services that are waiting for the process.
6233            mServices.processStartTimedOutLocked(app);
6234            app.kill("start timeout", true);
6235            removeLruProcessLocked(app);
6236            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6237                Slog.w(TAG, "Unattached app died before backup, skipping");
6238                try {
6239                    IBackupManager bm = IBackupManager.Stub.asInterface(
6240                            ServiceManager.getService(Context.BACKUP_SERVICE));
6241                    bm.agentDisconnected(app.info.packageName);
6242                } catch (RemoteException e) {
6243                    // Can't happen; the backup manager is local
6244                }
6245            }
6246            if (isPendingBroadcastProcessLocked(pid)) {
6247                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6248                skipPendingBroadcastLocked(pid);
6249            }
6250        } else {
6251            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6252        }
6253    }
6254
6255    private final boolean attachApplicationLocked(IApplicationThread thread,
6256            int pid) {
6257
6258        // Find the application record that is being attached...  either via
6259        // the pid if we are running in multiple processes, or just pull the
6260        // next app record if we are emulating process with anonymous threads.
6261        ProcessRecord app;
6262        if (pid != MY_PID && pid >= 0) {
6263            synchronized (mPidsSelfLocked) {
6264                app = mPidsSelfLocked.get(pid);
6265            }
6266        } else {
6267            app = null;
6268        }
6269
6270        if (app == null) {
6271            Slog.w(TAG, "No pending application record for pid " + pid
6272                    + " (IApplicationThread " + thread + "); dropping process");
6273            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6274            if (pid > 0 && pid != MY_PID) {
6275                Process.killProcessQuiet(pid);
6276                //TODO: killProcessGroup(app.info.uid, pid);
6277            } else {
6278                try {
6279                    thread.scheduleExit();
6280                } catch (Exception e) {
6281                    // Ignore exceptions.
6282                }
6283            }
6284            return false;
6285        }
6286
6287        // If this application record is still attached to a previous
6288        // process, clean it up now.
6289        if (app.thread != null) {
6290            handleAppDiedLocked(app, true, true);
6291        }
6292
6293        // Tell the process all about itself.
6294
6295        if (DEBUG_ALL) Slog.v(
6296                TAG, "Binding process pid " + pid + " to record " + app);
6297
6298        final String processName = app.processName;
6299        try {
6300            AppDeathRecipient adr = new AppDeathRecipient(
6301                    app, pid, thread);
6302            thread.asBinder().linkToDeath(adr, 0);
6303            app.deathRecipient = adr;
6304        } catch (RemoteException e) {
6305            app.resetPackageList(mProcessStats);
6306            startProcessLocked(app, "link fail", processName);
6307            return false;
6308        }
6309
6310        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6311
6312        app.makeActive(thread, mProcessStats);
6313        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6314        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6315        app.forcingToForeground = null;
6316        updateProcessForegroundLocked(app, false, false);
6317        app.hasShownUi = false;
6318        app.debugging = false;
6319        app.cached = false;
6320        app.killedByAm = false;
6321
6322        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6323
6324        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6325        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6326
6327        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6328            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6329            msg.obj = app;
6330            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6331        }
6332
6333        if (!normalMode) {
6334            Slog.i(TAG, "Launching preboot mode app: " + app);
6335        }
6336
6337        if (DEBUG_ALL) Slog.v(
6338            TAG, "New app record " + app
6339            + " thread=" + thread.asBinder() + " pid=" + pid);
6340        try {
6341            int testMode = IApplicationThread.DEBUG_OFF;
6342            if (mDebugApp != null && mDebugApp.equals(processName)) {
6343                testMode = mWaitForDebugger
6344                    ? IApplicationThread.DEBUG_WAIT
6345                    : IApplicationThread.DEBUG_ON;
6346                app.debugging = true;
6347                if (mDebugTransient) {
6348                    mDebugApp = mOrigDebugApp;
6349                    mWaitForDebugger = mOrigWaitForDebugger;
6350                }
6351            }
6352            String profileFile = app.instrumentationProfileFile;
6353            ParcelFileDescriptor profileFd = null;
6354            int samplingInterval = 0;
6355            boolean profileAutoStop = false;
6356            if (mProfileApp != null && mProfileApp.equals(processName)) {
6357                mProfileProc = app;
6358                profileFile = mProfileFile;
6359                profileFd = mProfileFd;
6360                samplingInterval = mSamplingInterval;
6361                profileAutoStop = mAutoStopProfiler;
6362            }
6363            boolean enableTrackAllocation = false;
6364            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6365                enableTrackAllocation = true;
6366                mTrackAllocationApp = null;
6367            }
6368
6369            // If the app is being launched for restore or full backup, set it up specially
6370            boolean isRestrictedBackupMode = false;
6371            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6372                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6373                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6374                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6375            }
6376
6377            notifyPackageUse(app.instrumentationInfo != null
6378                    ? app.instrumentationInfo.packageName
6379                    : app.info.packageName);
6380            if (app.instrumentationClass != null) {
6381                notifyPackageUse(app.instrumentationClass.getPackageName());
6382            }
6383            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6384                    + processName + " with config " + mConfiguration);
6385            ApplicationInfo appInfo = app.instrumentationInfo != null
6386                    ? app.instrumentationInfo : app.info;
6387            app.compat = compatibilityInfoForPackageLocked(appInfo);
6388            if (profileFd != null) {
6389                profileFd = profileFd.dup();
6390            }
6391            ProfilerInfo profilerInfo = profileFile == null ? null
6392                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6393            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6394                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6395                    app.instrumentationUiAutomationConnection, testMode,
6396                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6397                    isRestrictedBackupMode || !normalMode, app.persistent,
6398                    new Configuration(mConfiguration), app.compat,
6399                    getCommonServicesLocked(app.isolated),
6400                    mCoreSettingsObserver.getCoreSettingsLocked());
6401            updateLruProcessLocked(app, false, null);
6402            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6403        } catch (Exception e) {
6404            // todo: Yikes!  What should we do?  For now we will try to
6405            // start another process, but that could easily get us in
6406            // an infinite loop of restarting processes...
6407            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6408
6409            app.resetPackageList(mProcessStats);
6410            app.unlinkDeathRecipient();
6411            startProcessLocked(app, "bind fail", processName);
6412            return false;
6413        }
6414
6415        // Remove this record from the list of starting applications.
6416        mPersistentStartingProcesses.remove(app);
6417        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6418                "Attach application locked removing on hold: " + app);
6419        mProcessesOnHold.remove(app);
6420
6421        boolean badApp = false;
6422        boolean didSomething = false;
6423
6424        // See if the top visible activity is waiting to run in this process...
6425        if (normalMode) {
6426            try {
6427                if (mStackSupervisor.attachApplicationLocked(app)) {
6428                    didSomething = true;
6429                }
6430            } catch (Exception e) {
6431                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6432                badApp = true;
6433            }
6434        }
6435
6436        // Find any services that should be running in this process...
6437        if (!badApp) {
6438            try {
6439                didSomething |= mServices.attachApplicationLocked(app, processName);
6440            } catch (Exception e) {
6441                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6442                badApp = true;
6443            }
6444        }
6445
6446        // Check if a next-broadcast receiver is in this process...
6447        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6448            try {
6449                didSomething |= sendPendingBroadcastsLocked(app);
6450            } catch (Exception e) {
6451                // If the app died trying to launch the receiver we declare it 'bad'
6452                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6453                badApp = true;
6454            }
6455        }
6456
6457        // Check whether the next backup agent is in this process...
6458        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6459            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6460                    "New app is backup target, launching agent for " + app);
6461            notifyPackageUse(mBackupTarget.appInfo.packageName);
6462            try {
6463                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6464                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6465                        mBackupTarget.backupMode);
6466            } catch (Exception e) {
6467                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6468                badApp = true;
6469            }
6470        }
6471
6472        if (badApp) {
6473            app.kill("error during init", true);
6474            handleAppDiedLocked(app, false, true);
6475            return false;
6476        }
6477
6478        if (!didSomething) {
6479            updateOomAdjLocked();
6480        }
6481
6482        return true;
6483    }
6484
6485    @Override
6486    public final void attachApplication(IApplicationThread thread) {
6487        synchronized (this) {
6488            int callingPid = Binder.getCallingPid();
6489            final long origId = Binder.clearCallingIdentity();
6490            attachApplicationLocked(thread, callingPid);
6491            Binder.restoreCallingIdentity(origId);
6492        }
6493    }
6494
6495    @Override
6496    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6497        final long origId = Binder.clearCallingIdentity();
6498        synchronized (this) {
6499            ActivityStack stack = ActivityRecord.getStackLocked(token);
6500            if (stack != null) {
6501                ActivityRecord r =
6502                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6503                if (stopProfiling) {
6504                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6505                        try {
6506                            mProfileFd.close();
6507                        } catch (IOException e) {
6508                        }
6509                        clearProfilerLocked();
6510                    }
6511                }
6512            }
6513        }
6514        Binder.restoreCallingIdentity(origId);
6515    }
6516
6517    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6518        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6519                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6520    }
6521
6522    void enableScreenAfterBoot() {
6523        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6524                SystemClock.uptimeMillis());
6525        mWindowManager.enableScreenAfterBoot();
6526
6527        synchronized (this) {
6528            updateEventDispatchingLocked();
6529        }
6530    }
6531
6532    @Override
6533    public void showBootMessage(final CharSequence msg, final boolean always) {
6534        if (Binder.getCallingUid() != Process.myUid()) {
6535            // These days only the core system can call this, so apps can't get in
6536            // the way of what we show about running them.
6537        }
6538        mWindowManager.showBootMessage(msg, always);
6539    }
6540
6541    @Override
6542    public void keyguardWaitingForActivityDrawn() {
6543        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6544        final long token = Binder.clearCallingIdentity();
6545        try {
6546            synchronized (this) {
6547                if (DEBUG_LOCKSCREEN) logLockScreen("");
6548                mWindowManager.keyguardWaitingForActivityDrawn();
6549                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6550                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6551                    updateSleepIfNeededLocked();
6552                }
6553            }
6554        } finally {
6555            Binder.restoreCallingIdentity(token);
6556        }
6557    }
6558
6559    @Override
6560    public void keyguardGoingAway(boolean disableWindowAnimations,
6561            boolean keyguardGoingToNotificationShade) {
6562        enforceNotIsolatedCaller("keyguardGoingAway");
6563        final long token = Binder.clearCallingIdentity();
6564        try {
6565            synchronized (this) {
6566                if (DEBUG_LOCKSCREEN) logLockScreen("");
6567                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6568                        keyguardGoingToNotificationShade);
6569                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6570                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6571                    updateSleepIfNeededLocked();
6572                }
6573            }
6574        } finally {
6575            Binder.restoreCallingIdentity(token);
6576        }
6577    }
6578
6579    final void finishBooting() {
6580        synchronized (this) {
6581            if (!mBootAnimationComplete) {
6582                mCallFinishBooting = true;
6583                return;
6584            }
6585            mCallFinishBooting = false;
6586        }
6587
6588        ArraySet<String> completedIsas = new ArraySet<String>();
6589        for (String abi : Build.SUPPORTED_ABIS) {
6590            Process.establishZygoteConnectionForAbi(abi);
6591            final String instructionSet = VMRuntime.getInstructionSet(abi);
6592            if (!completedIsas.contains(instructionSet)) {
6593                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6594                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6595                }
6596                completedIsas.add(instructionSet);
6597            }
6598        }
6599
6600        IntentFilter pkgFilter = new IntentFilter();
6601        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6602        pkgFilter.addDataScheme("package");
6603        mContext.registerReceiver(new BroadcastReceiver() {
6604            @Override
6605            public void onReceive(Context context, Intent intent) {
6606                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6607                if (pkgs != null) {
6608                    for (String pkg : pkgs) {
6609                        synchronized (ActivityManagerService.this) {
6610                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6611                                    0, "query restart")) {
6612                                setResultCode(Activity.RESULT_OK);
6613                                return;
6614                            }
6615                        }
6616                    }
6617                }
6618            }
6619        }, pkgFilter);
6620
6621        IntentFilter dumpheapFilter = new IntentFilter();
6622        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6623        mContext.registerReceiver(new BroadcastReceiver() {
6624            @Override
6625            public void onReceive(Context context, Intent intent) {
6626                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6627                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6628                } else {
6629                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6630                }
6631            }
6632        }, dumpheapFilter);
6633
6634        // Let system services know.
6635        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6636
6637        synchronized (this) {
6638            // Ensure that any processes we had put on hold are now started
6639            // up.
6640            final int NP = mProcessesOnHold.size();
6641            if (NP > 0) {
6642                ArrayList<ProcessRecord> procs =
6643                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6644                for (int ip=0; ip<NP; ip++) {
6645                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6646                            + procs.get(ip));
6647                    startProcessLocked(procs.get(ip), "on-hold", null);
6648                }
6649            }
6650
6651            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6652                // Start looking for apps that are abusing wake locks.
6653                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6654                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6655                // Tell anyone interested that we are done booting!
6656                SystemProperties.set("sys.boot_completed", "1");
6657
6658                // And trigger dev.bootcomplete if we are not showing encryption progress
6659                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6660                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6661                    SystemProperties.set("dev.bootcomplete", "1");
6662                }
6663                mUserController.sendBootCompletedLocked(
6664                        new IIntentReceiver.Stub() {
6665                            @Override
6666                            public void performReceive(Intent intent, int resultCode,
6667                                    String data, Bundle extras, boolean ordered,
6668                                    boolean sticky, int sendingUser) {
6669                                synchronized (ActivityManagerService.this) {
6670                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6671                                            true, false);
6672                                }
6673                            }
6674                        });
6675                scheduleStartProfilesLocked();
6676            }
6677        }
6678    }
6679
6680    @Override
6681    public void bootAnimationComplete() {
6682        final boolean callFinishBooting;
6683        synchronized (this) {
6684            callFinishBooting = mCallFinishBooting;
6685            mBootAnimationComplete = true;
6686        }
6687        if (callFinishBooting) {
6688            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6689            finishBooting();
6690            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6691        }
6692    }
6693
6694    final void ensureBootCompleted() {
6695        boolean booting;
6696        boolean enableScreen;
6697        synchronized (this) {
6698            booting = mBooting;
6699            mBooting = false;
6700            enableScreen = !mBooted;
6701            mBooted = true;
6702        }
6703
6704        if (booting) {
6705            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6706            finishBooting();
6707            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6708        }
6709
6710        if (enableScreen) {
6711            enableScreenAfterBoot();
6712        }
6713    }
6714
6715    @Override
6716    public final void activityResumed(IBinder token) {
6717        final long origId = Binder.clearCallingIdentity();
6718        synchronized(this) {
6719            ActivityStack stack = ActivityRecord.getStackLocked(token);
6720            if (stack != null) {
6721                ActivityRecord.activityResumedLocked(token);
6722            }
6723        }
6724        Binder.restoreCallingIdentity(origId);
6725    }
6726
6727    @Override
6728    public final void activityPaused(IBinder token) {
6729        final long origId = Binder.clearCallingIdentity();
6730        synchronized(this) {
6731            ActivityStack stack = ActivityRecord.getStackLocked(token);
6732            if (stack != null) {
6733                stack.activityPausedLocked(token, false);
6734            }
6735        }
6736        Binder.restoreCallingIdentity(origId);
6737    }
6738
6739    @Override
6740    public final void activityStopped(IBinder token, Bundle icicle,
6741            PersistableBundle persistentState, CharSequence description) {
6742        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6743
6744        // Refuse possible leaked file descriptors
6745        if (icicle != null && icicle.hasFileDescriptors()) {
6746            throw new IllegalArgumentException("File descriptors passed in Bundle");
6747        }
6748
6749        final long origId = Binder.clearCallingIdentity();
6750
6751        synchronized (this) {
6752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6753            if (r != null) {
6754                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6755            }
6756        }
6757
6758        trimApplications();
6759
6760        Binder.restoreCallingIdentity(origId);
6761    }
6762
6763    @Override
6764    public final void activityDestroyed(IBinder token) {
6765        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6766        synchronized (this) {
6767            ActivityStack stack = ActivityRecord.getStackLocked(token);
6768            if (stack != null) {
6769                stack.activityDestroyedLocked(token, "activityDestroyed");
6770            }
6771        }
6772    }
6773
6774    @Override
6775    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6776            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6777        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6778                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6779        synchronized (this) {
6780            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6781            if (record == null) {
6782                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6783                        + "found for: " + token);
6784            }
6785            record.setSizeConfigurations(horizontalSizeConfiguration,
6786                    verticalSizeConfigurations, smallestSizeConfigurations);
6787        }
6788    }
6789
6790    @Override
6791    public final void backgroundResourcesReleased(IBinder token) {
6792        final long origId = Binder.clearCallingIdentity();
6793        try {
6794            synchronized (this) {
6795                ActivityStack stack = ActivityRecord.getStackLocked(token);
6796                if (stack != null) {
6797                    stack.backgroundResourcesReleased();
6798                }
6799            }
6800        } finally {
6801            Binder.restoreCallingIdentity(origId);
6802        }
6803    }
6804
6805    @Override
6806    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6807        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6808    }
6809
6810    @Override
6811    public final void notifyEnterAnimationComplete(IBinder token) {
6812        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6813    }
6814
6815    @Override
6816    public String getCallingPackage(IBinder token) {
6817        synchronized (this) {
6818            ActivityRecord r = getCallingRecordLocked(token);
6819            return r != null ? r.info.packageName : null;
6820        }
6821    }
6822
6823    @Override
6824    public ComponentName getCallingActivity(IBinder token) {
6825        synchronized (this) {
6826            ActivityRecord r = getCallingRecordLocked(token);
6827            return r != null ? r.intent.getComponent() : null;
6828        }
6829    }
6830
6831    private ActivityRecord getCallingRecordLocked(IBinder token) {
6832        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6833        if (r == null) {
6834            return null;
6835        }
6836        return r.resultTo;
6837    }
6838
6839    @Override
6840    public ComponentName getActivityClassForToken(IBinder token) {
6841        synchronized(this) {
6842            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6843            if (r == null) {
6844                return null;
6845            }
6846            return r.intent.getComponent();
6847        }
6848    }
6849
6850    @Override
6851    public String getPackageForToken(IBinder token) {
6852        synchronized(this) {
6853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6854            if (r == null) {
6855                return null;
6856            }
6857            return r.packageName;
6858        }
6859    }
6860
6861    @Override
6862    public boolean isRootVoiceInteraction(IBinder token) {
6863        synchronized(this) {
6864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6865            if (r == null) {
6866                return false;
6867            }
6868            return r.rootVoiceInteraction;
6869        }
6870    }
6871
6872    @Override
6873    public IIntentSender getIntentSender(int type,
6874            String packageName, IBinder token, String resultWho,
6875            int requestCode, Intent[] intents, String[] resolvedTypes,
6876            int flags, Bundle bOptions, int userId) {
6877        enforceNotIsolatedCaller("getIntentSender");
6878        // Refuse possible leaked file descriptors
6879        if (intents != null) {
6880            if (intents.length < 1) {
6881                throw new IllegalArgumentException("Intents array length must be >= 1");
6882            }
6883            for (int i=0; i<intents.length; i++) {
6884                Intent intent = intents[i];
6885                if (intent != null) {
6886                    if (intent.hasFileDescriptors()) {
6887                        throw new IllegalArgumentException("File descriptors passed in Intent");
6888                    }
6889                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6890                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6891                        throw new IllegalArgumentException(
6892                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6893                    }
6894                    intents[i] = new Intent(intent);
6895                }
6896            }
6897            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6898                throw new IllegalArgumentException(
6899                        "Intent array length does not match resolvedTypes length");
6900            }
6901        }
6902        if (bOptions != null) {
6903            if (bOptions.hasFileDescriptors()) {
6904                throw new IllegalArgumentException("File descriptors passed in options");
6905            }
6906        }
6907
6908        synchronized(this) {
6909            int callingUid = Binder.getCallingUid();
6910            int origUserId = userId;
6911            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6912                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6913                    ALLOW_NON_FULL, "getIntentSender", null);
6914            if (origUserId == UserHandle.USER_CURRENT) {
6915                // We don't want to evaluate this until the pending intent is
6916                // actually executed.  However, we do want to always do the
6917                // security checking for it above.
6918                userId = UserHandle.USER_CURRENT;
6919            }
6920            try {
6921                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6922                    int uid = AppGlobals.getPackageManager()
6923                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6924                    if (!UserHandle.isSameApp(callingUid, uid)) {
6925                        String msg = "Permission Denial: getIntentSender() from pid="
6926                            + Binder.getCallingPid()
6927                            + ", uid=" + Binder.getCallingUid()
6928                            + ", (need uid=" + uid + ")"
6929                            + " is not allowed to send as package " + packageName;
6930                        Slog.w(TAG, msg);
6931                        throw new SecurityException(msg);
6932                    }
6933                }
6934
6935                return getIntentSenderLocked(type, packageName, callingUid, userId,
6936                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6937
6938            } catch (RemoteException e) {
6939                throw new SecurityException(e);
6940            }
6941        }
6942    }
6943
6944    IIntentSender getIntentSenderLocked(int type, String packageName,
6945            int callingUid, int userId, IBinder token, String resultWho,
6946            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6947            Bundle bOptions) {
6948        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6949        ActivityRecord activity = null;
6950        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6951            activity = ActivityRecord.isInStackLocked(token);
6952            if (activity == null) {
6953                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6954                return null;
6955            }
6956            if (activity.finishing) {
6957                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6958                return null;
6959            }
6960        }
6961
6962        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6963        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6964        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6965        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6966                |PendingIntent.FLAG_UPDATE_CURRENT);
6967
6968        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6969                type, packageName, activity, resultWho,
6970                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6971        WeakReference<PendingIntentRecord> ref;
6972        ref = mIntentSenderRecords.get(key);
6973        PendingIntentRecord rec = ref != null ? ref.get() : null;
6974        if (rec != null) {
6975            if (!cancelCurrent) {
6976                if (updateCurrent) {
6977                    if (rec.key.requestIntent != null) {
6978                        rec.key.requestIntent.replaceExtras(intents != null ?
6979                                intents[intents.length - 1] : null);
6980                    }
6981                    if (intents != null) {
6982                        intents[intents.length-1] = rec.key.requestIntent;
6983                        rec.key.allIntents = intents;
6984                        rec.key.allResolvedTypes = resolvedTypes;
6985                    } else {
6986                        rec.key.allIntents = null;
6987                        rec.key.allResolvedTypes = null;
6988                    }
6989                }
6990                return rec;
6991            }
6992            rec.canceled = true;
6993            mIntentSenderRecords.remove(key);
6994        }
6995        if (noCreate) {
6996            return rec;
6997        }
6998        rec = new PendingIntentRecord(this, key, callingUid);
6999        mIntentSenderRecords.put(key, rec.ref);
7000        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7001            if (activity.pendingResults == null) {
7002                activity.pendingResults
7003                        = new HashSet<WeakReference<PendingIntentRecord>>();
7004            }
7005            activity.pendingResults.add(rec.ref);
7006        }
7007        return rec;
7008    }
7009
7010    @Override
7011    public void cancelIntentSender(IIntentSender sender) {
7012        if (!(sender instanceof PendingIntentRecord)) {
7013            return;
7014        }
7015        synchronized(this) {
7016            PendingIntentRecord rec = (PendingIntentRecord)sender;
7017            try {
7018                int uid = AppGlobals.getPackageManager()
7019                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
7020                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7021                    String msg = "Permission Denial: cancelIntentSender() from pid="
7022                        + Binder.getCallingPid()
7023                        + ", uid=" + Binder.getCallingUid()
7024                        + " is not allowed to cancel packges "
7025                        + rec.key.packageName;
7026                    Slog.w(TAG, msg);
7027                    throw new SecurityException(msg);
7028                }
7029            } catch (RemoteException e) {
7030                throw new SecurityException(e);
7031            }
7032            cancelIntentSenderLocked(rec, true);
7033        }
7034    }
7035
7036    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7037        rec.canceled = true;
7038        mIntentSenderRecords.remove(rec.key);
7039        if (cleanActivity && rec.key.activity != null) {
7040            rec.key.activity.pendingResults.remove(rec.ref);
7041        }
7042    }
7043
7044    @Override
7045    public String getPackageForIntentSender(IIntentSender pendingResult) {
7046        if (!(pendingResult instanceof PendingIntentRecord)) {
7047            return null;
7048        }
7049        try {
7050            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7051            return res.key.packageName;
7052        } catch (ClassCastException e) {
7053        }
7054        return null;
7055    }
7056
7057    @Override
7058    public int getUidForIntentSender(IIntentSender sender) {
7059        if (sender instanceof PendingIntentRecord) {
7060            try {
7061                PendingIntentRecord res = (PendingIntentRecord)sender;
7062                return res.uid;
7063            } catch (ClassCastException e) {
7064            }
7065        }
7066        return -1;
7067    }
7068
7069    @Override
7070    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7071        if (!(pendingResult instanceof PendingIntentRecord)) {
7072            return false;
7073        }
7074        try {
7075            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7076            if (res.key.allIntents == null) {
7077                return false;
7078            }
7079            for (int i=0; i<res.key.allIntents.length; i++) {
7080                Intent intent = res.key.allIntents[i];
7081                if (intent.getPackage() != null && intent.getComponent() != null) {
7082                    return false;
7083                }
7084            }
7085            return true;
7086        } catch (ClassCastException e) {
7087        }
7088        return false;
7089    }
7090
7091    @Override
7092    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7093        if (!(pendingResult instanceof PendingIntentRecord)) {
7094            return false;
7095        }
7096        try {
7097            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7098            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7099                return true;
7100            }
7101            return false;
7102        } catch (ClassCastException e) {
7103        }
7104        return false;
7105    }
7106
7107    @Override
7108    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7109        if (!(pendingResult instanceof PendingIntentRecord)) {
7110            return null;
7111        }
7112        try {
7113            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7114            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7115        } catch (ClassCastException e) {
7116        }
7117        return null;
7118    }
7119
7120    @Override
7121    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7122        if (!(pendingResult instanceof PendingIntentRecord)) {
7123            return null;
7124        }
7125        try {
7126            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7127            synchronized (this) {
7128                return getTagForIntentSenderLocked(res, prefix);
7129            }
7130        } catch (ClassCastException e) {
7131        }
7132        return null;
7133    }
7134
7135    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7136        final Intent intent = res.key.requestIntent;
7137        if (intent != null) {
7138            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7139                    || res.lastTagPrefix.equals(prefix))) {
7140                return res.lastTag;
7141            }
7142            res.lastTagPrefix = prefix;
7143            final StringBuilder sb = new StringBuilder(128);
7144            if (prefix != null) {
7145                sb.append(prefix);
7146            }
7147            if (intent.getAction() != null) {
7148                sb.append(intent.getAction());
7149            } else if (intent.getComponent() != null) {
7150                intent.getComponent().appendShortString(sb);
7151            } else {
7152                sb.append("?");
7153            }
7154            return res.lastTag = sb.toString();
7155        }
7156        return null;
7157    }
7158
7159    @Override
7160    public void setProcessLimit(int max) {
7161        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7162                "setProcessLimit()");
7163        synchronized (this) {
7164            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7165            mProcessLimitOverride = max;
7166        }
7167        trimApplications();
7168    }
7169
7170    @Override
7171    public int getProcessLimit() {
7172        synchronized (this) {
7173            return mProcessLimitOverride;
7174        }
7175    }
7176
7177    void foregroundTokenDied(ForegroundToken token) {
7178        synchronized (ActivityManagerService.this) {
7179            synchronized (mPidsSelfLocked) {
7180                ForegroundToken cur
7181                    = mForegroundProcesses.get(token.pid);
7182                if (cur != token) {
7183                    return;
7184                }
7185                mForegroundProcesses.remove(token.pid);
7186                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7187                if (pr == null) {
7188                    return;
7189                }
7190                pr.forcingToForeground = null;
7191                updateProcessForegroundLocked(pr, false, false);
7192            }
7193            updateOomAdjLocked();
7194        }
7195    }
7196
7197    @Override
7198    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7199        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7200                "setProcessForeground()");
7201        synchronized(this) {
7202            boolean changed = false;
7203
7204            synchronized (mPidsSelfLocked) {
7205                ProcessRecord pr = mPidsSelfLocked.get(pid);
7206                if (pr == null && isForeground) {
7207                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7208                    return;
7209                }
7210                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7211                if (oldToken != null) {
7212                    oldToken.token.unlinkToDeath(oldToken, 0);
7213                    mForegroundProcesses.remove(pid);
7214                    if (pr != null) {
7215                        pr.forcingToForeground = null;
7216                    }
7217                    changed = true;
7218                }
7219                if (isForeground && token != null) {
7220                    ForegroundToken newToken = new ForegroundToken() {
7221                        @Override
7222                        public void binderDied() {
7223                            foregroundTokenDied(this);
7224                        }
7225                    };
7226                    newToken.pid = pid;
7227                    newToken.token = token;
7228                    try {
7229                        token.linkToDeath(newToken, 0);
7230                        mForegroundProcesses.put(pid, newToken);
7231                        pr.forcingToForeground = token;
7232                        changed = true;
7233                    } catch (RemoteException e) {
7234                        // If the process died while doing this, we will later
7235                        // do the cleanup with the process death link.
7236                    }
7237                }
7238            }
7239
7240            if (changed) {
7241                updateOomAdjLocked();
7242            }
7243        }
7244    }
7245
7246    @Override
7247    public boolean inMultiWindowMode(IBinder token) {
7248        final long origId = Binder.clearCallingIdentity();
7249        try {
7250            synchronized(this) {
7251                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7252                if (r == null) {
7253                    return false;
7254                }
7255                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7256                return !r.task.mFullscreen;
7257            }
7258        } finally {
7259            Binder.restoreCallingIdentity(origId);
7260        }
7261    }
7262
7263    @Override
7264    public boolean inPictureInPictureMode(IBinder token) {
7265        final long origId = Binder.clearCallingIdentity();
7266        try {
7267            synchronized(this) {
7268                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7269                if (stack == null) {
7270                    return false;
7271                }
7272                return stack.mStackId == PINNED_STACK_ID;
7273            }
7274        } finally {
7275            Binder.restoreCallingIdentity(origId);
7276        }
7277    }
7278
7279    @Override
7280    public void enterPictureInPictureMode(IBinder token) {
7281        final long origId = Binder.clearCallingIdentity();
7282        try {
7283            synchronized(this) {
7284                if (!mSupportsPictureInPicture) {
7285                    throw new IllegalStateException("enterPictureInPictureMode: "
7286                            + "Device doesn't support picture-in-picture mode.");
7287                }
7288
7289                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7290
7291                if (r == null) {
7292                    throw new IllegalStateException("enterPictureInPictureMode: "
7293                            + "Can't find activity for token=" + token);
7294                }
7295
7296                if (!r.supportsPictureInPicture()) {
7297                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7298                            + "Picture-In-Picture not supported for r=" + r);
7299                }
7300
7301                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7302                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7303                        ? mDefaultPinnedStackBounds : null;
7304
7305                mStackSupervisor.moveActivityToStackLocked(
7306                        r, PINNED_STACK_ID, "enterPictureInPictureMode", bounds);
7307            }
7308        } finally {
7309            Binder.restoreCallingIdentity(origId);
7310        }
7311    }
7312
7313    // =========================================================
7314    // PROCESS INFO
7315    // =========================================================
7316
7317    static class ProcessInfoService extends IProcessInfoService.Stub {
7318        final ActivityManagerService mActivityManagerService;
7319        ProcessInfoService(ActivityManagerService activityManagerService) {
7320            mActivityManagerService = activityManagerService;
7321        }
7322
7323        @Override
7324        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7325            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7326                    /*in*/ pids, /*out*/ states, null);
7327        }
7328
7329        @Override
7330        public void getProcessStatesAndOomScoresFromPids(
7331                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7332            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7333                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7334        }
7335    }
7336
7337    /**
7338     * For each PID in the given input array, write the current process state
7339     * for that process into the states array, or -1 to indicate that no
7340     * process with the given PID exists. If scores array is provided, write
7341     * the oom score for the process into the scores array, with INVALID_ADJ
7342     * indicating the PID doesn't exist.
7343     */
7344    public void getProcessStatesAndOomScoresForPIDs(
7345            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7346        if (scores != null) {
7347            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7348                    "getProcessStatesAndOomScoresForPIDs()");
7349        }
7350
7351        if (pids == null) {
7352            throw new NullPointerException("pids");
7353        } else if (states == null) {
7354            throw new NullPointerException("states");
7355        } else if (pids.length != states.length) {
7356            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7357        } else if (scores != null && pids.length != scores.length) {
7358            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7359        }
7360
7361        synchronized (mPidsSelfLocked) {
7362            for (int i = 0; i < pids.length; i++) {
7363                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7364                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7365                        pr.curProcState;
7366                if (scores != null) {
7367                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7368                }
7369            }
7370        }
7371    }
7372
7373    // =========================================================
7374    // PERMISSIONS
7375    // =========================================================
7376
7377    static class PermissionController extends IPermissionController.Stub {
7378        ActivityManagerService mActivityManagerService;
7379        PermissionController(ActivityManagerService activityManagerService) {
7380            mActivityManagerService = activityManagerService;
7381        }
7382
7383        @Override
7384        public boolean checkPermission(String permission, int pid, int uid) {
7385            return mActivityManagerService.checkPermission(permission, pid,
7386                    uid) == PackageManager.PERMISSION_GRANTED;
7387        }
7388
7389        @Override
7390        public String[] getPackagesForUid(int uid) {
7391            return mActivityManagerService.mContext.getPackageManager()
7392                    .getPackagesForUid(uid);
7393        }
7394
7395        @Override
7396        public boolean isRuntimePermission(String permission) {
7397            try {
7398                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7399                        .getPermissionInfo(permission, 0);
7400                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7401            } catch (NameNotFoundException nnfe) {
7402                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7403            }
7404            return false;
7405        }
7406    }
7407
7408    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7409        @Override
7410        public int checkComponentPermission(String permission, int pid, int uid,
7411                int owningUid, boolean exported) {
7412            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7413                    owningUid, exported);
7414        }
7415
7416        @Override
7417        public Object getAMSLock() {
7418            return ActivityManagerService.this;
7419        }
7420    }
7421
7422    /**
7423     * This can be called with or without the global lock held.
7424     */
7425    int checkComponentPermission(String permission, int pid, int uid,
7426            int owningUid, boolean exported) {
7427        if (pid == MY_PID) {
7428            return PackageManager.PERMISSION_GRANTED;
7429        }
7430        return ActivityManager.checkComponentPermission(permission, uid,
7431                owningUid, exported);
7432    }
7433
7434    /**
7435     * As the only public entry point for permissions checking, this method
7436     * can enforce the semantic that requesting a check on a null global
7437     * permission is automatically denied.  (Internally a null permission
7438     * string is used when calling {@link #checkComponentPermission} in cases
7439     * when only uid-based security is needed.)
7440     *
7441     * This can be called with or without the global lock held.
7442     */
7443    @Override
7444    public int checkPermission(String permission, int pid, int uid) {
7445        if (permission == null) {
7446            return PackageManager.PERMISSION_DENIED;
7447        }
7448        return checkComponentPermission(permission, pid, uid, -1, true);
7449    }
7450
7451    @Override
7452    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7453        if (permission == null) {
7454            return PackageManager.PERMISSION_DENIED;
7455        }
7456
7457        // We might be performing an operation on behalf of an indirect binder
7458        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7459        // client identity accordingly before proceeding.
7460        Identity tlsIdentity = sCallerIdentity.get();
7461        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7462            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7463                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7464            uid = tlsIdentity.uid;
7465            pid = tlsIdentity.pid;
7466        }
7467
7468        return checkComponentPermission(permission, pid, uid, -1, true);
7469    }
7470
7471    /**
7472     * Binder IPC calls go through the public entry point.
7473     * This can be called with or without the global lock held.
7474     */
7475    int checkCallingPermission(String permission) {
7476        return checkPermission(permission,
7477                Binder.getCallingPid(),
7478                UserHandle.getAppId(Binder.getCallingUid()));
7479    }
7480
7481    /**
7482     * This can be called with or without the global lock held.
7483     */
7484    void enforceCallingPermission(String permission, String func) {
7485        if (checkCallingPermission(permission)
7486                == PackageManager.PERMISSION_GRANTED) {
7487            return;
7488        }
7489
7490        String msg = "Permission Denial: " + func + " from pid="
7491                + Binder.getCallingPid()
7492                + ", uid=" + Binder.getCallingUid()
7493                + " requires " + permission;
7494        Slog.w(TAG, msg);
7495        throw new SecurityException(msg);
7496    }
7497
7498    /**
7499     * Determine if UID is holding permissions required to access {@link Uri} in
7500     * the given {@link ProviderInfo}. Final permission checking is always done
7501     * in {@link ContentProvider}.
7502     */
7503    private final boolean checkHoldingPermissionsLocked(
7504            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7505        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7506                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7507        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7508            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7509                    != PERMISSION_GRANTED) {
7510                return false;
7511            }
7512        }
7513        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7514    }
7515
7516    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7517            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7518        if (pi.applicationInfo.uid == uid) {
7519            return true;
7520        } else if (!pi.exported) {
7521            return false;
7522        }
7523
7524        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7525        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7526        try {
7527            // check if target holds top-level <provider> permissions
7528            if (!readMet && pi.readPermission != null && considerUidPermissions
7529                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7530                readMet = true;
7531            }
7532            if (!writeMet && pi.writePermission != null && considerUidPermissions
7533                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7534                writeMet = true;
7535            }
7536
7537            // track if unprotected read/write is allowed; any denied
7538            // <path-permission> below removes this ability
7539            boolean allowDefaultRead = pi.readPermission == null;
7540            boolean allowDefaultWrite = pi.writePermission == null;
7541
7542            // check if target holds any <path-permission> that match uri
7543            final PathPermission[] pps = pi.pathPermissions;
7544            if (pps != null) {
7545                final String path = grantUri.uri.getPath();
7546                int i = pps.length;
7547                while (i > 0 && (!readMet || !writeMet)) {
7548                    i--;
7549                    PathPermission pp = pps[i];
7550                    if (pp.match(path)) {
7551                        if (!readMet) {
7552                            final String pprperm = pp.getReadPermission();
7553                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7554                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7555                                    + ": match=" + pp.match(path)
7556                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7557                            if (pprperm != null) {
7558                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7559                                        == PERMISSION_GRANTED) {
7560                                    readMet = true;
7561                                } else {
7562                                    allowDefaultRead = false;
7563                                }
7564                            }
7565                        }
7566                        if (!writeMet) {
7567                            final String ppwperm = pp.getWritePermission();
7568                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7569                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7570                                    + ": match=" + pp.match(path)
7571                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7572                            if (ppwperm != null) {
7573                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7574                                        == PERMISSION_GRANTED) {
7575                                    writeMet = true;
7576                                } else {
7577                                    allowDefaultWrite = false;
7578                                }
7579                            }
7580                        }
7581                    }
7582                }
7583            }
7584
7585            // grant unprotected <provider> read/write, if not blocked by
7586            // <path-permission> above
7587            if (allowDefaultRead) readMet = true;
7588            if (allowDefaultWrite) writeMet = true;
7589
7590        } catch (RemoteException e) {
7591            return false;
7592        }
7593
7594        return readMet && writeMet;
7595    }
7596
7597    public int getAppStartMode(int uid, String packageName) {
7598        synchronized (this) {
7599            return checkAllowBackgroundLocked(uid, packageName, -1);
7600        }
7601    }
7602
7603    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7604        UidRecord uidRec = mActiveUids.get(uid);
7605        if (uidRec == null || uidRec.idle) {
7606            if (callingPid >= 0) {
7607                ProcessRecord proc;
7608                synchronized (mPidsSelfLocked) {
7609                    proc = mPidsSelfLocked.get(callingPid);
7610                }
7611                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7612                    // Whoever is instigating this is in the foreground, so we will allow it
7613                    // to go through.
7614                    return ActivityManager.APP_START_MODE_NORMAL;
7615                }
7616            }
7617            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7618                    != AppOpsManager.MODE_ALLOWED) {
7619                return ActivityManager.APP_START_MODE_DELAYED;
7620            }
7621        }
7622        return ActivityManager.APP_START_MODE_NORMAL;
7623    }
7624
7625    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7626        ProviderInfo pi = null;
7627        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7628        if (cpr != null) {
7629            pi = cpr.info;
7630        } else {
7631            try {
7632                pi = AppGlobals.getPackageManager().resolveContentProvider(
7633                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7634            } catch (RemoteException ex) {
7635            }
7636        }
7637        return pi;
7638    }
7639
7640    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7641        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7642        if (targetUris != null) {
7643            return targetUris.get(grantUri);
7644        }
7645        return null;
7646    }
7647
7648    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7649            String targetPkg, int targetUid, GrantUri grantUri) {
7650        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7651        if (targetUris == null) {
7652            targetUris = Maps.newArrayMap();
7653            mGrantedUriPermissions.put(targetUid, targetUris);
7654        }
7655
7656        UriPermission perm = targetUris.get(grantUri);
7657        if (perm == null) {
7658            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7659            targetUris.put(grantUri, perm);
7660        }
7661
7662        return perm;
7663    }
7664
7665    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7666            final int modeFlags) {
7667        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7668        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7669                : UriPermission.STRENGTH_OWNED;
7670
7671        // Root gets to do everything.
7672        if (uid == 0) {
7673            return true;
7674        }
7675
7676        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7677        if (perms == null) return false;
7678
7679        // First look for exact match
7680        final UriPermission exactPerm = perms.get(grantUri);
7681        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7682            return true;
7683        }
7684
7685        // No exact match, look for prefixes
7686        final int N = perms.size();
7687        for (int i = 0; i < N; i++) {
7688            final UriPermission perm = perms.valueAt(i);
7689            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7690                    && perm.getStrength(modeFlags) >= minStrength) {
7691                return true;
7692            }
7693        }
7694
7695        return false;
7696    }
7697
7698    /**
7699     * @param uri This uri must NOT contain an embedded userId.
7700     * @param userId The userId in which the uri is to be resolved.
7701     */
7702    @Override
7703    public int checkUriPermission(Uri uri, int pid, int uid,
7704            final int modeFlags, int userId, IBinder callerToken) {
7705        enforceNotIsolatedCaller("checkUriPermission");
7706
7707        // Another redirected-binder-call permissions check as in
7708        // {@link checkPermissionWithToken}.
7709        Identity tlsIdentity = sCallerIdentity.get();
7710        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7711            uid = tlsIdentity.uid;
7712            pid = tlsIdentity.pid;
7713        }
7714
7715        // Our own process gets to do everything.
7716        if (pid == MY_PID) {
7717            return PackageManager.PERMISSION_GRANTED;
7718        }
7719        synchronized (this) {
7720            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7721                    ? PackageManager.PERMISSION_GRANTED
7722                    : PackageManager.PERMISSION_DENIED;
7723        }
7724    }
7725
7726    /**
7727     * Check if the targetPkg can be granted permission to access uri by
7728     * the callingUid using the given modeFlags.  Throws a security exception
7729     * if callingUid is not allowed to do this.  Returns the uid of the target
7730     * if the URI permission grant should be performed; returns -1 if it is not
7731     * needed (for example targetPkg already has permission to access the URI).
7732     * If you already know the uid of the target, you can supply it in
7733     * lastTargetUid else set that to -1.
7734     */
7735    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7736            final int modeFlags, int lastTargetUid) {
7737        if (!Intent.isAccessUriMode(modeFlags)) {
7738            return -1;
7739        }
7740
7741        if (targetPkg != null) {
7742            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7743                    "Checking grant " + targetPkg + " permission to " + grantUri);
7744        }
7745
7746        final IPackageManager pm = AppGlobals.getPackageManager();
7747
7748        // If this is not a content: uri, we can't do anything with it.
7749        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7750            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7751                    "Can't grant URI permission for non-content URI: " + grantUri);
7752            return -1;
7753        }
7754
7755        final String authority = grantUri.uri.getAuthority();
7756        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7757        if (pi == null) {
7758            Slog.w(TAG, "No content provider found for permission check: " +
7759                    grantUri.uri.toSafeString());
7760            return -1;
7761        }
7762
7763        int targetUid = lastTargetUid;
7764        if (targetUid < 0 && targetPkg != null) {
7765            try {
7766                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7767                if (targetUid < 0) {
7768                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7769                            "Can't grant URI permission no uid for: " + targetPkg);
7770                    return -1;
7771                }
7772            } catch (RemoteException ex) {
7773                return -1;
7774            }
7775        }
7776
7777        if (targetUid >= 0) {
7778            // First...  does the target actually need this permission?
7779            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7780                // No need to grant the target this permission.
7781                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7782                        "Target " + targetPkg + " already has full permission to " + grantUri);
7783                return -1;
7784            }
7785        } else {
7786            // First...  there is no target package, so can anyone access it?
7787            boolean allowed = pi.exported;
7788            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7789                if (pi.readPermission != null) {
7790                    allowed = false;
7791                }
7792            }
7793            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7794                if (pi.writePermission != null) {
7795                    allowed = false;
7796                }
7797            }
7798            if (allowed) {
7799                return -1;
7800            }
7801        }
7802
7803        /* There is a special cross user grant if:
7804         * - The target is on another user.
7805         * - Apps on the current user can access the uri without any uid permissions.
7806         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7807         * grant uri permissions.
7808         */
7809        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7810                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7811                modeFlags, false /*without considering the uid permissions*/);
7812
7813        // Second...  is the provider allowing granting of URI permissions?
7814        if (!specialCrossUserGrant) {
7815            if (!pi.grantUriPermissions) {
7816                throw new SecurityException("Provider " + pi.packageName
7817                        + "/" + pi.name
7818                        + " does not allow granting of Uri permissions (uri "
7819                        + grantUri + ")");
7820            }
7821            if (pi.uriPermissionPatterns != null) {
7822                final int N = pi.uriPermissionPatterns.length;
7823                boolean allowed = false;
7824                for (int i=0; i<N; i++) {
7825                    if (pi.uriPermissionPatterns[i] != null
7826                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7827                        allowed = true;
7828                        break;
7829                    }
7830                }
7831                if (!allowed) {
7832                    throw new SecurityException("Provider " + pi.packageName
7833                            + "/" + pi.name
7834                            + " does not allow granting of permission to path of Uri "
7835                            + grantUri);
7836                }
7837            }
7838        }
7839
7840        // Third...  does the caller itself have permission to access
7841        // this uri?
7842        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7843            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7844                // Require they hold a strong enough Uri permission
7845                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7846                    throw new SecurityException("Uid " + callingUid
7847                            + " does not have permission to uri " + grantUri);
7848                }
7849            }
7850        }
7851        return targetUid;
7852    }
7853
7854    /**
7855     * @param uri This uri must NOT contain an embedded userId.
7856     * @param userId The userId in which the uri is to be resolved.
7857     */
7858    @Override
7859    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7860            final int modeFlags, int userId) {
7861        enforceNotIsolatedCaller("checkGrantUriPermission");
7862        synchronized(this) {
7863            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7864                    new GrantUri(userId, uri, false), modeFlags, -1);
7865        }
7866    }
7867
7868    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7869            final int modeFlags, UriPermissionOwner owner) {
7870        if (!Intent.isAccessUriMode(modeFlags)) {
7871            return;
7872        }
7873
7874        // So here we are: the caller has the assumed permission
7875        // to the uri, and the target doesn't.  Let's now give this to
7876        // the target.
7877
7878        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7879                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7880
7881        final String authority = grantUri.uri.getAuthority();
7882        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7883        if (pi == null) {
7884            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7885            return;
7886        }
7887
7888        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7889            grantUri.prefix = true;
7890        }
7891        final UriPermission perm = findOrCreateUriPermissionLocked(
7892                pi.packageName, targetPkg, targetUid, grantUri);
7893        perm.grantModes(modeFlags, owner);
7894    }
7895
7896    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7897            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7898        if (targetPkg == null) {
7899            throw new NullPointerException("targetPkg");
7900        }
7901        int targetUid;
7902        final IPackageManager pm = AppGlobals.getPackageManager();
7903        try {
7904            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7905        } catch (RemoteException ex) {
7906            return;
7907        }
7908
7909        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7910                targetUid);
7911        if (targetUid < 0) {
7912            return;
7913        }
7914
7915        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7916                owner);
7917    }
7918
7919    static class NeededUriGrants extends ArrayList<GrantUri> {
7920        final String targetPkg;
7921        final int targetUid;
7922        final int flags;
7923
7924        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7925            this.targetPkg = targetPkg;
7926            this.targetUid = targetUid;
7927            this.flags = flags;
7928        }
7929    }
7930
7931    /**
7932     * Like checkGrantUriPermissionLocked, but takes an Intent.
7933     */
7934    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7935            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7936        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7937                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7938                + " clip=" + (intent != null ? intent.getClipData() : null)
7939                + " from " + intent + "; flags=0x"
7940                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7941
7942        if (targetPkg == null) {
7943            throw new NullPointerException("targetPkg");
7944        }
7945
7946        if (intent == null) {
7947            return null;
7948        }
7949        Uri data = intent.getData();
7950        ClipData clip = intent.getClipData();
7951        if (data == null && clip == null) {
7952            return null;
7953        }
7954        // Default userId for uris in the intent (if they don't specify it themselves)
7955        int contentUserHint = intent.getContentUserHint();
7956        if (contentUserHint == UserHandle.USER_CURRENT) {
7957            contentUserHint = UserHandle.getUserId(callingUid);
7958        }
7959        final IPackageManager pm = AppGlobals.getPackageManager();
7960        int targetUid;
7961        if (needed != null) {
7962            targetUid = needed.targetUid;
7963        } else {
7964            try {
7965                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7966            } catch (RemoteException ex) {
7967                return null;
7968            }
7969            if (targetUid < 0) {
7970                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7971                        "Can't grant URI permission no uid for: " + targetPkg
7972                        + " on user " + targetUserId);
7973                return null;
7974            }
7975        }
7976        if (data != null) {
7977            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7978            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7979                    targetUid);
7980            if (targetUid > 0) {
7981                if (needed == null) {
7982                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7983                }
7984                needed.add(grantUri);
7985            }
7986        }
7987        if (clip != null) {
7988            for (int i=0; i<clip.getItemCount(); i++) {
7989                Uri uri = clip.getItemAt(i).getUri();
7990                if (uri != null) {
7991                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7992                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7993                            targetUid);
7994                    if (targetUid > 0) {
7995                        if (needed == null) {
7996                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7997                        }
7998                        needed.add(grantUri);
7999                    }
8000                } else {
8001                    Intent clipIntent = clip.getItemAt(i).getIntent();
8002                    if (clipIntent != null) {
8003                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8004                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8005                        if (newNeeded != null) {
8006                            needed = newNeeded;
8007                        }
8008                    }
8009                }
8010            }
8011        }
8012
8013        return needed;
8014    }
8015
8016    /**
8017     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8018     */
8019    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8020            UriPermissionOwner owner) {
8021        if (needed != null) {
8022            for (int i=0; i<needed.size(); i++) {
8023                GrantUri grantUri = needed.get(i);
8024                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8025                        grantUri, needed.flags, owner);
8026            }
8027        }
8028    }
8029
8030    void grantUriPermissionFromIntentLocked(int callingUid,
8031            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8032        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8033                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8034        if (needed == null) {
8035            return;
8036        }
8037
8038        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8039    }
8040
8041    /**
8042     * @param uri This uri must NOT contain an embedded userId.
8043     * @param userId The userId in which the uri is to be resolved.
8044     */
8045    @Override
8046    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8047            final int modeFlags, int userId) {
8048        enforceNotIsolatedCaller("grantUriPermission");
8049        GrantUri grantUri = new GrantUri(userId, uri, false);
8050        synchronized(this) {
8051            final ProcessRecord r = getRecordForAppLocked(caller);
8052            if (r == null) {
8053                throw new SecurityException("Unable to find app for caller "
8054                        + caller
8055                        + " when granting permission to uri " + grantUri);
8056            }
8057            if (targetPkg == null) {
8058                throw new IllegalArgumentException("null target");
8059            }
8060            if (grantUri == null) {
8061                throw new IllegalArgumentException("null uri");
8062            }
8063
8064            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8065                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8066                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8067                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8068
8069            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8070                    UserHandle.getUserId(r.uid));
8071        }
8072    }
8073
8074    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8075        if (perm.modeFlags == 0) {
8076            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8077                    perm.targetUid);
8078            if (perms != null) {
8079                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8080                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8081
8082                perms.remove(perm.uri);
8083                if (perms.isEmpty()) {
8084                    mGrantedUriPermissions.remove(perm.targetUid);
8085                }
8086            }
8087        }
8088    }
8089
8090    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8091        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8092                "Revoking all granted permissions to " + grantUri);
8093
8094        final IPackageManager pm = AppGlobals.getPackageManager();
8095        final String authority = grantUri.uri.getAuthority();
8096        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8097        if (pi == null) {
8098            Slog.w(TAG, "No content provider found for permission revoke: "
8099                    + grantUri.toSafeString());
8100            return;
8101        }
8102
8103        // Does the caller have this permission on the URI?
8104        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8105            // If they don't have direct access to the URI, then revoke any
8106            // ownerless URI permissions that have been granted to them.
8107            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8108            if (perms != null) {
8109                boolean persistChanged = false;
8110                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8111                    final UriPermission perm = it.next();
8112                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8113                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8114                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8115                                "Revoking non-owned " + perm.targetUid
8116                                + " permission to " + perm.uri);
8117                        persistChanged |= perm.revokeModes(
8118                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8119                        if (perm.modeFlags == 0) {
8120                            it.remove();
8121                        }
8122                    }
8123                }
8124                if (perms.isEmpty()) {
8125                    mGrantedUriPermissions.remove(callingUid);
8126                }
8127                if (persistChanged) {
8128                    schedulePersistUriGrants();
8129                }
8130            }
8131            return;
8132        }
8133
8134        boolean persistChanged = false;
8135
8136        // Go through all of the permissions and remove any that match.
8137        int N = mGrantedUriPermissions.size();
8138        for (int i = 0; i < N; i++) {
8139            final int targetUid = mGrantedUriPermissions.keyAt(i);
8140            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8141
8142            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8143                final UriPermission perm = it.next();
8144                if (perm.uri.sourceUserId == grantUri.sourceUserId
8145                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8146                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8147                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8148                    persistChanged |= perm.revokeModes(
8149                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8150                    if (perm.modeFlags == 0) {
8151                        it.remove();
8152                    }
8153                }
8154            }
8155
8156            if (perms.isEmpty()) {
8157                mGrantedUriPermissions.remove(targetUid);
8158                N--;
8159                i--;
8160            }
8161        }
8162
8163        if (persistChanged) {
8164            schedulePersistUriGrants();
8165        }
8166    }
8167
8168    /**
8169     * @param uri This uri must NOT contain an embedded userId.
8170     * @param userId The userId in which the uri is to be resolved.
8171     */
8172    @Override
8173    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8174            int userId) {
8175        enforceNotIsolatedCaller("revokeUriPermission");
8176        synchronized(this) {
8177            final ProcessRecord r = getRecordForAppLocked(caller);
8178            if (r == null) {
8179                throw new SecurityException("Unable to find app for caller "
8180                        + caller
8181                        + " when revoking permission to uri " + uri);
8182            }
8183            if (uri == null) {
8184                Slog.w(TAG, "revokeUriPermission: null uri");
8185                return;
8186            }
8187
8188            if (!Intent.isAccessUriMode(modeFlags)) {
8189                return;
8190            }
8191
8192            final String authority = uri.getAuthority();
8193            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8194            if (pi == null) {
8195                Slog.w(TAG, "No content provider found for permission revoke: "
8196                        + uri.toSafeString());
8197                return;
8198            }
8199
8200            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8201        }
8202    }
8203
8204    /**
8205     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8206     * given package.
8207     *
8208     * @param packageName Package name to match, or {@code null} to apply to all
8209     *            packages.
8210     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8211     *            to all users.
8212     * @param persistable If persistable grants should be removed.
8213     */
8214    private void removeUriPermissionsForPackageLocked(
8215            String packageName, int userHandle, boolean persistable) {
8216        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8217            throw new IllegalArgumentException("Must narrow by either package or user");
8218        }
8219
8220        boolean persistChanged = false;
8221
8222        int N = mGrantedUriPermissions.size();
8223        for (int i = 0; i < N; i++) {
8224            final int targetUid = mGrantedUriPermissions.keyAt(i);
8225            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8226
8227            // Only inspect grants matching user
8228            if (userHandle == UserHandle.USER_ALL
8229                    || userHandle == UserHandle.getUserId(targetUid)) {
8230                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8231                    final UriPermission perm = it.next();
8232
8233                    // Only inspect grants matching package
8234                    if (packageName == null || perm.sourcePkg.equals(packageName)
8235                            || perm.targetPkg.equals(packageName)) {
8236                        persistChanged |= perm.revokeModes(persistable
8237                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8238
8239                        // Only remove when no modes remain; any persisted grants
8240                        // will keep this alive.
8241                        if (perm.modeFlags == 0) {
8242                            it.remove();
8243                        }
8244                    }
8245                }
8246
8247                if (perms.isEmpty()) {
8248                    mGrantedUriPermissions.remove(targetUid);
8249                    N--;
8250                    i--;
8251                }
8252            }
8253        }
8254
8255        if (persistChanged) {
8256            schedulePersistUriGrants();
8257        }
8258    }
8259
8260    @Override
8261    public IBinder newUriPermissionOwner(String name) {
8262        enforceNotIsolatedCaller("newUriPermissionOwner");
8263        synchronized(this) {
8264            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8265            return owner.getExternalTokenLocked();
8266        }
8267    }
8268
8269    @Override
8270    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8271        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8272        synchronized(this) {
8273            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8274            if (r == null) {
8275                throw new IllegalArgumentException("Activity does not exist; token="
8276                        + activityToken);
8277            }
8278            return r.getUriPermissionsLocked().getExternalTokenLocked();
8279        }
8280    }
8281    /**
8282     * @param uri This uri must NOT contain an embedded userId.
8283     * @param sourceUserId The userId in which the uri is to be resolved.
8284     * @param targetUserId The userId of the app that receives the grant.
8285     */
8286    @Override
8287    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8288            final int modeFlags, int sourceUserId, int targetUserId) {
8289        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8290                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8291                "grantUriPermissionFromOwner", null);
8292        synchronized(this) {
8293            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8294            if (owner == null) {
8295                throw new IllegalArgumentException("Unknown owner: " + token);
8296            }
8297            if (fromUid != Binder.getCallingUid()) {
8298                if (Binder.getCallingUid() != Process.myUid()) {
8299                    // Only system code can grant URI permissions on behalf
8300                    // of other users.
8301                    throw new SecurityException("nice try");
8302                }
8303            }
8304            if (targetPkg == null) {
8305                throw new IllegalArgumentException("null target");
8306            }
8307            if (uri == null) {
8308                throw new IllegalArgumentException("null uri");
8309            }
8310
8311            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8312                    modeFlags, owner, targetUserId);
8313        }
8314    }
8315
8316    /**
8317     * @param uri This uri must NOT contain an embedded userId.
8318     * @param userId The userId in which the uri is to be resolved.
8319     */
8320    @Override
8321    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8322        synchronized(this) {
8323            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8324            if (owner == null) {
8325                throw new IllegalArgumentException("Unknown owner: " + token);
8326            }
8327
8328            if (uri == null) {
8329                owner.removeUriPermissionsLocked(mode);
8330            } else {
8331                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8332            }
8333        }
8334    }
8335
8336    private void schedulePersistUriGrants() {
8337        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8338            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8339                    10 * DateUtils.SECOND_IN_MILLIS);
8340        }
8341    }
8342
8343    private void writeGrantedUriPermissions() {
8344        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8345
8346        // Snapshot permissions so we can persist without lock
8347        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8348        synchronized (this) {
8349            final int size = mGrantedUriPermissions.size();
8350            for (int i = 0; i < size; i++) {
8351                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8352                for (UriPermission perm : perms.values()) {
8353                    if (perm.persistedModeFlags != 0) {
8354                        persist.add(perm.snapshot());
8355                    }
8356                }
8357            }
8358        }
8359
8360        FileOutputStream fos = null;
8361        try {
8362            fos = mGrantFile.startWrite();
8363
8364            XmlSerializer out = new FastXmlSerializer();
8365            out.setOutput(fos, StandardCharsets.UTF_8.name());
8366            out.startDocument(null, true);
8367            out.startTag(null, TAG_URI_GRANTS);
8368            for (UriPermission.Snapshot perm : persist) {
8369                out.startTag(null, TAG_URI_GRANT);
8370                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8371                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8372                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8373                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8374                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8375                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8376                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8377                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8378                out.endTag(null, TAG_URI_GRANT);
8379            }
8380            out.endTag(null, TAG_URI_GRANTS);
8381            out.endDocument();
8382
8383            mGrantFile.finishWrite(fos);
8384        } catch (IOException e) {
8385            if (fos != null) {
8386                mGrantFile.failWrite(fos);
8387            }
8388        }
8389    }
8390
8391    private void readGrantedUriPermissionsLocked() {
8392        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8393
8394        final long now = System.currentTimeMillis();
8395
8396        FileInputStream fis = null;
8397        try {
8398            fis = mGrantFile.openRead();
8399            final XmlPullParser in = Xml.newPullParser();
8400            in.setInput(fis, StandardCharsets.UTF_8.name());
8401
8402            int type;
8403            while ((type = in.next()) != END_DOCUMENT) {
8404                final String tag = in.getName();
8405                if (type == START_TAG) {
8406                    if (TAG_URI_GRANT.equals(tag)) {
8407                        final int sourceUserId;
8408                        final int targetUserId;
8409                        final int userHandle = readIntAttribute(in,
8410                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8411                        if (userHandle != UserHandle.USER_NULL) {
8412                            // For backwards compatibility.
8413                            sourceUserId = userHandle;
8414                            targetUserId = userHandle;
8415                        } else {
8416                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8417                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8418                        }
8419                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8420                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8421                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8422                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8423                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8424                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8425
8426                        // Sanity check that provider still belongs to source package
8427                        final ProviderInfo pi = getProviderInfoLocked(
8428                                uri.getAuthority(), sourceUserId);
8429                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8430                            int targetUid = -1;
8431                            try {
8432                                targetUid = AppGlobals.getPackageManager()
8433                                        .getPackageUid(targetPkg, targetUserId);
8434                            } catch (RemoteException e) {
8435                            }
8436                            if (targetUid != -1) {
8437                                final UriPermission perm = findOrCreateUriPermissionLocked(
8438                                        sourcePkg, targetPkg, targetUid,
8439                                        new GrantUri(sourceUserId, uri, prefix));
8440                                perm.initPersistedModes(modeFlags, createdTime);
8441                            }
8442                        } else {
8443                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8444                                    + " but instead found " + pi);
8445                        }
8446                    }
8447                }
8448            }
8449        } catch (FileNotFoundException e) {
8450            // Missing grants is okay
8451        } catch (IOException e) {
8452            Slog.wtf(TAG, "Failed reading Uri grants", e);
8453        } catch (XmlPullParserException e) {
8454            Slog.wtf(TAG, "Failed reading Uri grants", e);
8455        } finally {
8456            IoUtils.closeQuietly(fis);
8457        }
8458    }
8459
8460    /**
8461     * @param uri This uri must NOT contain an embedded userId.
8462     * @param userId The userId in which the uri is to be resolved.
8463     */
8464    @Override
8465    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8466        enforceNotIsolatedCaller("takePersistableUriPermission");
8467
8468        Preconditions.checkFlagsArgument(modeFlags,
8469                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8470
8471        synchronized (this) {
8472            final int callingUid = Binder.getCallingUid();
8473            boolean persistChanged = false;
8474            GrantUri grantUri = new GrantUri(userId, uri, false);
8475
8476            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8477                    new GrantUri(userId, uri, false));
8478            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8479                    new GrantUri(userId, uri, true));
8480
8481            final boolean exactValid = (exactPerm != null)
8482                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8483            final boolean prefixValid = (prefixPerm != null)
8484                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8485
8486            if (!(exactValid || prefixValid)) {
8487                throw new SecurityException("No persistable permission grants found for UID "
8488                        + callingUid + " and Uri " + grantUri.toSafeString());
8489            }
8490
8491            if (exactValid) {
8492                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8493            }
8494            if (prefixValid) {
8495                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8496            }
8497
8498            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8499
8500            if (persistChanged) {
8501                schedulePersistUriGrants();
8502            }
8503        }
8504    }
8505
8506    /**
8507     * @param uri This uri must NOT contain an embedded userId.
8508     * @param userId The userId in which the uri is to be resolved.
8509     */
8510    @Override
8511    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8512        enforceNotIsolatedCaller("releasePersistableUriPermission");
8513
8514        Preconditions.checkFlagsArgument(modeFlags,
8515                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8516
8517        synchronized (this) {
8518            final int callingUid = Binder.getCallingUid();
8519            boolean persistChanged = false;
8520
8521            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8522                    new GrantUri(userId, uri, false));
8523            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8524                    new GrantUri(userId, uri, true));
8525            if (exactPerm == null && prefixPerm == null) {
8526                throw new SecurityException("No permission grants found for UID " + callingUid
8527                        + " and Uri " + uri.toSafeString());
8528            }
8529
8530            if (exactPerm != null) {
8531                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8532                removeUriPermissionIfNeededLocked(exactPerm);
8533            }
8534            if (prefixPerm != null) {
8535                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8536                removeUriPermissionIfNeededLocked(prefixPerm);
8537            }
8538
8539            if (persistChanged) {
8540                schedulePersistUriGrants();
8541            }
8542        }
8543    }
8544
8545    /**
8546     * Prune any older {@link UriPermission} for the given UID until outstanding
8547     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8548     *
8549     * @return if any mutations occured that require persisting.
8550     */
8551    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8552        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8553        if (perms == null) return false;
8554        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8555
8556        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8557        for (UriPermission perm : perms.values()) {
8558            if (perm.persistedModeFlags != 0) {
8559                persisted.add(perm);
8560            }
8561        }
8562
8563        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8564        if (trimCount <= 0) return false;
8565
8566        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8567        for (int i = 0; i < trimCount; i++) {
8568            final UriPermission perm = persisted.get(i);
8569
8570            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8571                    "Trimming grant created at " + perm.persistedCreateTime);
8572
8573            perm.releasePersistableModes(~0);
8574            removeUriPermissionIfNeededLocked(perm);
8575        }
8576
8577        return true;
8578    }
8579
8580    @Override
8581    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8582            String packageName, boolean incoming) {
8583        enforceNotIsolatedCaller("getPersistedUriPermissions");
8584        Preconditions.checkNotNull(packageName, "packageName");
8585
8586        final int callingUid = Binder.getCallingUid();
8587        final IPackageManager pm = AppGlobals.getPackageManager();
8588        try {
8589            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8590            if (packageUid != callingUid) {
8591                throw new SecurityException(
8592                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8593            }
8594        } catch (RemoteException e) {
8595            throw new SecurityException("Failed to verify package name ownership");
8596        }
8597
8598        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8599        synchronized (this) {
8600            if (incoming) {
8601                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8602                        callingUid);
8603                if (perms == null) {
8604                    Slog.w(TAG, "No permission grants found for " + packageName);
8605                } else {
8606                    for (UriPermission perm : perms.values()) {
8607                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8608                            result.add(perm.buildPersistedPublicApiObject());
8609                        }
8610                    }
8611                }
8612            } else {
8613                final int size = mGrantedUriPermissions.size();
8614                for (int i = 0; i < size; i++) {
8615                    final ArrayMap<GrantUri, UriPermission> perms =
8616                            mGrantedUriPermissions.valueAt(i);
8617                    for (UriPermission perm : perms.values()) {
8618                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8619                            result.add(perm.buildPersistedPublicApiObject());
8620                        }
8621                    }
8622                }
8623            }
8624        }
8625        return new ParceledListSlice<android.content.UriPermission>(result);
8626    }
8627
8628    @Override
8629    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8630        synchronized (this) {
8631            ProcessRecord app =
8632                who != null ? getRecordForAppLocked(who) : null;
8633            if (app == null) return;
8634
8635            Message msg = Message.obtain();
8636            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8637            msg.obj = app;
8638            msg.arg1 = waiting ? 1 : 0;
8639            mUiHandler.sendMessage(msg);
8640        }
8641    }
8642
8643    @Override
8644    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8645        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8646        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8647        outInfo.availMem = Process.getFreeMemory();
8648        outInfo.totalMem = Process.getTotalMemory();
8649        outInfo.threshold = homeAppMem;
8650        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8651        outInfo.hiddenAppThreshold = cachedAppMem;
8652        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8653                ProcessList.SERVICE_ADJ);
8654        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8655                ProcessList.VISIBLE_APP_ADJ);
8656        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8657                ProcessList.FOREGROUND_APP_ADJ);
8658    }
8659
8660    // =========================================================
8661    // TASK MANAGEMENT
8662    // =========================================================
8663
8664    @Override
8665    public List<IAppTask> getAppTasks(String callingPackage) {
8666        int callingUid = Binder.getCallingUid();
8667        long ident = Binder.clearCallingIdentity();
8668
8669        synchronized(this) {
8670            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8671            try {
8672                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8673
8674                final int N = mRecentTasks.size();
8675                for (int i = 0; i < N; i++) {
8676                    TaskRecord tr = mRecentTasks.get(i);
8677                    // Skip tasks that do not match the caller.  We don't need to verify
8678                    // callingPackage, because we are also limiting to callingUid and know
8679                    // that will limit to the correct security sandbox.
8680                    if (tr.effectiveUid != callingUid) {
8681                        continue;
8682                    }
8683                    Intent intent = tr.getBaseIntent();
8684                    if (intent == null ||
8685                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8686                        continue;
8687                    }
8688                    ActivityManager.RecentTaskInfo taskInfo =
8689                            createRecentTaskInfoFromTaskRecord(tr);
8690                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8691                    list.add(taskImpl);
8692                }
8693            } finally {
8694                Binder.restoreCallingIdentity(ident);
8695            }
8696            return list;
8697        }
8698    }
8699
8700    @Override
8701    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8702        final int callingUid = Binder.getCallingUid();
8703        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8704
8705        synchronized(this) {
8706            if (DEBUG_ALL) Slog.v(
8707                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8708
8709            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8710                    callingUid);
8711
8712            // TODO: Improve with MRU list from all ActivityStacks.
8713            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8714        }
8715
8716        return list;
8717    }
8718
8719    /**
8720     * Creates a new RecentTaskInfo from a TaskRecord.
8721     */
8722    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8723        // Update the task description to reflect any changes in the task stack
8724        tr.updateTaskDescription();
8725
8726        // Compose the recent task info
8727        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8728        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8729        rti.persistentId = tr.taskId;
8730        rti.baseIntent = new Intent(tr.getBaseIntent());
8731        rti.origActivity = tr.origActivity;
8732        rti.realActivity = tr.realActivity;
8733        rti.description = tr.lastDescription;
8734        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8735        rti.userId = tr.userId;
8736        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8737        rti.firstActiveTime = tr.firstActiveTime;
8738        rti.lastActiveTime = tr.lastActiveTime;
8739        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8740        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8741        rti.numActivities = 0;
8742        if (tr.mBounds != null) {
8743            rti.bounds = new Rect(tr.mBounds);
8744        }
8745
8746        ActivityRecord base = null;
8747        ActivityRecord top = null;
8748        ActivityRecord tmp;
8749
8750        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8751            tmp = tr.mActivities.get(i);
8752            if (tmp.finishing) {
8753                continue;
8754            }
8755            base = tmp;
8756            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8757                top = base;
8758            }
8759            rti.numActivities++;
8760        }
8761
8762        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8763        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8764
8765        return rti;
8766    }
8767
8768    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8769        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8770                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8771        if (!allowed) {
8772            if (checkPermission(android.Manifest.permission.GET_TASKS,
8773                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8774                // Temporary compatibility: some existing apps on the system image may
8775                // still be requesting the old permission and not switched to the new
8776                // one; if so, we'll still allow them full access.  This means we need
8777                // to see if they are holding the old permission and are a system app.
8778                try {
8779                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8780                        allowed = true;
8781                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8782                                + " is using old GET_TASKS but privileged; allowing");
8783                    }
8784                } catch (RemoteException e) {
8785                }
8786            }
8787        }
8788        if (!allowed) {
8789            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8790                    + " does not hold REAL_GET_TASKS; limiting output");
8791        }
8792        return allowed;
8793    }
8794
8795    @Override
8796    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8797        final int callingUid = Binder.getCallingUid();
8798        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8799                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8800
8801        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8802        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8803        synchronized (this) {
8804            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8805                    callingUid);
8806            final boolean detailed = checkCallingPermission(
8807                    android.Manifest.permission.GET_DETAILED_TASKS)
8808                    == PackageManager.PERMISSION_GRANTED;
8809
8810            final int recentsCount = mRecentTasks.size();
8811            ArrayList<ActivityManager.RecentTaskInfo> res =
8812                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8813
8814            final Set<Integer> includedUsers;
8815            if (includeProfiles) {
8816                includedUsers = mUserController.getProfileIds(userId);
8817            } else {
8818                includedUsers = new HashSet<>();
8819            }
8820            includedUsers.add(Integer.valueOf(userId));
8821
8822            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8823                TaskRecord tr = mRecentTasks.get(i);
8824                // Only add calling user or related users recent tasks
8825                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8826                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8827                    continue;
8828                }
8829
8830                // Return the entry if desired by the caller.  We always return
8831                // the first entry, because callers always expect this to be the
8832                // foreground app.  We may filter others if the caller has
8833                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8834                // we should exclude the entry.
8835
8836                if (i == 0
8837                        || withExcluded
8838                        || (tr.intent == null)
8839                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8840                                == 0)) {
8841                    if (!allowed) {
8842                        // If the caller doesn't have the GET_TASKS permission, then only
8843                        // allow them to see a small subset of tasks -- their own and home.
8844                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8845                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8846                            continue;
8847                        }
8848                    }
8849                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8850                        if (tr.stack != null && tr.stack.isHomeStack()) {
8851                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8852                                    "Skipping, home stack task: " + tr);
8853                            continue;
8854                        }
8855                    }
8856                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8857                        if (tr.stack != null && tr.stack.isDockedStack()) {
8858                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8859                                    "Skipping, docked stack task: " + tr);
8860                            continue;
8861                        }
8862                    }
8863                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8864                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8865                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8866                                    "Skipping, pinned stack task: " + tr);
8867                            continue;
8868                        }
8869                    }
8870                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8871                        // Don't include auto remove tasks that are finished or finishing.
8872                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8873                                "Skipping, auto-remove without activity: " + tr);
8874                        continue;
8875                    }
8876                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8877                            && !tr.isAvailable) {
8878                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8879                                "Skipping, unavail real act: " + tr);
8880                        continue;
8881                    }
8882
8883                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8884                    if (!detailed) {
8885                        rti.baseIntent.replaceExtras((Bundle)null);
8886                    }
8887
8888                    res.add(rti);
8889                    maxNum--;
8890                }
8891            }
8892            return res;
8893        }
8894    }
8895
8896    @Override
8897    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8898        synchronized (this) {
8899            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8900                    "getTaskThumbnail()");
8901            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8902                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8903            if (tr != null) {
8904                return tr.getTaskThumbnailLocked();
8905            }
8906        }
8907        return null;
8908    }
8909
8910    @Override
8911    public int addAppTask(IBinder activityToken, Intent intent,
8912            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8913        final int callingUid = Binder.getCallingUid();
8914        final long callingIdent = Binder.clearCallingIdentity();
8915
8916        try {
8917            synchronized (this) {
8918                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8919                if (r == null) {
8920                    throw new IllegalArgumentException("Activity does not exist; token="
8921                            + activityToken);
8922                }
8923                ComponentName comp = intent.getComponent();
8924                if (comp == null) {
8925                    throw new IllegalArgumentException("Intent " + intent
8926                            + " must specify explicit component");
8927                }
8928                if (thumbnail.getWidth() != mThumbnailWidth
8929                        || thumbnail.getHeight() != mThumbnailHeight) {
8930                    throw new IllegalArgumentException("Bad thumbnail size: got "
8931                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8932                            + mThumbnailWidth + "x" + mThumbnailHeight);
8933                }
8934                if (intent.getSelector() != null) {
8935                    intent.setSelector(null);
8936                }
8937                if (intent.getSourceBounds() != null) {
8938                    intent.setSourceBounds(null);
8939                }
8940                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8941                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8942                        // The caller has added this as an auto-remove task...  that makes no
8943                        // sense, so turn off auto-remove.
8944                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8945                    }
8946                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8947                    // Must be a new task.
8948                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8949                }
8950                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8951                    mLastAddedTaskActivity = null;
8952                }
8953                ActivityInfo ainfo = mLastAddedTaskActivity;
8954                if (ainfo == null) {
8955                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8956                            comp, 0, UserHandle.getUserId(callingUid));
8957                    if (ainfo.applicationInfo.uid != callingUid) {
8958                        throw new SecurityException(
8959                                "Can't add task for another application: target uid="
8960                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8961                    }
8962                }
8963
8964                // Use the full screen as the context for the task thumbnail
8965                final Point displaySize = new Point();
8966                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8967                r.task.stack.getDisplaySize(displaySize);
8968                thumbnailInfo.taskWidth = displaySize.x;
8969                thumbnailInfo.taskHeight = displaySize.y;
8970                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8971
8972                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8973                        intent, description, thumbnailInfo);
8974
8975                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8976                if (trimIdx >= 0) {
8977                    // If this would have caused a trim, then we'll abort because that
8978                    // means it would be added at the end of the list but then just removed.
8979                    return INVALID_TASK_ID;
8980                }
8981
8982                final int N = mRecentTasks.size();
8983                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8984                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8985                    tr.removedFromRecents();
8986                }
8987
8988                task.inRecents = true;
8989                mRecentTasks.add(task);
8990                r.task.stack.addTask(task, false, "addAppTask");
8991
8992                task.setLastThumbnailLocked(thumbnail);
8993                task.freeLastThumbnail();
8994
8995                return task.taskId;
8996            }
8997        } finally {
8998            Binder.restoreCallingIdentity(callingIdent);
8999        }
9000    }
9001
9002    @Override
9003    public Point getAppTaskThumbnailSize() {
9004        synchronized (this) {
9005            return new Point(mThumbnailWidth,  mThumbnailHeight);
9006        }
9007    }
9008
9009    @Override
9010    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9011        synchronized (this) {
9012            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9013            if (r != null) {
9014                r.setTaskDescription(td);
9015                r.task.updateTaskDescription();
9016            }
9017        }
9018    }
9019
9020    @Override
9021    public void setTaskResizeable(int taskId, boolean resizeable) {
9022        synchronized (this) {
9023            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9024                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9025            if (task == null) {
9026                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9027                return;
9028            }
9029            if (task.mResizeable != resizeable) {
9030                task.mResizeable = resizeable;
9031                mWindowManager.setTaskResizeable(taskId, resizeable);
9032                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9033                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9034            }
9035        }
9036    }
9037
9038    @Override
9039    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9040        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9041        long ident = Binder.clearCallingIdentity();
9042        try {
9043            synchronized (this) {
9044                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9045                if (task == null) {
9046                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9047                    return;
9048                }
9049                int stackId = task.stack.mStackId;
9050                // First, check if this is a non-resizeble task in docked stack or if the task size
9051                // is affected by the docked stack changing size. If so, instead of resizing, we
9052                // can only scroll the task. No need to update configuration.
9053                if (bounds != null && !task.mResizeable
9054                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9055                    mWindowManager.scrollTask(task.taskId, bounds);
9056                    return;
9057                }
9058
9059                // Place the task in the right stack if it isn't there already based on
9060                // the requested bounds.
9061                // The stack transition logic is:
9062                // - a null bounds on a freeform task moves that task to fullscreen
9063                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9064                //   that task to freeform
9065                // - otherwise the task is not moved
9066                if (!StackId.isTaskResizeAllowed(stackId)) {
9067                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9068                }
9069                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9070                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9071                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9072                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9073                }
9074                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9075                if (stackId != task.stack.mStackId) {
9076                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9077                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9078                    preserveWindow = false;
9079                }
9080
9081                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9082            }
9083        } finally {
9084            Binder.restoreCallingIdentity(ident);
9085        }
9086    }
9087
9088    @Override
9089    public Rect getTaskBounds(int taskId) {
9090        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9091        long ident = Binder.clearCallingIdentity();
9092        Rect rect = new Rect();
9093        try {
9094            synchronized (this) {
9095                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9096                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9097                if (task == null) {
9098                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9099                    return rect;
9100                }
9101                if (task.stack != null) {
9102                    // Return the bounds from window manager since it will be adjusted for various
9103                    // things like the presense of a docked stack for tasks that aren't resizeable.
9104                    mWindowManager.getTaskBounds(task.taskId, rect);
9105                } else {
9106                    // Task isn't in window manager yet since it isn't associated with a stack.
9107                    // Return the persist value from activity manager
9108                    if (task.mBounds != null) {
9109                        rect.set(task.mBounds);
9110                    } else if (task.mLastNonFullscreenBounds != null) {
9111                        rect.set(task.mLastNonFullscreenBounds);
9112                    }
9113                }
9114            }
9115        } finally {
9116            Binder.restoreCallingIdentity(ident);
9117        }
9118        return rect;
9119    }
9120
9121    @Override
9122    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9123        if (userId != UserHandle.getCallingUserId()) {
9124            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9125                    "getTaskDescriptionIcon");
9126        }
9127        final File passedIconFile = new File(filePath);
9128        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9129                passedIconFile.getName());
9130        if (!legitIconFile.getPath().equals(filePath)
9131                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9132            throw new IllegalArgumentException("Bad file path: " + filePath);
9133        }
9134        return mTaskPersister.getTaskDescriptionIcon(filePath);
9135    }
9136
9137    @Override
9138    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9139            throws RemoteException {
9140        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9141                opts.getCustomInPlaceResId() == 0) {
9142            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9143                    "with valid animation");
9144        }
9145        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9146        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9147                opts.getCustomInPlaceResId());
9148        mWindowManager.executeAppTransition();
9149    }
9150
9151    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9152            boolean removeFromRecents) {
9153        if (removeFromRecents) {
9154            mRecentTasks.remove(tr);
9155            tr.removedFromRecents();
9156        }
9157        ComponentName component = tr.getBaseIntent().getComponent();
9158        if (component == null) {
9159            Slog.w(TAG, "No component for base intent of task: " + tr);
9160            return;
9161        }
9162
9163        // Find any running services associated with this app and stop if needed.
9164        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9165
9166        if (!killProcess) {
9167            return;
9168        }
9169
9170        // Determine if the process(es) for this task should be killed.
9171        final String pkg = component.getPackageName();
9172        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9173        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9174        for (int i = 0; i < pmap.size(); i++) {
9175
9176            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9177            for (int j = 0; j < uids.size(); j++) {
9178                ProcessRecord proc = uids.valueAt(j);
9179                if (proc.userId != tr.userId) {
9180                    // Don't kill process for a different user.
9181                    continue;
9182                }
9183                if (proc == mHomeProcess) {
9184                    // Don't kill the home process along with tasks from the same package.
9185                    continue;
9186                }
9187                if (!proc.pkgList.containsKey(pkg)) {
9188                    // Don't kill process that is not associated with this task.
9189                    continue;
9190                }
9191
9192                for (int k = 0; k < proc.activities.size(); k++) {
9193                    TaskRecord otherTask = proc.activities.get(k).task;
9194                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9195                        // Don't kill process(es) that has an activity in a different task that is
9196                        // also in recents.
9197                        return;
9198                    }
9199                }
9200
9201                if (proc.foregroundServices) {
9202                    // Don't kill process(es) with foreground service.
9203                    return;
9204                }
9205
9206                // Add process to kill list.
9207                procsToKill.add(proc);
9208            }
9209        }
9210
9211        // Kill the running processes.
9212        for (int i = 0; i < procsToKill.size(); i++) {
9213            ProcessRecord pr = procsToKill.get(i);
9214            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9215                    && pr.curReceiver == null) {
9216                pr.kill("remove task", true);
9217            } else {
9218                // We delay killing processes that are not in the background or running a receiver.
9219                pr.waitingToKill = "remove task";
9220            }
9221        }
9222    }
9223
9224    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9225        // Remove all tasks with activities in the specified package from the list of recent tasks
9226        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9227            TaskRecord tr = mRecentTasks.get(i);
9228            if (tr.userId != userId) continue;
9229
9230            ComponentName cn = tr.intent.getComponent();
9231            if (cn != null && cn.getPackageName().equals(packageName)) {
9232                // If the package name matches, remove the task.
9233                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9234            }
9235        }
9236    }
9237
9238    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9239            int userId) {
9240
9241        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9242            TaskRecord tr = mRecentTasks.get(i);
9243            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9244                continue;
9245            }
9246
9247            ComponentName cn = tr.intent.getComponent();
9248            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9249                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9250            if (sameComponent) {
9251                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9252            }
9253        }
9254    }
9255
9256    /**
9257     * Removes the task with the specified task id.
9258     *
9259     * @param taskId Identifier of the task to be removed.
9260     * @param killProcess Kill any process associated with the task if possible.
9261     * @param removeFromRecents Whether to also remove the task from recents.
9262     * @return Returns true if the given task was found and removed.
9263     */
9264    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9265            boolean removeFromRecents) {
9266        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9267                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9268        if (tr != null) {
9269            tr.removeTaskActivitiesLocked();
9270            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9271            if (tr.isPersistable) {
9272                notifyTaskPersisterLocked(null, true);
9273            }
9274            return true;
9275        }
9276        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9277        return false;
9278    }
9279
9280    @Override
9281    public boolean removeTask(int taskId) {
9282        synchronized (this) {
9283            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9284                    "removeTask()");
9285            long ident = Binder.clearCallingIdentity();
9286            try {
9287                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9288            } finally {
9289                Binder.restoreCallingIdentity(ident);
9290            }
9291        }
9292    }
9293
9294    /**
9295     * TODO: Add mController hook
9296     */
9297    @Override
9298    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9299        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9300
9301        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9302        synchronized(this) {
9303            moveTaskToFrontLocked(taskId, flags, bOptions);
9304        }
9305    }
9306
9307    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9308        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9309
9310        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9311                Binder.getCallingUid(), -1, -1, "Task to front")) {
9312            ActivityOptions.abort(options);
9313            return;
9314        }
9315        final long origId = Binder.clearCallingIdentity();
9316        try {
9317            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9318            if (task == null) {
9319                Slog.d(TAG, "Could not find task for id: "+ taskId);
9320                return;
9321            }
9322            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9323                mStackSupervisor.showLockTaskToast();
9324                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9325                return;
9326            }
9327            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9328            if (prev != null && prev.isRecentsActivity()) {
9329                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9330            }
9331            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9332        } finally {
9333            Binder.restoreCallingIdentity(origId);
9334        }
9335        ActivityOptions.abort(options);
9336    }
9337
9338    /**
9339     * Moves an activity, and all of the other activities within the same task, to the bottom
9340     * of the history stack.  The activity's order within the task is unchanged.
9341     *
9342     * @param token A reference to the activity we wish to move
9343     * @param nonRoot If false then this only works if the activity is the root
9344     *                of a task; if true it will work for any activity in a task.
9345     * @return Returns true if the move completed, false if not.
9346     */
9347    @Override
9348    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9349        enforceNotIsolatedCaller("moveActivityTaskToBack");
9350        synchronized(this) {
9351            final long origId = Binder.clearCallingIdentity();
9352            try {
9353                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9354                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9355                if (task != null) {
9356                    if (mStackSupervisor.isLockedTask(task)) {
9357                        mStackSupervisor.showLockTaskToast();
9358                        return false;
9359                    }
9360                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9361                }
9362            } finally {
9363                Binder.restoreCallingIdentity(origId);
9364            }
9365        }
9366        return false;
9367    }
9368
9369    @Override
9370    public void moveTaskBackwards(int task) {
9371        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9372                "moveTaskBackwards()");
9373
9374        synchronized(this) {
9375            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9376                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9377                return;
9378            }
9379            final long origId = Binder.clearCallingIdentity();
9380            moveTaskBackwardsLocked(task);
9381            Binder.restoreCallingIdentity(origId);
9382        }
9383    }
9384
9385    private final void moveTaskBackwardsLocked(int task) {
9386        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9387    }
9388
9389    @Override
9390    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9391            IActivityContainerCallback callback) throws RemoteException {
9392        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9393        synchronized (this) {
9394            if (parentActivityToken == null) {
9395                throw new IllegalArgumentException("parent token must not be null");
9396            }
9397            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9398            if (r == null) {
9399                return null;
9400            }
9401            if (callback == null) {
9402                throw new IllegalArgumentException("callback must not be null");
9403            }
9404            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9405        }
9406    }
9407
9408    @Override
9409    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9410        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9411        synchronized (this) {
9412            mStackSupervisor.deleteActivityContainer(container);
9413        }
9414    }
9415
9416    @Override
9417    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9418        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9419        synchronized (this) {
9420            final int stackId = mStackSupervisor.getNextStackId();
9421            final ActivityStack stack =
9422                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9423            if (stack == null) {
9424                return null;
9425            }
9426            return stack.mActivityContainer;
9427        }
9428    }
9429
9430    @Override
9431    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9432        synchronized (this) {
9433            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9434            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9435                return stack.mActivityContainer.getDisplayId();
9436            }
9437            return Display.DEFAULT_DISPLAY;
9438        }
9439    }
9440
9441    @Override
9442    public int getActivityStackId(IBinder token) throws RemoteException {
9443        synchronized (this) {
9444            ActivityStack stack = ActivityRecord.getStackLocked(token);
9445            if (stack == null) {
9446                return INVALID_STACK_ID;
9447            }
9448            return stack.mStackId;
9449        }
9450    }
9451
9452    @Override
9453    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9454        if (stackId == HOME_STACK_ID) {
9455            throw new IllegalArgumentException(
9456                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9457        }
9458        synchronized (this) {
9459            long ident = Binder.clearCallingIdentity();
9460            try {
9461                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9462                if (r == null) {
9463                    throw new IllegalArgumentException(
9464                            "moveActivityToStack: No activity record matching token=" + token);
9465                }
9466                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9467                        + " to stackId=" + stackId);
9468                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9469                        "moveActivityToStack", ANIMATE);
9470            } finally {
9471                Binder.restoreCallingIdentity(ident);
9472            }
9473        }
9474    }
9475
9476    @Override
9477    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9478        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9479        if (stackId == HOME_STACK_ID) {
9480            throw new IllegalArgumentException(
9481                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9482        }
9483        synchronized (this) {
9484            long ident = Binder.clearCallingIdentity();
9485            try {
9486                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9487                        + " to stackId=" + stackId + " toTop=" + toTop);
9488                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9489                        "moveTaskToStack", ANIMATE);
9490            } finally {
9491                Binder.restoreCallingIdentity(ident);
9492            }
9493        }
9494    }
9495
9496    /**
9497     * Moves the input task to the docked stack.
9498     *
9499     * @param taskId Id of task to move.
9500     * @param createMode The mode the docked stack should be created in if it doesn't exist
9501     *                   already. See
9502     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9503     *                   and
9504     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9505     * @param toTop If the task and stack should be moved to the top.
9506     * @param animate Whether we should play an animation for the moving the task
9507     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9508     *                      docked stack. Pass {@code null} to use default bounds.
9509     */
9510    @Override
9511    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9512            Rect initialBounds) {
9513        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9514        synchronized (this) {
9515            long ident = Binder.clearCallingIdentity();
9516            try {
9517                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9518                        + " to createMode=" + createMode + " toTop=" + toTop);
9519                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9520                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9521                        "moveTaskToDockedStack", animate);
9522            } finally {
9523                Binder.restoreCallingIdentity(ident);
9524            }
9525        }
9526    }
9527
9528    /**
9529     * Moves the top activity in the input stackId to the pinned stack.
9530     *
9531     * @param stackId Id of stack to move the top activity to pinned stack.
9532     * @param bounds Bounds to use for pinned stack.
9533     *
9534     * @return True if the top activity of the input stack was successfully moved to the pinned
9535     *          stack.
9536     */
9537    @Override
9538    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9539        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9540        synchronized (this) {
9541            if (!mSupportsPictureInPicture) {
9542                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9543                        + "Device doesn't support picture-in-pciture mode");
9544            }
9545
9546            long ident = Binder.clearCallingIdentity();
9547            try {
9548                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9549            } finally {
9550                Binder.restoreCallingIdentity(ident);
9551            }
9552        }
9553    }
9554
9555    @Override
9556    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9557        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9558        long ident = Binder.clearCallingIdentity();
9559        try {
9560            synchronized (this) {
9561                mStackSupervisor.resizeStackLocked(
9562                        stackId, bounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
9563                        !PRESERVE_WINDOWS, allowResizeInDockedMode);
9564            }
9565        } finally {
9566            Binder.restoreCallingIdentity(ident);
9567        }
9568    }
9569
9570    @Override
9571    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9572            Rect tempDockedTaskInsetBounds,
9573            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9574        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9575                "resizeDockedStack()");
9576        long ident = Binder.clearCallingIdentity();
9577        try {
9578            synchronized (this) {
9579                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9580                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9581                        PRESERVE_WINDOWS);
9582            }
9583        } finally {
9584            Binder.restoreCallingIdentity(ident);
9585        }
9586    }
9587
9588    @Override
9589    public void positionTaskInStack(int taskId, int stackId, int position) {
9590        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9591        if (stackId == HOME_STACK_ID) {
9592            throw new IllegalArgumentException(
9593                    "positionTaskInStack: Attempt to change the position of task "
9594                    + taskId + " in/to home stack");
9595        }
9596        synchronized (this) {
9597            long ident = Binder.clearCallingIdentity();
9598            try {
9599                if (DEBUG_STACK) Slog.d(TAG_STACK,
9600                        "positionTaskInStack: positioning task=" + taskId
9601                        + " in stackId=" + stackId + " at position=" + position);
9602                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9603            } finally {
9604                Binder.restoreCallingIdentity(ident);
9605            }
9606        }
9607    }
9608
9609    @Override
9610    public List<StackInfo> getAllStackInfos() {
9611        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9612        long ident = Binder.clearCallingIdentity();
9613        try {
9614            synchronized (this) {
9615                return mStackSupervisor.getAllStackInfosLocked();
9616            }
9617        } finally {
9618            Binder.restoreCallingIdentity(ident);
9619        }
9620    }
9621
9622    @Override
9623    public StackInfo getStackInfo(int stackId) {
9624        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9625        long ident = Binder.clearCallingIdentity();
9626        try {
9627            synchronized (this) {
9628                return mStackSupervisor.getStackInfoLocked(stackId);
9629            }
9630        } finally {
9631            Binder.restoreCallingIdentity(ident);
9632        }
9633    }
9634
9635    @Override
9636    public boolean isInHomeStack(int taskId) {
9637        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9638        long ident = Binder.clearCallingIdentity();
9639        try {
9640            synchronized (this) {
9641                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9642                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9643                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9644            }
9645        } finally {
9646            Binder.restoreCallingIdentity(ident);
9647        }
9648    }
9649
9650    @Override
9651    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9652        synchronized(this) {
9653            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9654        }
9655    }
9656
9657    @Override
9658    public void updateDeviceOwner(String packageName) {
9659        final int callingUid = Binder.getCallingUid();
9660        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9661            throw new SecurityException("updateDeviceOwner called from non-system process");
9662        }
9663        synchronized (this) {
9664            mDeviceOwnerName = packageName;
9665        }
9666    }
9667
9668    @Override
9669    public void updateLockTaskPackages(int userId, String[] packages) {
9670        final int callingUid = Binder.getCallingUid();
9671        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9672            throw new SecurityException("updateLockTaskPackage called from non-system process");
9673        }
9674        synchronized (this) {
9675            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9676                    Arrays.toString(packages));
9677            mLockTaskPackages.put(userId, packages);
9678            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9679        }
9680    }
9681
9682
9683    void startLockTaskModeLocked(TaskRecord task) {
9684        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9685        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9686            return;
9687        }
9688
9689        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9690        // is initiated by system after the pinning request was shown and locked mode is initiated
9691        // by an authorized app directly
9692        final int callingUid = Binder.getCallingUid();
9693        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9694        long ident = Binder.clearCallingIdentity();
9695        try {
9696            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9697            if (!isSystemInitiated) {
9698                task.mLockTaskUid = callingUid;
9699                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9700                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9701                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9702                    StatusBarManagerInternal statusBarManager =
9703                            LocalServices.getService(StatusBarManagerInternal.class);
9704                    if (statusBarManager != null) {
9705                        statusBarManager.showScreenPinningRequest();
9706                    }
9707                    return;
9708                }
9709
9710                if (stack == null || task != stack.topTask()) {
9711                    throw new IllegalArgumentException("Invalid task, not in foreground");
9712                }
9713            }
9714            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9715                    "Locking fully");
9716            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9717                    ActivityManager.LOCK_TASK_MODE_PINNED :
9718                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9719                    "startLockTask", true);
9720        } finally {
9721            Binder.restoreCallingIdentity(ident);
9722        }
9723    }
9724
9725    @Override
9726    public void startLockTaskMode(int taskId) {
9727        synchronized (this) {
9728            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9729            if (task != null) {
9730                startLockTaskModeLocked(task);
9731            }
9732        }
9733    }
9734
9735    @Override
9736    public void startLockTaskMode(IBinder token) {
9737        synchronized (this) {
9738            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9739            if (r == null) {
9740                return;
9741            }
9742            final TaskRecord task = r.task;
9743            if (task != null) {
9744                startLockTaskModeLocked(task);
9745            }
9746        }
9747    }
9748
9749    @Override
9750    public void startLockTaskModeOnCurrent() throws RemoteException {
9751        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9752        long ident = Binder.clearCallingIdentity();
9753        try {
9754            synchronized (this) {
9755                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9756                if (r != null) {
9757                    startLockTaskModeLocked(r.task);
9758                }
9759            }
9760        } finally {
9761            Binder.restoreCallingIdentity(ident);
9762        }
9763    }
9764
9765    @Override
9766    public void stopLockTaskMode() {
9767        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9768        if (lockTask == null) {
9769            // Our work here is done.
9770            return;
9771        }
9772
9773        final int callingUid = Binder.getCallingUid();
9774        final int lockTaskUid = lockTask.mLockTaskUid;
9775        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9776        // It is possible lockTaskMode was started by the system process because
9777        // android:lockTaskMode is set to a locking value in the application manifest instead of
9778        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9779        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9780        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9781                callingUid != lockTaskUid
9782                && (lockTaskUid != 0
9783                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9784            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9785                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9786        }
9787
9788        long ident = Binder.clearCallingIdentity();
9789        try {
9790            Log.d(TAG, "stopLockTaskMode");
9791            // Stop lock task
9792            synchronized (this) {
9793                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9794                        "stopLockTask", true);
9795            }
9796        } finally {
9797            Binder.restoreCallingIdentity(ident);
9798        }
9799    }
9800
9801    @Override
9802    public void stopLockTaskModeOnCurrent() throws RemoteException {
9803        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9804        long ident = Binder.clearCallingIdentity();
9805        try {
9806            stopLockTaskMode();
9807        } finally {
9808            Binder.restoreCallingIdentity(ident);
9809        }
9810    }
9811
9812    @Override
9813    public boolean isInLockTaskMode() {
9814        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9815    }
9816
9817    @Override
9818    public int getLockTaskModeState() {
9819        synchronized (this) {
9820            return mStackSupervisor.getLockTaskModeState();
9821        }
9822    }
9823
9824    @Override
9825    public void showLockTaskEscapeMessage(IBinder token) {
9826        synchronized (this) {
9827            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9828            if (r == null) {
9829                return;
9830            }
9831            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9832        }
9833    }
9834
9835    // =========================================================
9836    // CONTENT PROVIDERS
9837    // =========================================================
9838
9839    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9840        List<ProviderInfo> providers = null;
9841        try {
9842            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9843                    .queryContentProviders(app.processName, app.uid,
9844                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9845                                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
9846            providers = slice != null ? slice.getList() : null;
9847        } catch (RemoteException ex) {
9848        }
9849        if (DEBUG_MU) Slog.v(TAG_MU,
9850                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9851        int userId = app.userId;
9852        if (providers != null) {
9853            int N = providers.size();
9854            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9855            for (int i=0; i<N; i++) {
9856                ProviderInfo cpi =
9857                    (ProviderInfo)providers.get(i);
9858                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9859                        cpi.name, cpi.flags);
9860                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9861                    // This is a singleton provider, but a user besides the
9862                    // default user is asking to initialize a process it runs
9863                    // in...  well, no, it doesn't actually run in this process,
9864                    // it runs in the process of the default user.  Get rid of it.
9865                    providers.remove(i);
9866                    N--;
9867                    i--;
9868                    continue;
9869                }
9870
9871                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9872                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9873                if (cpr == null) {
9874                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9875                    mProviderMap.putProviderByClass(comp, cpr);
9876                }
9877                if (DEBUG_MU) Slog.v(TAG_MU,
9878                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9879                app.pubProviders.put(cpi.name, cpr);
9880                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9881                    // Don't add this if it is a platform component that is marked
9882                    // to run in multiple processes, because this is actually
9883                    // part of the framework so doesn't make sense to track as a
9884                    // separate apk in the process.
9885                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9886                            mProcessStats);
9887                }
9888                notifyPackageUse(cpi.applicationInfo.packageName);
9889            }
9890        }
9891        return providers;
9892    }
9893
9894    /**
9895     * Check if {@link ProcessRecord} has a possible chance at accessing the
9896     * given {@link ProviderInfo}. Final permission checking is always done
9897     * in {@link ContentProvider}.
9898     */
9899    private final String checkContentProviderPermissionLocked(
9900            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9901        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9902        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9903        boolean checkedGrants = false;
9904        if (checkUser) {
9905            // Looking for cross-user grants before enforcing the typical cross-users permissions
9906            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9907            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9908                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9909                    return null;
9910                }
9911                checkedGrants = true;
9912            }
9913            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9914                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9915            if (userId != tmpTargetUserId) {
9916                // When we actually went to determine the final targer user ID, this ended
9917                // up different than our initial check for the authority.  This is because
9918                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9919                // SELF.  So we need to re-check the grants again.
9920                checkedGrants = false;
9921            }
9922        }
9923        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9924                cpi.applicationInfo.uid, cpi.exported)
9925                == PackageManager.PERMISSION_GRANTED) {
9926            return null;
9927        }
9928        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9929                cpi.applicationInfo.uid, cpi.exported)
9930                == PackageManager.PERMISSION_GRANTED) {
9931            return null;
9932        }
9933
9934        PathPermission[] pps = cpi.pathPermissions;
9935        if (pps != null) {
9936            int i = pps.length;
9937            while (i > 0) {
9938                i--;
9939                PathPermission pp = pps[i];
9940                String pprperm = pp.getReadPermission();
9941                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9942                        cpi.applicationInfo.uid, cpi.exported)
9943                        == PackageManager.PERMISSION_GRANTED) {
9944                    return null;
9945                }
9946                String ppwperm = pp.getWritePermission();
9947                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9948                        cpi.applicationInfo.uid, cpi.exported)
9949                        == PackageManager.PERMISSION_GRANTED) {
9950                    return null;
9951                }
9952            }
9953        }
9954        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9955            return null;
9956        }
9957
9958        String msg;
9959        if (!cpi.exported) {
9960            msg = "Permission Denial: opening provider " + cpi.name
9961                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9962                    + ", uid=" + callingUid + ") that is not exported from uid "
9963                    + cpi.applicationInfo.uid;
9964        } else {
9965            msg = "Permission Denial: opening provider " + cpi.name
9966                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9967                    + ", uid=" + callingUid + ") requires "
9968                    + cpi.readPermission + " or " + cpi.writePermission;
9969        }
9970        Slog.w(TAG, msg);
9971        return msg;
9972    }
9973
9974    /**
9975     * Returns if the ContentProvider has granted a uri to callingUid
9976     */
9977    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9978        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9979        if (perms != null) {
9980            for (int i=perms.size()-1; i>=0; i--) {
9981                GrantUri grantUri = perms.keyAt(i);
9982                if (grantUri.sourceUserId == userId || !checkUser) {
9983                    if (matchesProvider(grantUri.uri, cpi)) {
9984                        return true;
9985                    }
9986                }
9987            }
9988        }
9989        return false;
9990    }
9991
9992    /**
9993     * Returns true if the uri authority is one of the authorities specified in the provider.
9994     */
9995    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9996        String uriAuth = uri.getAuthority();
9997        String cpiAuth = cpi.authority;
9998        if (cpiAuth.indexOf(';') == -1) {
9999            return cpiAuth.equals(uriAuth);
10000        }
10001        String[] cpiAuths = cpiAuth.split(";");
10002        int length = cpiAuths.length;
10003        for (int i = 0; i < length; i++) {
10004            if (cpiAuths[i].equals(uriAuth)) return true;
10005        }
10006        return false;
10007    }
10008
10009    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10010            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10011        if (r != null) {
10012            for (int i=0; i<r.conProviders.size(); i++) {
10013                ContentProviderConnection conn = r.conProviders.get(i);
10014                if (conn.provider == cpr) {
10015                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10016                            "Adding provider requested by "
10017                            + r.processName + " from process "
10018                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10019                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10020                    if (stable) {
10021                        conn.stableCount++;
10022                        conn.numStableIncs++;
10023                    } else {
10024                        conn.unstableCount++;
10025                        conn.numUnstableIncs++;
10026                    }
10027                    return conn;
10028                }
10029            }
10030            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10031            if (stable) {
10032                conn.stableCount = 1;
10033                conn.numStableIncs = 1;
10034            } else {
10035                conn.unstableCount = 1;
10036                conn.numUnstableIncs = 1;
10037            }
10038            cpr.connections.add(conn);
10039            r.conProviders.add(conn);
10040            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10041            return conn;
10042        }
10043        cpr.addExternalProcessHandleLocked(externalProcessToken);
10044        return null;
10045    }
10046
10047    boolean decProviderCountLocked(ContentProviderConnection conn,
10048            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10049        if (conn != null) {
10050            cpr = conn.provider;
10051            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10052                    "Removing provider requested by "
10053                    + conn.client.processName + " from process "
10054                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10055                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10056            if (stable) {
10057                conn.stableCount--;
10058            } else {
10059                conn.unstableCount--;
10060            }
10061            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10062                cpr.connections.remove(conn);
10063                conn.client.conProviders.remove(conn);
10064                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10065                    // The client is more important than last activity -- note the time this
10066                    // is happening, so we keep the old provider process around a bit as last
10067                    // activity to avoid thrashing it.
10068                    if (cpr.proc != null) {
10069                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10070                    }
10071                }
10072                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10073                return true;
10074            }
10075            return false;
10076        }
10077        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10078        return false;
10079    }
10080
10081    private void checkTime(long startTime, String where) {
10082        long now = SystemClock.elapsedRealtime();
10083        if ((now-startTime) > 1000) {
10084            // If we are taking more than a second, log about it.
10085            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10086        }
10087    }
10088
10089    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10090            String name, IBinder token, boolean stable, int userId) {
10091        ContentProviderRecord cpr;
10092        ContentProviderConnection conn = null;
10093        ProviderInfo cpi = null;
10094
10095        synchronized(this) {
10096            long startTime = SystemClock.elapsedRealtime();
10097
10098            ProcessRecord r = null;
10099            if (caller != null) {
10100                r = getRecordForAppLocked(caller);
10101                if (r == null) {
10102                    throw new SecurityException(
10103                            "Unable to find app for caller " + caller
10104                          + " (pid=" + Binder.getCallingPid()
10105                          + ") when getting content provider " + name);
10106                }
10107            }
10108
10109            boolean checkCrossUser = true;
10110
10111            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10112
10113            // First check if this content provider has been published...
10114            cpr = mProviderMap.getProviderByName(name, userId);
10115            // If that didn't work, check if it exists for user 0 and then
10116            // verify that it's a singleton provider before using it.
10117            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10118                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10119                if (cpr != null) {
10120                    cpi = cpr.info;
10121                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10122                            cpi.name, cpi.flags)
10123                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10124                        userId = UserHandle.USER_SYSTEM;
10125                        checkCrossUser = false;
10126                    } else {
10127                        cpr = null;
10128                        cpi = null;
10129                    }
10130                }
10131            }
10132
10133            boolean providerRunning = cpr != null;
10134            if (providerRunning) {
10135                cpi = cpr.info;
10136                String msg;
10137                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10138                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10139                        != null) {
10140                    throw new SecurityException(msg);
10141                }
10142                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10143
10144                if (r != null && cpr.canRunHere(r)) {
10145                    // This provider has been published or is in the process
10146                    // of being published...  but it is also allowed to run
10147                    // in the caller's process, so don't make a connection
10148                    // and just let the caller instantiate its own instance.
10149                    ContentProviderHolder holder = cpr.newHolder(null);
10150                    // don't give caller the provider object, it needs
10151                    // to make its own.
10152                    holder.provider = null;
10153                    return holder;
10154                }
10155
10156                final long origId = Binder.clearCallingIdentity();
10157
10158                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10159
10160                // In this case the provider instance already exists, so we can
10161                // return it right away.
10162                conn = incProviderCountLocked(r, cpr, token, stable);
10163                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10164                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10165                        // If this is a perceptible app accessing the provider,
10166                        // make sure to count it as being accessed and thus
10167                        // back up on the LRU list.  This is good because
10168                        // content providers are often expensive to start.
10169                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10170                        updateLruProcessLocked(cpr.proc, false, null);
10171                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10172                    }
10173                }
10174
10175                if (cpr.proc != null) {
10176                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10177                    boolean success = updateOomAdjLocked(cpr.proc);
10178                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10179                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10180                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10181                    // NOTE: there is still a race here where a signal could be
10182                    // pending on the process even though we managed to update its
10183                    // adj level.  Not sure what to do about this, but at least
10184                    // the race is now smaller.
10185                    if (!success) {
10186                        // Uh oh...  it looks like the provider's process
10187                        // has been killed on us.  We need to wait for a new
10188                        // process to be started, and make sure its death
10189                        // doesn't kill our process.
10190                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10191                                + " is crashing; detaching " + r);
10192                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10193                        checkTime(startTime, "getContentProviderImpl: before appDied");
10194                        appDiedLocked(cpr.proc);
10195                        checkTime(startTime, "getContentProviderImpl: after appDied");
10196                        if (!lastRef) {
10197                            // This wasn't the last ref our process had on
10198                            // the provider...  we have now been killed, bail.
10199                            return null;
10200                        }
10201                        providerRunning = false;
10202                        conn = null;
10203                    }
10204                }
10205
10206                Binder.restoreCallingIdentity(origId);
10207            }
10208
10209            if (!providerRunning) {
10210                try {
10211                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10212                    cpi = AppGlobals.getPackageManager().
10213                        resolveContentProvider(name,
10214                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10215                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10216                } catch (RemoteException ex) {
10217                }
10218                if (cpi == null) {
10219                    return null;
10220                }
10221                // If the provider is a singleton AND
10222                // (it's a call within the same user || the provider is a
10223                // privileged app)
10224                // Then allow connecting to the singleton provider
10225                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10226                        cpi.name, cpi.flags)
10227                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10228                if (singleton) {
10229                    userId = UserHandle.USER_SYSTEM;
10230                }
10231                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10232                checkTime(startTime, "getContentProviderImpl: got app info for user");
10233
10234                String msg;
10235                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10236                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10237                        != null) {
10238                    throw new SecurityException(msg);
10239                }
10240                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10241
10242                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10243                        && !cpi.processName.equals("system")) {
10244                    // If this content provider does not run in the system
10245                    // process, and the system is not yet ready to run other
10246                    // processes, then fail fast instead of hanging.
10247                    throw new IllegalArgumentException(
10248                            "Attempt to launch content provider before system ready");
10249                }
10250
10251                // Make sure that the user who owns this provider is running.  If not,
10252                // we don't want to allow it to run.
10253                if (!mUserController.isUserRunningLocked(userId, 0)) {
10254                    Slog.w(TAG, "Unable to launch app "
10255                            + cpi.applicationInfo.packageName + "/"
10256                            + cpi.applicationInfo.uid + " for provider "
10257                            + name + ": user " + userId + " is stopped");
10258                    return null;
10259                }
10260
10261                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10262                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10263                cpr = mProviderMap.getProviderByClass(comp, userId);
10264                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10265                final boolean firstClass = cpr == null;
10266                if (firstClass) {
10267                    final long ident = Binder.clearCallingIdentity();
10268
10269                    // If permissions need a review before any of the app components can run,
10270                    // we return no provider and launch a review activity if the calling app
10271                    // is in the foreground.
10272                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10273                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10274                            return null;
10275                        }
10276                    }
10277
10278                    try {
10279                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10280                        ApplicationInfo ai =
10281                            AppGlobals.getPackageManager().
10282                                getApplicationInfo(
10283                                        cpi.applicationInfo.packageName,
10284                                        STOCK_PM_FLAGS, userId);
10285                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10286                        if (ai == null) {
10287                            Slog.w(TAG, "No package info for content provider "
10288                                    + cpi.name);
10289                            return null;
10290                        }
10291                        ai = getAppInfoForUser(ai, userId);
10292                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10293                    } catch (RemoteException ex) {
10294                        // pm is in same process, this will never happen.
10295                    } finally {
10296                        Binder.restoreCallingIdentity(ident);
10297                    }
10298                }
10299
10300                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10301
10302                if (r != null && cpr.canRunHere(r)) {
10303                    // If this is a multiprocess provider, then just return its
10304                    // info and allow the caller to instantiate it.  Only do
10305                    // this if the provider is the same user as the caller's
10306                    // process, or can run as root (so can be in any process).
10307                    return cpr.newHolder(null);
10308                }
10309
10310                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10311                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10312                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10313
10314                // This is single process, and our app is now connecting to it.
10315                // See if we are already in the process of launching this
10316                // provider.
10317                final int N = mLaunchingProviders.size();
10318                int i;
10319                for (i = 0; i < N; i++) {
10320                    if (mLaunchingProviders.get(i) == cpr) {
10321                        break;
10322                    }
10323                }
10324
10325                // If the provider is not already being launched, then get it
10326                // started.
10327                if (i >= N) {
10328                    final long origId = Binder.clearCallingIdentity();
10329
10330                    try {
10331                        // Content provider is now in use, its package can't be stopped.
10332                        try {
10333                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10334                            AppGlobals.getPackageManager().setPackageStoppedState(
10335                                    cpr.appInfo.packageName, false, userId);
10336                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10337                        } catch (RemoteException e) {
10338                        } catch (IllegalArgumentException e) {
10339                            Slog.w(TAG, "Failed trying to unstop package "
10340                                    + cpr.appInfo.packageName + ": " + e);
10341                        }
10342
10343                        // Use existing process if already started
10344                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10345                        ProcessRecord proc = getProcessRecordLocked(
10346                                cpi.processName, cpr.appInfo.uid, false);
10347                        if (proc != null && proc.thread != null) {
10348                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10349                                    "Installing in existing process " + proc);
10350                            if (!proc.pubProviders.containsKey(cpi.name)) {
10351                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10352                                proc.pubProviders.put(cpi.name, cpr);
10353                                try {
10354                                    proc.thread.scheduleInstallProvider(cpi);
10355                                } catch (RemoteException e) {
10356                                }
10357                            }
10358                        } else {
10359                            checkTime(startTime, "getContentProviderImpl: before start process");
10360                            proc = startProcessLocked(cpi.processName,
10361                                    cpr.appInfo, false, 0, "content provider",
10362                                    new ComponentName(cpi.applicationInfo.packageName,
10363                                            cpi.name), false, false, false);
10364                            checkTime(startTime, "getContentProviderImpl: after start process");
10365                            if (proc == null) {
10366                                Slog.w(TAG, "Unable to launch app "
10367                                        + cpi.applicationInfo.packageName + "/"
10368                                        + cpi.applicationInfo.uid + " for provider "
10369                                        + name + ": process is bad");
10370                                return null;
10371                            }
10372                        }
10373                        cpr.launchingApp = proc;
10374                        mLaunchingProviders.add(cpr);
10375                    } finally {
10376                        Binder.restoreCallingIdentity(origId);
10377                    }
10378                }
10379
10380                checkTime(startTime, "getContentProviderImpl: updating data structures");
10381
10382                // Make sure the provider is published (the same provider class
10383                // may be published under multiple names).
10384                if (firstClass) {
10385                    mProviderMap.putProviderByClass(comp, cpr);
10386                }
10387
10388                mProviderMap.putProviderByName(name, cpr);
10389                conn = incProviderCountLocked(r, cpr, token, stable);
10390                if (conn != null) {
10391                    conn.waiting = true;
10392                }
10393            }
10394            checkTime(startTime, "getContentProviderImpl: done!");
10395        }
10396
10397        // Wait for the provider to be published...
10398        synchronized (cpr) {
10399            while (cpr.provider == null) {
10400                if (cpr.launchingApp == null) {
10401                    Slog.w(TAG, "Unable to launch app "
10402                            + cpi.applicationInfo.packageName + "/"
10403                            + cpi.applicationInfo.uid + " for provider "
10404                            + name + ": launching app became null");
10405                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10406                            UserHandle.getUserId(cpi.applicationInfo.uid),
10407                            cpi.applicationInfo.packageName,
10408                            cpi.applicationInfo.uid, name);
10409                    return null;
10410                }
10411                try {
10412                    if (DEBUG_MU) Slog.v(TAG_MU,
10413                            "Waiting to start provider " + cpr
10414                            + " launchingApp=" + cpr.launchingApp);
10415                    if (conn != null) {
10416                        conn.waiting = true;
10417                    }
10418                    cpr.wait();
10419                } catch (InterruptedException ex) {
10420                } finally {
10421                    if (conn != null) {
10422                        conn.waiting = false;
10423                    }
10424                }
10425            }
10426        }
10427        return cpr != null ? cpr.newHolder(conn) : null;
10428    }
10429
10430    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10431            ProcessRecord r, final int userId) {
10432        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10433                cpi.packageName, r.userId)) {
10434
10435            final boolean callerForeground = r != null ? r.setSchedGroup
10436                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10437
10438            // Show a permission review UI only for starting from a foreground app
10439            if (!callerForeground) {
10440                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10441                        + cpi.packageName + " requires a permissions review");
10442                return false;
10443            }
10444
10445            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10446            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10447                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10448            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10449
10450            if (DEBUG_PERMISSIONS_REVIEW) {
10451                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10452                        + "for package " + cpi.packageName);
10453            }
10454
10455            final UserHandle userHandle = new UserHandle(userId);
10456            mHandler.post(new Runnable() {
10457                @Override
10458                public void run() {
10459                    mContext.startActivityAsUser(intent, userHandle);
10460                }
10461            });
10462
10463            return false;
10464        }
10465
10466        return true;
10467    }
10468
10469    PackageManagerInternal getPackageManagerInternalLocked() {
10470        if (mPackageManagerInt == null) {
10471            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10472        }
10473        return mPackageManagerInt;
10474    }
10475
10476    @Override
10477    public final ContentProviderHolder getContentProvider(
10478            IApplicationThread caller, String name, int userId, boolean stable) {
10479        enforceNotIsolatedCaller("getContentProvider");
10480        if (caller == null) {
10481            String msg = "null IApplicationThread when getting content provider "
10482                    + name;
10483            Slog.w(TAG, msg);
10484            throw new SecurityException(msg);
10485        }
10486        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10487        // with cross-user grant.
10488        return getContentProviderImpl(caller, name, null, stable, userId);
10489    }
10490
10491    public ContentProviderHolder getContentProviderExternal(
10492            String name, int userId, IBinder token) {
10493        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10494            "Do not have permission in call getContentProviderExternal()");
10495        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10496                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10497        return getContentProviderExternalUnchecked(name, token, userId);
10498    }
10499
10500    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10501            IBinder token, int userId) {
10502        return getContentProviderImpl(null, name, token, true, userId);
10503    }
10504
10505    /**
10506     * Drop a content provider from a ProcessRecord's bookkeeping
10507     */
10508    public void removeContentProvider(IBinder connection, boolean stable) {
10509        enforceNotIsolatedCaller("removeContentProvider");
10510        long ident = Binder.clearCallingIdentity();
10511        try {
10512            synchronized (this) {
10513                ContentProviderConnection conn;
10514                try {
10515                    conn = (ContentProviderConnection)connection;
10516                } catch (ClassCastException e) {
10517                    String msg ="removeContentProvider: " + connection
10518                            + " not a ContentProviderConnection";
10519                    Slog.w(TAG, msg);
10520                    throw new IllegalArgumentException(msg);
10521                }
10522                if (conn == null) {
10523                    throw new NullPointerException("connection is null");
10524                }
10525                if (decProviderCountLocked(conn, null, null, stable)) {
10526                    updateOomAdjLocked();
10527                }
10528            }
10529        } finally {
10530            Binder.restoreCallingIdentity(ident);
10531        }
10532    }
10533
10534    public void removeContentProviderExternal(String name, IBinder token) {
10535        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10536            "Do not have permission in call removeContentProviderExternal()");
10537        int userId = UserHandle.getCallingUserId();
10538        long ident = Binder.clearCallingIdentity();
10539        try {
10540            removeContentProviderExternalUnchecked(name, token, userId);
10541        } finally {
10542            Binder.restoreCallingIdentity(ident);
10543        }
10544    }
10545
10546    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10547        synchronized (this) {
10548            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10549            if(cpr == null) {
10550                //remove from mProvidersByClass
10551                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10552                return;
10553            }
10554
10555            //update content provider record entry info
10556            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10557            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10558            if (localCpr.hasExternalProcessHandles()) {
10559                if (localCpr.removeExternalProcessHandleLocked(token)) {
10560                    updateOomAdjLocked();
10561                } else {
10562                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10563                            + " with no external reference for token: "
10564                            + token + ".");
10565                }
10566            } else {
10567                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10568                        + " with no external references.");
10569            }
10570        }
10571    }
10572
10573    public final void publishContentProviders(IApplicationThread caller,
10574            List<ContentProviderHolder> providers) {
10575        if (providers == null) {
10576            return;
10577        }
10578
10579        enforceNotIsolatedCaller("publishContentProviders");
10580        synchronized (this) {
10581            final ProcessRecord r = getRecordForAppLocked(caller);
10582            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10583            if (r == null) {
10584                throw new SecurityException(
10585                        "Unable to find app for caller " + caller
10586                      + " (pid=" + Binder.getCallingPid()
10587                      + ") when publishing content providers");
10588            }
10589
10590            final long origId = Binder.clearCallingIdentity();
10591
10592            final int N = providers.size();
10593            for (int i = 0; i < N; i++) {
10594                ContentProviderHolder src = providers.get(i);
10595                if (src == null || src.info == null || src.provider == null) {
10596                    continue;
10597                }
10598                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10599                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10600                if (dst != null) {
10601                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10602                    mProviderMap.putProviderByClass(comp, dst);
10603                    String names[] = dst.info.authority.split(";");
10604                    for (int j = 0; j < names.length; j++) {
10605                        mProviderMap.putProviderByName(names[j], dst);
10606                    }
10607
10608                    int launchingCount = mLaunchingProviders.size();
10609                    int j;
10610                    boolean wasInLaunchingProviders = false;
10611                    for (j = 0; j < launchingCount; j++) {
10612                        if (mLaunchingProviders.get(j) == dst) {
10613                            mLaunchingProviders.remove(j);
10614                            wasInLaunchingProviders = true;
10615                            j--;
10616                            launchingCount--;
10617                        }
10618                    }
10619                    if (wasInLaunchingProviders) {
10620                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10621                    }
10622                    synchronized (dst) {
10623                        dst.provider = src.provider;
10624                        dst.proc = r;
10625                        dst.notifyAll();
10626                    }
10627                    updateOomAdjLocked(r);
10628                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10629                            src.info.authority);
10630                }
10631            }
10632
10633            Binder.restoreCallingIdentity(origId);
10634        }
10635    }
10636
10637    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10638        ContentProviderConnection conn;
10639        try {
10640            conn = (ContentProviderConnection)connection;
10641        } catch (ClassCastException e) {
10642            String msg ="refContentProvider: " + connection
10643                    + " not a ContentProviderConnection";
10644            Slog.w(TAG, msg);
10645            throw new IllegalArgumentException(msg);
10646        }
10647        if (conn == null) {
10648            throw new NullPointerException("connection is null");
10649        }
10650
10651        synchronized (this) {
10652            if (stable > 0) {
10653                conn.numStableIncs += stable;
10654            }
10655            stable = conn.stableCount + stable;
10656            if (stable < 0) {
10657                throw new IllegalStateException("stableCount < 0: " + stable);
10658            }
10659
10660            if (unstable > 0) {
10661                conn.numUnstableIncs += unstable;
10662            }
10663            unstable = conn.unstableCount + unstable;
10664            if (unstable < 0) {
10665                throw new IllegalStateException("unstableCount < 0: " + unstable);
10666            }
10667
10668            if ((stable+unstable) <= 0) {
10669                throw new IllegalStateException("ref counts can't go to zero here: stable="
10670                        + stable + " unstable=" + unstable);
10671            }
10672            conn.stableCount = stable;
10673            conn.unstableCount = unstable;
10674            return !conn.dead;
10675        }
10676    }
10677
10678    public void unstableProviderDied(IBinder connection) {
10679        ContentProviderConnection conn;
10680        try {
10681            conn = (ContentProviderConnection)connection;
10682        } catch (ClassCastException e) {
10683            String msg ="refContentProvider: " + connection
10684                    + " not a ContentProviderConnection";
10685            Slog.w(TAG, msg);
10686            throw new IllegalArgumentException(msg);
10687        }
10688        if (conn == null) {
10689            throw new NullPointerException("connection is null");
10690        }
10691
10692        // Safely retrieve the content provider associated with the connection.
10693        IContentProvider provider;
10694        synchronized (this) {
10695            provider = conn.provider.provider;
10696        }
10697
10698        if (provider == null) {
10699            // Um, yeah, we're way ahead of you.
10700            return;
10701        }
10702
10703        // Make sure the caller is being honest with us.
10704        if (provider.asBinder().pingBinder()) {
10705            // Er, no, still looks good to us.
10706            synchronized (this) {
10707                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10708                        + " says " + conn + " died, but we don't agree");
10709                return;
10710            }
10711        }
10712
10713        // Well look at that!  It's dead!
10714        synchronized (this) {
10715            if (conn.provider.provider != provider) {
10716                // But something changed...  good enough.
10717                return;
10718            }
10719
10720            ProcessRecord proc = conn.provider.proc;
10721            if (proc == null || proc.thread == null) {
10722                // Seems like the process is already cleaned up.
10723                return;
10724            }
10725
10726            // As far as we're concerned, this is just like receiving a
10727            // death notification...  just a bit prematurely.
10728            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10729                    + ") early provider death");
10730            final long ident = Binder.clearCallingIdentity();
10731            try {
10732                appDiedLocked(proc);
10733            } finally {
10734                Binder.restoreCallingIdentity(ident);
10735            }
10736        }
10737    }
10738
10739    @Override
10740    public void appNotRespondingViaProvider(IBinder connection) {
10741        enforceCallingPermission(
10742                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10743
10744        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10745        if (conn == null) {
10746            Slog.w(TAG, "ContentProviderConnection is null");
10747            return;
10748        }
10749
10750        final ProcessRecord host = conn.provider.proc;
10751        if (host == null) {
10752            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10753            return;
10754        }
10755
10756        final long token = Binder.clearCallingIdentity();
10757        try {
10758            appNotResponding(host, null, null, false, "ContentProvider not responding");
10759        } finally {
10760            Binder.restoreCallingIdentity(token);
10761        }
10762    }
10763
10764    public final void installSystemProviders() {
10765        List<ProviderInfo> providers;
10766        synchronized (this) {
10767            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10768            providers = generateApplicationProvidersLocked(app);
10769            if (providers != null) {
10770                for (int i=providers.size()-1; i>=0; i--) {
10771                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10772                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10773                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10774                                + ": not system .apk");
10775                        providers.remove(i);
10776                    }
10777                }
10778            }
10779        }
10780        if (providers != null) {
10781            mSystemThread.installSystemProviders(providers);
10782        }
10783
10784        mCoreSettingsObserver = new CoreSettingsObserver(this);
10785
10786        //mUsageStatsService.monitorPackages();
10787    }
10788
10789    /**
10790     * Allows apps to retrieve the MIME type of a URI.
10791     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10792     * users, then it does not need permission to access the ContentProvider.
10793     * Either, it needs cross-user uri grants.
10794     *
10795     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10796     *
10797     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10798     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10799     */
10800    public String getProviderMimeType(Uri uri, int userId) {
10801        enforceNotIsolatedCaller("getProviderMimeType");
10802        final String name = uri.getAuthority();
10803        int callingUid = Binder.getCallingUid();
10804        int callingPid = Binder.getCallingPid();
10805        long ident = 0;
10806        boolean clearedIdentity = false;
10807        synchronized (this) {
10808            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10809        }
10810        if (canClearIdentity(callingPid, callingUid, userId)) {
10811            clearedIdentity = true;
10812            ident = Binder.clearCallingIdentity();
10813        }
10814        ContentProviderHolder holder = null;
10815        try {
10816            holder = getContentProviderExternalUnchecked(name, null, userId);
10817            if (holder != null) {
10818                return holder.provider.getType(uri);
10819            }
10820        } catch (RemoteException e) {
10821            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10822            return null;
10823        } finally {
10824            // We need to clear the identity to call removeContentProviderExternalUnchecked
10825            if (!clearedIdentity) {
10826                ident = Binder.clearCallingIdentity();
10827            }
10828            try {
10829                if (holder != null) {
10830                    removeContentProviderExternalUnchecked(name, null, userId);
10831                }
10832            } finally {
10833                Binder.restoreCallingIdentity(ident);
10834            }
10835        }
10836
10837        return null;
10838    }
10839
10840    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10841        if (UserHandle.getUserId(callingUid) == userId) {
10842            return true;
10843        }
10844        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10845                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10846                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10847                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10848                return true;
10849        }
10850        return false;
10851    }
10852
10853    // =========================================================
10854    // GLOBAL MANAGEMENT
10855    // =========================================================
10856
10857    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10858            boolean isolated, int isolatedUid) {
10859        String proc = customProcess != null ? customProcess : info.processName;
10860        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10861        final int userId = UserHandle.getUserId(info.uid);
10862        int uid = info.uid;
10863        if (isolated) {
10864            if (isolatedUid == 0) {
10865                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10866                while (true) {
10867                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10868                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10869                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10870                    }
10871                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10872                    mNextIsolatedProcessUid++;
10873                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10874                        // No process for this uid, use it.
10875                        break;
10876                    }
10877                    stepsLeft--;
10878                    if (stepsLeft <= 0) {
10879                        return null;
10880                    }
10881                }
10882            } else {
10883                // Special case for startIsolatedProcess (internal only), where
10884                // the uid of the isolated process is specified by the caller.
10885                uid = isolatedUid;
10886            }
10887        }
10888        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10889        if (!mBooted && !mBooting
10890                && userId == UserHandle.USER_SYSTEM
10891                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10892            r.persistent = true;
10893        }
10894        addProcessNameLocked(r);
10895        return r;
10896    }
10897
10898    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10899            String abiOverride) {
10900        ProcessRecord app;
10901        if (!isolated) {
10902            app = getProcessRecordLocked(info.processName, info.uid, true);
10903        } else {
10904            app = null;
10905        }
10906
10907        if (app == null) {
10908            app = newProcessRecordLocked(info, null, isolated, 0);
10909            updateLruProcessLocked(app, false, null);
10910            updateOomAdjLocked();
10911        }
10912
10913        // This package really, really can not be stopped.
10914        try {
10915            AppGlobals.getPackageManager().setPackageStoppedState(
10916                    info.packageName, false, UserHandle.getUserId(app.uid));
10917        } catch (RemoteException e) {
10918        } catch (IllegalArgumentException e) {
10919            Slog.w(TAG, "Failed trying to unstop package "
10920                    + info.packageName + ": " + e);
10921        }
10922
10923        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10924            app.persistent = true;
10925            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10926        }
10927        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10928            mPersistentStartingProcesses.add(app);
10929            startProcessLocked(app, "added application", app.processName, abiOverride,
10930                    null /* entryPoint */, null /* entryPointArgs */);
10931        }
10932
10933        return app;
10934    }
10935
10936    public void unhandledBack() {
10937        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10938                "unhandledBack()");
10939
10940        synchronized(this) {
10941            final long origId = Binder.clearCallingIdentity();
10942            try {
10943                getFocusedStack().unhandledBackLocked();
10944            } finally {
10945                Binder.restoreCallingIdentity(origId);
10946            }
10947        }
10948    }
10949
10950    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10951        enforceNotIsolatedCaller("openContentUri");
10952        final int userId = UserHandle.getCallingUserId();
10953        String name = uri.getAuthority();
10954        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10955        ParcelFileDescriptor pfd = null;
10956        if (cph != null) {
10957            // We record the binder invoker's uid in thread-local storage before
10958            // going to the content provider to open the file.  Later, in the code
10959            // that handles all permissions checks, we look for this uid and use
10960            // that rather than the Activity Manager's own uid.  The effect is that
10961            // we do the check against the caller's permissions even though it looks
10962            // to the content provider like the Activity Manager itself is making
10963            // the request.
10964            Binder token = new Binder();
10965            sCallerIdentity.set(new Identity(
10966                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10967            try {
10968                pfd = cph.provider.openFile(null, uri, "r", null, token);
10969            } catch (FileNotFoundException e) {
10970                // do nothing; pfd will be returned null
10971            } finally {
10972                // Ensure that whatever happens, we clean up the identity state
10973                sCallerIdentity.remove();
10974                // Ensure we're done with the provider.
10975                removeContentProviderExternalUnchecked(name, null, userId);
10976            }
10977        } else {
10978            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10979        }
10980        return pfd;
10981    }
10982
10983    // Actually is sleeping or shutting down or whatever else in the future
10984    // is an inactive state.
10985    public boolean isSleepingOrShuttingDown() {
10986        return isSleeping() || mShuttingDown;
10987    }
10988
10989    public boolean isSleeping() {
10990        return mSleeping;
10991    }
10992
10993    void onWakefulnessChanged(int wakefulness) {
10994        synchronized(this) {
10995            mWakefulness = wakefulness;
10996            updateSleepIfNeededLocked();
10997        }
10998    }
10999
11000    void finishRunningVoiceLocked() {
11001        if (mRunningVoice != null) {
11002            mRunningVoice = null;
11003            mVoiceWakeLock.release();
11004            updateSleepIfNeededLocked();
11005        }
11006    }
11007
11008    void startTimeTrackingFocusedActivityLocked() {
11009        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11010            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11011        }
11012    }
11013
11014    void updateSleepIfNeededLocked() {
11015        if (mSleeping && !shouldSleepLocked()) {
11016            mSleeping = false;
11017            startTimeTrackingFocusedActivityLocked();
11018            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11019            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11020            updateOomAdjLocked();
11021        } else if (!mSleeping && shouldSleepLocked()) {
11022            mSleeping = true;
11023            if (mCurAppTimeTracker != null) {
11024                mCurAppTimeTracker.stop();
11025            }
11026            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11027            mStackSupervisor.goingToSleepLocked();
11028            updateOomAdjLocked();
11029
11030            // Initialize the wake times of all processes.
11031            checkExcessivePowerUsageLocked(false);
11032            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11033            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11034            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11035        }
11036    }
11037
11038    private boolean shouldSleepLocked() {
11039        // Resume applications while running a voice interactor.
11040        if (mRunningVoice != null) {
11041            return false;
11042        }
11043
11044        // TODO: Transform the lock screen state into a sleep token instead.
11045        switch (mWakefulness) {
11046            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11047            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11048            case PowerManagerInternal.WAKEFULNESS_DOZING:
11049                // Pause applications whenever the lock screen is shown or any sleep
11050                // tokens have been acquired.
11051                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11052            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11053            default:
11054                // If we're asleep then pause applications unconditionally.
11055                return true;
11056        }
11057    }
11058
11059    /** Pokes the task persister. */
11060    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11061        if (task != null && task.stack != null && task.stack.isHomeStack()) {
11062            // Never persist the home stack.
11063            return;
11064        }
11065        mTaskPersister.wakeup(task, flush);
11066    }
11067
11068    /** Notifies all listeners when the task stack has changed. */
11069    void notifyTaskStackChangedLocked() {
11070        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11071        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11072        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11073        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11074    }
11075
11076    /** Notifies all listeners when an Activity is pinned. */
11077    void notifyActivityPinnedLocked() {
11078        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11079        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11080    }
11081
11082    @Override
11083    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11084        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11085    }
11086
11087    @Override
11088    public boolean shutdown(int timeout) {
11089        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11090                != PackageManager.PERMISSION_GRANTED) {
11091            throw new SecurityException("Requires permission "
11092                    + android.Manifest.permission.SHUTDOWN);
11093        }
11094
11095        boolean timedout = false;
11096
11097        synchronized(this) {
11098            mShuttingDown = true;
11099            updateEventDispatchingLocked();
11100            timedout = mStackSupervisor.shutdownLocked(timeout);
11101        }
11102
11103        mAppOpsService.shutdown();
11104        if (mUsageStatsService != null) {
11105            mUsageStatsService.prepareShutdown();
11106        }
11107        mBatteryStatsService.shutdown();
11108        synchronized (this) {
11109            mProcessStats.shutdownLocked();
11110            notifyTaskPersisterLocked(null, true);
11111        }
11112
11113        return timedout;
11114    }
11115
11116    public final void activitySlept(IBinder token) {
11117        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11118
11119        final long origId = Binder.clearCallingIdentity();
11120
11121        synchronized (this) {
11122            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11123            if (r != null) {
11124                mStackSupervisor.activitySleptLocked(r);
11125            }
11126        }
11127
11128        Binder.restoreCallingIdentity(origId);
11129    }
11130
11131    private String lockScreenShownToString() {
11132        switch (mLockScreenShown) {
11133            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11134            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11135            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11136            default: return "Unknown=" + mLockScreenShown;
11137        }
11138    }
11139
11140    void logLockScreen(String msg) {
11141        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11142                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11143                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11144                + " mSleeping=" + mSleeping);
11145    }
11146
11147    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11148        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11149        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11150            boolean wasRunningVoice = mRunningVoice != null;
11151            mRunningVoice = session;
11152            if (!wasRunningVoice) {
11153                mVoiceWakeLock.acquire();
11154                updateSleepIfNeededLocked();
11155            }
11156        }
11157    }
11158
11159    private void updateEventDispatchingLocked() {
11160        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11161    }
11162
11163    public void setLockScreenShown(boolean shown) {
11164        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11165                != PackageManager.PERMISSION_GRANTED) {
11166            throw new SecurityException("Requires permission "
11167                    + android.Manifest.permission.DEVICE_POWER);
11168        }
11169
11170        synchronized(this) {
11171            long ident = Binder.clearCallingIdentity();
11172            try {
11173                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11174                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11175                updateSleepIfNeededLocked();
11176            } finally {
11177                Binder.restoreCallingIdentity(ident);
11178            }
11179        }
11180    }
11181
11182    @Override
11183    public void stopAppSwitches() {
11184        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11185                != PackageManager.PERMISSION_GRANTED) {
11186            throw new SecurityException("viewquires permission "
11187                    + android.Manifest.permission.STOP_APP_SWITCHES);
11188        }
11189
11190        synchronized(this) {
11191            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11192                    + APP_SWITCH_DELAY_TIME;
11193            mDidAppSwitch = false;
11194            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11195            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11196            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11197        }
11198    }
11199
11200    public void resumeAppSwitches() {
11201        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11202                != PackageManager.PERMISSION_GRANTED) {
11203            throw new SecurityException("Requires permission "
11204                    + android.Manifest.permission.STOP_APP_SWITCHES);
11205        }
11206
11207        synchronized(this) {
11208            // Note that we don't execute any pending app switches... we will
11209            // let those wait until either the timeout, or the next start
11210            // activity request.
11211            mAppSwitchesAllowedTime = 0;
11212        }
11213    }
11214
11215    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11216            int callingPid, int callingUid, String name) {
11217        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11218            return true;
11219        }
11220
11221        int perm = checkComponentPermission(
11222                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11223                sourceUid, -1, true);
11224        if (perm == PackageManager.PERMISSION_GRANTED) {
11225            return true;
11226        }
11227
11228        // If the actual IPC caller is different from the logical source, then
11229        // also see if they are allowed to control app switches.
11230        if (callingUid != -1 && callingUid != sourceUid) {
11231            perm = checkComponentPermission(
11232                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11233                    callingUid, -1, true);
11234            if (perm == PackageManager.PERMISSION_GRANTED) {
11235                return true;
11236            }
11237        }
11238
11239        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11240        return false;
11241    }
11242
11243    public void setDebugApp(String packageName, boolean waitForDebugger,
11244            boolean persistent) {
11245        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11246                "setDebugApp()");
11247
11248        long ident = Binder.clearCallingIdentity();
11249        try {
11250            // Note that this is not really thread safe if there are multiple
11251            // callers into it at the same time, but that's not a situation we
11252            // care about.
11253            if (persistent) {
11254                final ContentResolver resolver = mContext.getContentResolver();
11255                Settings.Global.putString(
11256                    resolver, Settings.Global.DEBUG_APP,
11257                    packageName);
11258                Settings.Global.putInt(
11259                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11260                    waitForDebugger ? 1 : 0);
11261            }
11262
11263            synchronized (this) {
11264                if (!persistent) {
11265                    mOrigDebugApp = mDebugApp;
11266                    mOrigWaitForDebugger = mWaitForDebugger;
11267                }
11268                mDebugApp = packageName;
11269                mWaitForDebugger = waitForDebugger;
11270                mDebugTransient = !persistent;
11271                if (packageName != null) {
11272                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11273                            false, UserHandle.USER_ALL, "set debug app");
11274                }
11275            }
11276        } finally {
11277            Binder.restoreCallingIdentity(ident);
11278        }
11279    }
11280
11281    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11282        synchronized (this) {
11283            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11284            if (!isDebuggable) {
11285                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11286                    throw new SecurityException("Process not debuggable: " + app.packageName);
11287                }
11288            }
11289
11290            mTrackAllocationApp = processName;
11291        }
11292    }
11293
11294    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11295        synchronized (this) {
11296            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11297            if (!isDebuggable) {
11298                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11299                    throw new SecurityException("Process not debuggable: " + app.packageName);
11300                }
11301            }
11302            mProfileApp = processName;
11303            mProfileFile = profilerInfo.profileFile;
11304            if (mProfileFd != null) {
11305                try {
11306                    mProfileFd.close();
11307                } catch (IOException e) {
11308                }
11309                mProfileFd = null;
11310            }
11311            mProfileFd = profilerInfo.profileFd;
11312            mSamplingInterval = profilerInfo.samplingInterval;
11313            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11314            mProfileType = 0;
11315        }
11316    }
11317
11318    @Override
11319    public void setAlwaysFinish(boolean enabled) {
11320        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11321                "setAlwaysFinish()");
11322
11323        Settings.Global.putInt(
11324                mContext.getContentResolver(),
11325                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11326
11327        synchronized (this) {
11328            mAlwaysFinishActivities = enabled;
11329        }
11330    }
11331
11332    @Override
11333    public void setActivityController(IActivityController controller) {
11334        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11335                "setActivityController()");
11336        synchronized (this) {
11337            mController = controller;
11338            Watchdog.getInstance().setActivityController(controller);
11339        }
11340    }
11341
11342    @Override
11343    public void setUserIsMonkey(boolean userIsMonkey) {
11344        synchronized (this) {
11345            synchronized (mPidsSelfLocked) {
11346                final int callingPid = Binder.getCallingPid();
11347                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11348                if (precessRecord == null) {
11349                    throw new SecurityException("Unknown process: " + callingPid);
11350                }
11351                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11352                    throw new SecurityException("Only an instrumentation process "
11353                            + "with a UiAutomation can call setUserIsMonkey");
11354                }
11355            }
11356            mUserIsMonkey = userIsMonkey;
11357        }
11358    }
11359
11360    @Override
11361    public boolean isUserAMonkey() {
11362        synchronized (this) {
11363            // If there is a controller also implies the user is a monkey.
11364            return (mUserIsMonkey || mController != null);
11365        }
11366    }
11367
11368    public void requestBugReport(boolean progress) {
11369        final String service = progress ? "bugreportplus" : "bugreport";
11370        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11371        SystemProperties.set("ctl.start", service);
11372    }
11373
11374    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11375        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11376    }
11377
11378    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11379        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11380            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11381        }
11382        return KEY_DISPATCHING_TIMEOUT;
11383    }
11384
11385    @Override
11386    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11387        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11388                != PackageManager.PERMISSION_GRANTED) {
11389            throw new SecurityException("Requires permission "
11390                    + android.Manifest.permission.FILTER_EVENTS);
11391        }
11392        ProcessRecord proc;
11393        long timeout;
11394        synchronized (this) {
11395            synchronized (mPidsSelfLocked) {
11396                proc = mPidsSelfLocked.get(pid);
11397            }
11398            timeout = getInputDispatchingTimeoutLocked(proc);
11399        }
11400
11401        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11402            return -1;
11403        }
11404
11405        return timeout;
11406    }
11407
11408    /**
11409     * Handle input dispatching timeouts.
11410     * Returns whether input dispatching should be aborted or not.
11411     */
11412    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11413            final ActivityRecord activity, final ActivityRecord parent,
11414            final boolean aboveSystem, String reason) {
11415        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11416                != PackageManager.PERMISSION_GRANTED) {
11417            throw new SecurityException("Requires permission "
11418                    + android.Manifest.permission.FILTER_EVENTS);
11419        }
11420
11421        final String annotation;
11422        if (reason == null) {
11423            annotation = "Input dispatching timed out";
11424        } else {
11425            annotation = "Input dispatching timed out (" + reason + ")";
11426        }
11427
11428        if (proc != null) {
11429            synchronized (this) {
11430                if (proc.debugging) {
11431                    return false;
11432                }
11433
11434                if (mDidDexOpt) {
11435                    // Give more time since we were dexopting.
11436                    mDidDexOpt = false;
11437                    return false;
11438                }
11439
11440                if (proc.instrumentationClass != null) {
11441                    Bundle info = new Bundle();
11442                    info.putString("shortMsg", "keyDispatchingTimedOut");
11443                    info.putString("longMsg", annotation);
11444                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11445                    return true;
11446                }
11447            }
11448            mHandler.post(new Runnable() {
11449                @Override
11450                public void run() {
11451                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11452                }
11453            });
11454        }
11455
11456        return true;
11457    }
11458
11459    @Override
11460    public Bundle getAssistContextExtras(int requestType) {
11461        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11462                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11463        if (pae == null) {
11464            return null;
11465        }
11466        synchronized (pae) {
11467            while (!pae.haveResult) {
11468                try {
11469                    pae.wait();
11470                } catch (InterruptedException e) {
11471                }
11472            }
11473        }
11474        synchronized (this) {
11475            buildAssistBundleLocked(pae, pae.result);
11476            mPendingAssistExtras.remove(pae);
11477            mUiHandler.removeCallbacks(pae);
11478        }
11479        return pae.extras;
11480    }
11481
11482    @Override
11483    public boolean isAssistDataAllowedOnCurrentActivity() {
11484        int userId;
11485        synchronized (this) {
11486            userId = mUserController.getCurrentUserIdLocked();
11487            ActivityRecord activity = getFocusedStack().topActivity();
11488            if (activity == null) {
11489                return false;
11490            }
11491            userId = activity.userId;
11492        }
11493        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11494                Context.DEVICE_POLICY_SERVICE);
11495        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11496    }
11497
11498    @Override
11499    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11500        long ident = Binder.clearCallingIdentity();
11501        try {
11502            synchronized (this) {
11503                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11504                ActivityRecord top = getFocusedStack().topActivity();
11505                if (top != caller) {
11506                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11507                            + " is not current top " + top);
11508                    return false;
11509                }
11510                if (!top.nowVisible) {
11511                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11512                            + " is not visible");
11513                    return false;
11514                }
11515            }
11516            AssistUtils utils = new AssistUtils(mContext);
11517            return utils.showSessionForActiveService(args,
11518                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11519        } finally {
11520            Binder.restoreCallingIdentity(ident);
11521        }
11522    }
11523
11524    @Override
11525    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11526            IBinder activityToken) {
11527        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11528                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11529    }
11530
11531    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11532            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11533            long timeout) {
11534        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11535                "enqueueAssistContext()");
11536        synchronized (this) {
11537            ActivityRecord activity = getFocusedStack().topActivity();
11538            if (activity == null) {
11539                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11540                return null;
11541            }
11542            if (activity.app == null || activity.app.thread == null) {
11543                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11544                return null;
11545            }
11546            if (activityToken != null) {
11547                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11548                if (activity != caller) {
11549                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11550                            + " is not current top " + activity);
11551                    return null;
11552                }
11553            }
11554            PendingAssistExtras pae;
11555            Bundle extras = new Bundle();
11556            if (args != null) {
11557                extras.putAll(args);
11558            }
11559            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11560            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11561            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11562            try {
11563                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11564                        requestType);
11565                mPendingAssistExtras.add(pae);
11566                mUiHandler.postDelayed(pae, timeout);
11567            } catch (RemoteException e) {
11568                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11569                return null;
11570            }
11571            return pae;
11572        }
11573    }
11574
11575    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11576        IResultReceiver receiver;
11577        synchronized (this) {
11578            mPendingAssistExtras.remove(pae);
11579            receiver = pae.receiver;
11580        }
11581        if (receiver != null) {
11582            // Caller wants result sent back to them.
11583            try {
11584                pae.receiver.send(0, null);
11585            } catch (RemoteException e) {
11586            }
11587        }
11588    }
11589
11590    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11591        if (result != null) {
11592            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11593        }
11594        if (pae.hint != null) {
11595            pae.extras.putBoolean(pae.hint, true);
11596        }
11597    }
11598
11599    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11600            AssistContent content, Uri referrer) {
11601        PendingAssistExtras pae = (PendingAssistExtras)token;
11602        synchronized (pae) {
11603            pae.result = extras;
11604            pae.structure = structure;
11605            pae.content = content;
11606            if (referrer != null) {
11607                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11608            }
11609            pae.haveResult = true;
11610            pae.notifyAll();
11611            if (pae.intent == null && pae.receiver == null) {
11612                // Caller is just waiting for the result.
11613                return;
11614            }
11615        }
11616
11617        // We are now ready to launch the assist activity.
11618        IResultReceiver sendReceiver = null;
11619        Bundle sendBundle = null;
11620        synchronized (this) {
11621            buildAssistBundleLocked(pae, extras);
11622            boolean exists = mPendingAssistExtras.remove(pae);
11623            mUiHandler.removeCallbacks(pae);
11624            if (!exists) {
11625                // Timed out.
11626                return;
11627            }
11628            if ((sendReceiver=pae.receiver) != null) {
11629                // Caller wants result sent back to them.
11630                sendBundle = new Bundle();
11631                sendBundle.putBundle("data", pae.extras);
11632                sendBundle.putParcelable("structure", pae.structure);
11633                sendBundle.putParcelable("content", pae.content);
11634            }
11635        }
11636        if (sendReceiver != null) {
11637            try {
11638                sendReceiver.send(0, sendBundle);
11639            } catch (RemoteException e) {
11640            }
11641            return;
11642        }
11643
11644        long ident = Binder.clearCallingIdentity();
11645        try {
11646            pae.intent.replaceExtras(pae.extras);
11647            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11648                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11649                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11650            closeSystemDialogs("assist");
11651            try {
11652                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11653            } catch (ActivityNotFoundException e) {
11654                Slog.w(TAG, "No activity to handle assist action.", e);
11655            }
11656        } finally {
11657            Binder.restoreCallingIdentity(ident);
11658        }
11659    }
11660
11661    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11662            Bundle args) {
11663        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11664                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11665    }
11666
11667    public void registerProcessObserver(IProcessObserver observer) {
11668        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11669                "registerProcessObserver()");
11670        synchronized (this) {
11671            mProcessObservers.register(observer);
11672        }
11673    }
11674
11675    @Override
11676    public void unregisterProcessObserver(IProcessObserver observer) {
11677        synchronized (this) {
11678            mProcessObservers.unregister(observer);
11679        }
11680    }
11681
11682    @Override
11683    public void registerUidObserver(IUidObserver observer, int which) {
11684        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11685                "registerUidObserver()");
11686        synchronized (this) {
11687            mUidObservers.register(observer, which);
11688        }
11689    }
11690
11691    @Override
11692    public void unregisterUidObserver(IUidObserver observer) {
11693        synchronized (this) {
11694            mUidObservers.unregister(observer);
11695        }
11696    }
11697
11698    @Override
11699    public boolean convertFromTranslucent(IBinder token) {
11700        final long origId = Binder.clearCallingIdentity();
11701        try {
11702            synchronized (this) {
11703                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11704                if (r == null) {
11705                    return false;
11706                }
11707                final boolean translucentChanged = r.changeWindowTranslucency(true);
11708                if (translucentChanged) {
11709                    r.task.stack.releaseBackgroundResources(r);
11710                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11711                }
11712                mWindowManager.setAppFullscreen(token, true);
11713                return translucentChanged;
11714            }
11715        } finally {
11716            Binder.restoreCallingIdentity(origId);
11717        }
11718    }
11719
11720    @Override
11721    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11722        final long origId = Binder.clearCallingIdentity();
11723        try {
11724            synchronized (this) {
11725                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11726                if (r == null) {
11727                    return false;
11728                }
11729                int index = r.task.mActivities.lastIndexOf(r);
11730                if (index > 0) {
11731                    ActivityRecord under = r.task.mActivities.get(index - 1);
11732                    under.returningOptions = options;
11733                }
11734                final boolean translucentChanged = r.changeWindowTranslucency(false);
11735                if (translucentChanged) {
11736                    r.task.stack.convertActivityToTranslucent(r);
11737                }
11738                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11739                mWindowManager.setAppFullscreen(token, false);
11740                return translucentChanged;
11741            }
11742        } finally {
11743            Binder.restoreCallingIdentity(origId);
11744        }
11745    }
11746
11747    @Override
11748    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11749        final long origId = Binder.clearCallingIdentity();
11750        try {
11751            synchronized (this) {
11752                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11753                if (r != null) {
11754                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11755                }
11756            }
11757            return false;
11758        } finally {
11759            Binder.restoreCallingIdentity(origId);
11760        }
11761    }
11762
11763    @Override
11764    public boolean isBackgroundVisibleBehind(IBinder token) {
11765        final long origId = Binder.clearCallingIdentity();
11766        try {
11767            synchronized (this) {
11768                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11769                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11770                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11771                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11772                return visible;
11773            }
11774        } finally {
11775            Binder.restoreCallingIdentity(origId);
11776        }
11777    }
11778
11779    @Override
11780    public ActivityOptions getActivityOptions(IBinder token) {
11781        final long origId = Binder.clearCallingIdentity();
11782        try {
11783            synchronized (this) {
11784                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11785                if (r != null) {
11786                    final ActivityOptions activityOptions = r.pendingOptions;
11787                    r.pendingOptions = null;
11788                    return activityOptions;
11789                }
11790                return null;
11791            }
11792        } finally {
11793            Binder.restoreCallingIdentity(origId);
11794        }
11795    }
11796
11797    @Override
11798    public void setImmersive(IBinder token, boolean immersive) {
11799        synchronized(this) {
11800            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11801            if (r == null) {
11802                throw new IllegalArgumentException();
11803            }
11804            r.immersive = immersive;
11805
11806            // update associated state if we're frontmost
11807            if (r == mFocusedActivity) {
11808                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11809                applyUpdateLockStateLocked(r);
11810            }
11811        }
11812    }
11813
11814    @Override
11815    public boolean isImmersive(IBinder token) {
11816        synchronized (this) {
11817            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11818            if (r == null) {
11819                throw new IllegalArgumentException();
11820            }
11821            return r.immersive;
11822        }
11823    }
11824
11825    @Override
11826    public void setVrMode(IBinder token, boolean enabled) {
11827        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11828            throw new UnsupportedOperationException("VR mode not supported on this device!");
11829        }
11830
11831        synchronized(this) {
11832            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11833            if (r == null) {
11834                throw new IllegalArgumentException();
11835            }
11836            r.isVrActivity = enabled;
11837
11838            // Update associated state if this activity is currently focused
11839            if (r == mFocusedActivity) {
11840                applyUpdateVrModeLocked(r);
11841            }
11842        }
11843    }
11844
11845    public boolean isTopActivityImmersive() {
11846        enforceNotIsolatedCaller("startActivity");
11847        synchronized (this) {
11848            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11849            return (r != null) ? r.immersive : false;
11850        }
11851    }
11852
11853    @Override
11854    public boolean isTopOfTask(IBinder token) {
11855        synchronized (this) {
11856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11857            if (r == null) {
11858                throw new IllegalArgumentException();
11859            }
11860            return r.task.getTopActivity() == r;
11861        }
11862    }
11863
11864    public final void enterSafeMode() {
11865        synchronized(this) {
11866            // It only makes sense to do this before the system is ready
11867            // and started launching other packages.
11868            if (!mSystemReady) {
11869                try {
11870                    AppGlobals.getPackageManager().enterSafeMode();
11871                } catch (RemoteException e) {
11872                }
11873            }
11874
11875            mSafeMode = true;
11876        }
11877    }
11878
11879    public final void showSafeModeOverlay() {
11880        View v = LayoutInflater.from(mContext).inflate(
11881                com.android.internal.R.layout.safe_mode, null);
11882        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11883        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11884        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11885        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11886        lp.gravity = Gravity.BOTTOM | Gravity.START;
11887        lp.format = v.getBackground().getOpacity();
11888        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11889                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11890        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11891        ((WindowManager)mContext.getSystemService(
11892                Context.WINDOW_SERVICE)).addView(v, lp);
11893    }
11894
11895    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11896        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11897            return;
11898        }
11899        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11900        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11901        synchronized (stats) {
11902            if (mBatteryStatsService.isOnBattery()) {
11903                mBatteryStatsService.enforceCallingPermission();
11904                int MY_UID = Binder.getCallingUid();
11905                final int uid;
11906                if (sender == null) {
11907                    uid = sourceUid;
11908                } else {
11909                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11910                }
11911                BatteryStatsImpl.Uid.Pkg pkg =
11912                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11913                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11914                pkg.noteWakeupAlarmLocked(tag);
11915            }
11916        }
11917    }
11918
11919    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11920        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11921            return;
11922        }
11923        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11924        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11925        synchronized (stats) {
11926            mBatteryStatsService.enforceCallingPermission();
11927            int MY_UID = Binder.getCallingUid();
11928            final int uid;
11929            if (sender == null) {
11930                uid = sourceUid;
11931            } else {
11932                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11933            }
11934            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11935        }
11936    }
11937
11938    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11939        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11940            return;
11941        }
11942        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11943        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11944        synchronized (stats) {
11945            mBatteryStatsService.enforceCallingPermission();
11946            int MY_UID = Binder.getCallingUid();
11947            final int uid;
11948            if (sender == null) {
11949                uid = sourceUid;
11950            } else {
11951                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11952            }
11953            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11954        }
11955    }
11956
11957    public boolean killPids(int[] pids, String pReason, boolean secure) {
11958        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11959            throw new SecurityException("killPids only available to the system");
11960        }
11961        String reason = (pReason == null) ? "Unknown" : pReason;
11962        // XXX Note: don't acquire main activity lock here, because the window
11963        // manager calls in with its locks held.
11964
11965        boolean killed = false;
11966        synchronized (mPidsSelfLocked) {
11967            int worstType = 0;
11968            for (int i=0; i<pids.length; i++) {
11969                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11970                if (proc != null) {
11971                    int type = proc.setAdj;
11972                    if (type > worstType) {
11973                        worstType = type;
11974                    }
11975                }
11976            }
11977
11978            // If the worst oom_adj is somewhere in the cached proc LRU range,
11979            // then constrain it so we will kill all cached procs.
11980            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11981                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11982                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11983            }
11984
11985            // If this is not a secure call, don't let it kill processes that
11986            // are important.
11987            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11988                worstType = ProcessList.SERVICE_ADJ;
11989            }
11990
11991            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11992            for (int i=0; i<pids.length; i++) {
11993                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11994                if (proc == null) {
11995                    continue;
11996                }
11997                int adj = proc.setAdj;
11998                if (adj >= worstType && !proc.killedByAm) {
11999                    proc.kill(reason, true);
12000                    killed = true;
12001                }
12002            }
12003        }
12004        return killed;
12005    }
12006
12007    @Override
12008    public void killUid(int appId, int userId, String reason) {
12009        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12010        synchronized (this) {
12011            final long identity = Binder.clearCallingIdentity();
12012            try {
12013                killPackageProcessesLocked(null, appId, userId,
12014                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, true,
12015                        reason != null ? reason : "kill uid");
12016            } finally {
12017                Binder.restoreCallingIdentity(identity);
12018            }
12019        }
12020    }
12021
12022    @Override
12023    public boolean killProcessesBelowForeground(String reason) {
12024        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12025            throw new SecurityException("killProcessesBelowForeground() only available to system");
12026        }
12027
12028        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12029    }
12030
12031    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12032        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12033            throw new SecurityException("killProcessesBelowAdj() only available to system");
12034        }
12035
12036        boolean killed = false;
12037        synchronized (mPidsSelfLocked) {
12038            final int size = mPidsSelfLocked.size();
12039            for (int i = 0; i < size; i++) {
12040                final int pid = mPidsSelfLocked.keyAt(i);
12041                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12042                if (proc == null) continue;
12043
12044                final int adj = proc.setAdj;
12045                if (adj > belowAdj && !proc.killedByAm) {
12046                    proc.kill(reason, true);
12047                    killed = true;
12048                }
12049            }
12050        }
12051        return killed;
12052    }
12053
12054    @Override
12055    public void hang(final IBinder who, boolean allowRestart) {
12056        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12057                != PackageManager.PERMISSION_GRANTED) {
12058            throw new SecurityException("Requires permission "
12059                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12060        }
12061
12062        final IBinder.DeathRecipient death = new DeathRecipient() {
12063            @Override
12064            public void binderDied() {
12065                synchronized (this) {
12066                    notifyAll();
12067                }
12068            }
12069        };
12070
12071        try {
12072            who.linkToDeath(death, 0);
12073        } catch (RemoteException e) {
12074            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12075            return;
12076        }
12077
12078        synchronized (this) {
12079            Watchdog.getInstance().setAllowRestart(allowRestart);
12080            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12081            synchronized (death) {
12082                while (who.isBinderAlive()) {
12083                    try {
12084                        death.wait();
12085                    } catch (InterruptedException e) {
12086                    }
12087                }
12088            }
12089            Watchdog.getInstance().setAllowRestart(true);
12090        }
12091    }
12092
12093    @Override
12094    public void restart() {
12095        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12096                != PackageManager.PERMISSION_GRANTED) {
12097            throw new SecurityException("Requires permission "
12098                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12099        }
12100
12101        Log.i(TAG, "Sending shutdown broadcast...");
12102
12103        BroadcastReceiver br = new BroadcastReceiver() {
12104            @Override public void onReceive(Context context, Intent intent) {
12105                // Now the broadcast is done, finish up the low-level shutdown.
12106                Log.i(TAG, "Shutting down activity manager...");
12107                shutdown(10000);
12108                Log.i(TAG, "Shutdown complete, restarting!");
12109                Process.killProcess(Process.myPid());
12110                System.exit(10);
12111            }
12112        };
12113
12114        // First send the high-level shut down broadcast.
12115        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12116        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12117        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12118        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12119        mContext.sendOrderedBroadcastAsUser(intent,
12120                UserHandle.ALL, null, br, mHandler, 0, null, null);
12121        */
12122        br.onReceive(mContext, intent);
12123    }
12124
12125    private long getLowRamTimeSinceIdle(long now) {
12126        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12127    }
12128
12129    @Override
12130    public void performIdleMaintenance() {
12131        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12132                != PackageManager.PERMISSION_GRANTED) {
12133            throw new SecurityException("Requires permission "
12134                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12135        }
12136
12137        synchronized (this) {
12138            final long now = SystemClock.uptimeMillis();
12139            final long timeSinceLastIdle = now - mLastIdleTime;
12140            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12141            mLastIdleTime = now;
12142            mLowRamTimeSinceLastIdle = 0;
12143            if (mLowRamStartTime != 0) {
12144                mLowRamStartTime = now;
12145            }
12146
12147            StringBuilder sb = new StringBuilder(128);
12148            sb.append("Idle maintenance over ");
12149            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12150            sb.append(" low RAM for ");
12151            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12152            Slog.i(TAG, sb.toString());
12153
12154            // If at least 1/3 of our time since the last idle period has been spent
12155            // with RAM low, then we want to kill processes.
12156            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12157
12158            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12159                ProcessRecord proc = mLruProcesses.get(i);
12160                if (proc.notCachedSinceIdle) {
12161                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12162                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12163                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12164                        if (doKilling && proc.initialIdlePss != 0
12165                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12166                            sb = new StringBuilder(128);
12167                            sb.append("Kill");
12168                            sb.append(proc.processName);
12169                            sb.append(" in idle maint: pss=");
12170                            sb.append(proc.lastPss);
12171                            sb.append(", initialPss=");
12172                            sb.append(proc.initialIdlePss);
12173                            sb.append(", period=");
12174                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12175                            sb.append(", lowRamPeriod=");
12176                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12177                            Slog.wtfQuiet(TAG, sb.toString());
12178                            proc.kill("idle maint (pss " + proc.lastPss
12179                                    + " from " + proc.initialIdlePss + ")", true);
12180                        }
12181                    }
12182                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12183                    proc.notCachedSinceIdle = true;
12184                    proc.initialIdlePss = 0;
12185                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12186                            mTestPssMode, isSleeping(), now);
12187                }
12188            }
12189
12190            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12191            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12192        }
12193    }
12194
12195    private void retrieveSettings() {
12196        final ContentResolver resolver = mContext.getContentResolver();
12197        final boolean freeformWindowManagement =
12198                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
12199        final boolean supportsPictureInPicture =
12200                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12201
12202        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12203        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12204        final boolean alwaysFinishActivities =
12205                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12206        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12207        final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
12208        final boolean forceResizable = Settings.Global.getInt(
12209                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
12210        // Transfer any global setting for forcing RTL layout, into a System Property
12211        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12212
12213        final Configuration configuration = new Configuration();
12214        Settings.System.getConfiguration(resolver, configuration);
12215        if (forceRtl) {
12216            // This will take care of setting the correct layout direction flags
12217            configuration.setLayoutDirection(configuration.locale);
12218        }
12219
12220        synchronized (this) {
12221            mDebugApp = mOrigDebugApp = debugApp;
12222            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12223            mAlwaysFinishActivities = alwaysFinishActivities;
12224            mForceResizableActivities = forceResizable;
12225            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12226            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12227            // This happens before any activities are started, so we can
12228            // change mConfiguration in-place.
12229            updateConfigurationLocked(configuration, null, true);
12230            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12231                    "Initial config: " + mConfiguration);
12232
12233            // Load resources only after the current configuration has been set.
12234            final Resources res = mContext.getResources();
12235            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12236            mThumbnailWidth = res.getDimensionPixelSize(
12237                    com.android.internal.R.dimen.thumbnail_width);
12238            mThumbnailHeight = res.getDimensionPixelSize(
12239                    com.android.internal.R.dimen.thumbnail_height);
12240            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12241                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12242        }
12243    }
12244
12245    public boolean testIsSystemReady() {
12246        // no need to synchronize(this) just to read & return the value
12247        return mSystemReady;
12248    }
12249
12250    private static File getCalledPreBootReceiversFile() {
12251        File dataDir = Environment.getDataDirectory();
12252        File systemDir = new File(dataDir, "system");
12253        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12254        return fname;
12255    }
12256
12257    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12258        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12259        File file = getCalledPreBootReceiversFile();
12260        FileInputStream fis = null;
12261        try {
12262            fis = new FileInputStream(file);
12263            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12264            int fvers = dis.readInt();
12265            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12266                String vers = dis.readUTF();
12267                String codename = dis.readUTF();
12268                String build = dis.readUTF();
12269                if (android.os.Build.VERSION.RELEASE.equals(vers)
12270                        && android.os.Build.VERSION.CODENAME.equals(codename)
12271                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12272                    int num = dis.readInt();
12273                    while (num > 0) {
12274                        num--;
12275                        String pkg = dis.readUTF();
12276                        String cls = dis.readUTF();
12277                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12278                    }
12279                }
12280            }
12281        } catch (FileNotFoundException e) {
12282        } catch (IOException e) {
12283            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12284        } finally {
12285            if (fis != null) {
12286                try {
12287                    fis.close();
12288                } catch (IOException e) {
12289                }
12290            }
12291        }
12292        return lastDoneReceivers;
12293    }
12294
12295    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12296        File file = getCalledPreBootReceiversFile();
12297        FileOutputStream fos = null;
12298        DataOutputStream dos = null;
12299        try {
12300            fos = new FileOutputStream(file);
12301            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12302            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12303            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12304            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12305            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12306            dos.writeInt(list.size());
12307            for (int i=0; i<list.size(); i++) {
12308                dos.writeUTF(list.get(i).getPackageName());
12309                dos.writeUTF(list.get(i).getClassName());
12310            }
12311        } catch (IOException e) {
12312            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12313            file.delete();
12314        } finally {
12315            FileUtils.sync(fos);
12316            if (dos != null) {
12317                try {
12318                    dos.close();
12319                } catch (IOException e) {
12320                    // TODO Auto-generated catch block
12321                    e.printStackTrace();
12322                }
12323            }
12324        }
12325    }
12326
12327    final class PreBootContinuation extends IIntentReceiver.Stub {
12328        final Intent intent;
12329        final Runnable onFinishCallback;
12330        final ArrayList<ComponentName> doneReceivers;
12331        final List<ResolveInfo> ris;
12332        final int[] users;
12333        int lastRi = -1;
12334        int curRi = 0;
12335        int curUser = 0;
12336
12337        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12338                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12339            intent = _intent;
12340            onFinishCallback = _onFinishCallback;
12341            doneReceivers = _doneReceivers;
12342            ris = _ris;
12343            users = _users;
12344        }
12345
12346        void go() {
12347            if (lastRi != curRi) {
12348                ActivityInfo ai = ris.get(curRi).activityInfo;
12349                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12350                intent.setComponent(comp);
12351                doneReceivers.add(comp);
12352                lastRi = curRi;
12353                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12354                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12355            }
12356            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12357                    + " for user " + users[curUser]);
12358            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12359            broadcastIntentLocked(null, null, intent, null, this,
12360                    0, null, null, null, AppOpsManager.OP_NONE,
12361                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12362        }
12363
12364        public void performReceive(Intent intent, int resultCode,
12365                String data, Bundle extras, boolean ordered,
12366                boolean sticky, int sendingUser) {
12367            curUser++;
12368            if (curUser >= users.length) {
12369                curUser = 0;
12370                curRi++;
12371                if (curRi >= ris.size()) {
12372                    // All done sending broadcasts!
12373                    if (onFinishCallback != null) {
12374                        // The raw IIntentReceiver interface is called
12375                        // with the AM lock held, so redispatch to
12376                        // execute our code without the lock.
12377                        mHandler.post(onFinishCallback);
12378                    }
12379                    return;
12380                }
12381            }
12382            go();
12383        }
12384    }
12385
12386    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12387            ArrayList<ComponentName> doneReceivers) {
12388        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12389        List<ResolveInfo> ris = null;
12390        try {
12391            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12392                    intent, null, 0, UserHandle.USER_SYSTEM);
12393        } catch (RemoteException e) {
12394        }
12395        if (ris == null) {
12396            return false;
12397        }
12398        for (int i=ris.size()-1; i>=0; i--) {
12399            if ((ris.get(i).activityInfo.applicationInfo.flags
12400                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
12401                ris.remove(i);
12402            }
12403        }
12404        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12405
12406        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12407        for (int i=0; i<ris.size(); i++) {
12408            ActivityInfo ai = ris.get(i).activityInfo;
12409            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12410            if (lastDoneReceivers.contains(comp)) {
12411                // We already did the pre boot receiver for this app with the current
12412                // platform version, so don't do it again...
12413                ris.remove(i);
12414                i--;
12415                // ...however, do keep it as one that has been done, so we don't
12416                // forget about it when rewriting the file of last done receivers.
12417                doneReceivers.add(comp);
12418            }
12419        }
12420
12421        if (ris.size() <= 0) {
12422            return false;
12423        }
12424
12425        // TODO: can we still do this with per user encryption?
12426        final int[] users = mUserController.getUsers();
12427        if (users.length <= 0) {
12428            return false;
12429        }
12430
12431        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12432                ris, users);
12433        cont.go();
12434        return true;
12435    }
12436
12437    public void systemReady(final Runnable goingCallback) {
12438        synchronized(this) {
12439            if (mSystemReady) {
12440                // If we're done calling all the receivers, run the next "boot phase" passed in
12441                // by the SystemServer
12442                if (goingCallback != null) {
12443                    goingCallback.run();
12444                }
12445                return;
12446            }
12447
12448            mLocalDeviceIdleController
12449                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12450
12451            // Make sure we have the current profile info, since it is needed for
12452            // security checks.
12453            mUserController.updateCurrentProfileIdsLocked();
12454
12455            mRecentTasks.clear();
12456            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12457            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12458            mTaskPersister.startPersisting();
12459
12460            // Check to see if there are any update receivers to run.
12461            if (!mDidUpdate) {
12462                if (mWaitingUpdate) {
12463                    return;
12464                }
12465                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12466                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12467                    public void run() {
12468                        synchronized (ActivityManagerService.this) {
12469                            mDidUpdate = true;
12470                        }
12471                        showBootMessage(mContext.getText(
12472                                R.string.android_upgrading_complete),
12473                                false);
12474                        writeLastDonePreBootReceivers(doneReceivers);
12475                        systemReady(goingCallback);
12476                    }
12477                }, doneReceivers);
12478
12479                if (mWaitingUpdate) {
12480                    return;
12481                }
12482                mDidUpdate = true;
12483            }
12484
12485            mAppOpsService.systemReady();
12486            mSystemReady = true;
12487        }
12488
12489        ArrayList<ProcessRecord> procsToKill = null;
12490        synchronized(mPidsSelfLocked) {
12491            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12492                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12493                if (!isAllowedWhileBooting(proc.info)){
12494                    if (procsToKill == null) {
12495                        procsToKill = new ArrayList<ProcessRecord>();
12496                    }
12497                    procsToKill.add(proc);
12498                }
12499            }
12500        }
12501
12502        synchronized(this) {
12503            if (procsToKill != null) {
12504                for (int i=procsToKill.size()-1; i>=0; i--) {
12505                    ProcessRecord proc = procsToKill.get(i);
12506                    Slog.i(TAG, "Removing system update proc: " + proc);
12507                    removeProcessLocked(proc, true, false, "system update done");
12508                }
12509            }
12510
12511            // Now that we have cleaned up any update processes, we
12512            // are ready to start launching real processes and know that
12513            // we won't trample on them any more.
12514            mProcessesReady = true;
12515        }
12516
12517        Slog.i(TAG, "System now ready");
12518        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12519            SystemClock.uptimeMillis());
12520
12521        synchronized(this) {
12522            // Make sure we have no pre-ready processes sitting around.
12523
12524            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12525                ResolveInfo ri = mContext.getPackageManager()
12526                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12527                                STOCK_PM_FLAGS);
12528                CharSequence errorMsg = null;
12529                if (ri != null) {
12530                    ActivityInfo ai = ri.activityInfo;
12531                    ApplicationInfo app = ai.applicationInfo;
12532                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12533                        mTopAction = Intent.ACTION_FACTORY_TEST;
12534                        mTopData = null;
12535                        mTopComponent = new ComponentName(app.packageName,
12536                                ai.name);
12537                    } else {
12538                        errorMsg = mContext.getResources().getText(
12539                                com.android.internal.R.string.factorytest_not_system);
12540                    }
12541                } else {
12542                    errorMsg = mContext.getResources().getText(
12543                            com.android.internal.R.string.factorytest_no_action);
12544                }
12545                if (errorMsg != null) {
12546                    mTopAction = null;
12547                    mTopData = null;
12548                    mTopComponent = null;
12549                    Message msg = Message.obtain();
12550                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12551                    msg.getData().putCharSequence("msg", errorMsg);
12552                    mUiHandler.sendMessage(msg);
12553                }
12554            }
12555        }
12556
12557        retrieveSettings();
12558        final int currentUserId;
12559        synchronized (this) {
12560            currentUserId = mUserController.getCurrentUserIdLocked();
12561            readGrantedUriPermissionsLocked();
12562        }
12563
12564        if (goingCallback != null) goingCallback.run();
12565
12566
12567        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12568                Integer.toString(currentUserId), currentUserId);
12569        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12570                Integer.toString(currentUserId), currentUserId);
12571        mSystemServiceManager.startUser(currentUserId);
12572
12573        synchronized (this) {
12574            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12575                try {
12576                    List apps = AppGlobals.getPackageManager().
12577                        getPersistentApplications(STOCK_PM_FLAGS);
12578                    if (apps != null) {
12579                        int N = apps.size();
12580                        int i;
12581                        for (i=0; i<N; i++) {
12582                            ApplicationInfo info
12583                                = (ApplicationInfo)apps.get(i);
12584                            if (info != null &&
12585                                    !info.packageName.equals("android")) {
12586                                addAppLocked(info, false, null /* ABI override */);
12587                            }
12588                        }
12589                    }
12590                } catch (RemoteException ex) {
12591                    // pm is in same process, this will never happen.
12592                }
12593            }
12594
12595            // Start up initial activity.
12596            mBooting = true;
12597            // Enable home activity for system user, so that the system can always boot
12598            if (UserManager.isSplitSystemUser()) {
12599                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12600                try {
12601                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12602                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12603                            UserHandle.USER_SYSTEM);
12604                } catch (RemoteException e) {
12605                    e.rethrowAsRuntimeException();
12606                }
12607            }
12608            startHomeActivityLocked(currentUserId, "systemReady");
12609
12610            try {
12611                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12612                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12613                            + " data partition or your device will be unstable.");
12614                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12615                }
12616            } catch (RemoteException e) {
12617            }
12618
12619            if (!Build.isBuildConsistent()) {
12620                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12621                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12622            }
12623
12624            long ident = Binder.clearCallingIdentity();
12625            try {
12626                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12627                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12628                        | Intent.FLAG_RECEIVER_FOREGROUND);
12629                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12630                broadcastIntentLocked(null, null, intent,
12631                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12632                        null, false, false, MY_PID, Process.SYSTEM_UID,
12633                        currentUserId);
12634                intent = new Intent(Intent.ACTION_USER_STARTING);
12635                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12636                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12637                broadcastIntentLocked(null, null, intent,
12638                        null, new IIntentReceiver.Stub() {
12639                            @Override
12640                            public void performReceive(Intent intent, int resultCode, String data,
12641                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12642                                    throws RemoteException {
12643                            }
12644                        }, 0, null, null,
12645                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12646                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12647            } catch (Throwable t) {
12648                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12649            } finally {
12650                Binder.restoreCallingIdentity(ident);
12651            }
12652            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12653            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12654        }
12655    }
12656
12657    private boolean makeAppCrashingLocked(ProcessRecord app,
12658            String shortMsg, String longMsg, String stackTrace) {
12659        app.crashing = true;
12660        app.crashingReport = generateProcessError(app,
12661                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12662        startAppProblemLocked(app);
12663        app.stopFreezingAllLocked();
12664        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12665    }
12666
12667    private void makeAppNotRespondingLocked(ProcessRecord app,
12668            String activity, String shortMsg, String longMsg) {
12669        app.notResponding = true;
12670        app.notRespondingReport = generateProcessError(app,
12671                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12672                activity, shortMsg, longMsg, null);
12673        startAppProblemLocked(app);
12674        app.stopFreezingAllLocked();
12675    }
12676
12677    /**
12678     * Generate a process error record, suitable for attachment to a ProcessRecord.
12679     *
12680     * @param app The ProcessRecord in which the error occurred.
12681     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12682     *                      ActivityManager.AppErrorStateInfo
12683     * @param activity The activity associated with the crash, if known.
12684     * @param shortMsg Short message describing the crash.
12685     * @param longMsg Long message describing the crash.
12686     * @param stackTrace Full crash stack trace, may be null.
12687     *
12688     * @return Returns a fully-formed AppErrorStateInfo record.
12689     */
12690    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12691            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12692        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12693
12694        report.condition = condition;
12695        report.processName = app.processName;
12696        report.pid = app.pid;
12697        report.uid = app.info.uid;
12698        report.tag = activity;
12699        report.shortMsg = shortMsg;
12700        report.longMsg = longMsg;
12701        report.stackTrace = stackTrace;
12702
12703        return report;
12704    }
12705
12706    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12707        synchronized (this) {
12708            app.crashing = false;
12709            app.crashingReport = null;
12710            app.notResponding = false;
12711            app.notRespondingReport = null;
12712            if (app.anrDialog == fromDialog) {
12713                app.anrDialog = null;
12714            }
12715            if (app.waitDialog == fromDialog) {
12716                app.waitDialog = null;
12717            }
12718            if (app.pid > 0 && app.pid != MY_PID) {
12719                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12720                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12721                app.kill("user request after error", true);
12722            }
12723        }
12724    }
12725
12726    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12727            String shortMsg, String longMsg, String stackTrace) {
12728        long now = SystemClock.uptimeMillis();
12729
12730        Long crashTime;
12731        if (!app.isolated) {
12732            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12733        } else {
12734            crashTime = null;
12735        }
12736        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12737            // This process loses!
12738            Slog.w(TAG, "Process " + app.info.processName
12739                    + " has crashed too many times: killing!");
12740            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12741                    app.userId, app.info.processName, app.uid);
12742            mStackSupervisor.handleAppCrashLocked(app);
12743            if (!app.persistent) {
12744                // We don't want to start this process again until the user
12745                // explicitly does so...  but for persistent process, we really
12746                // need to keep it running.  If a persistent process is actually
12747                // repeatedly crashing, then badness for everyone.
12748                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12749                        app.info.processName);
12750                if (!app.isolated) {
12751                    // XXX We don't have a way to mark isolated processes
12752                    // as bad, since they don't have a peristent identity.
12753                    mBadProcesses.put(app.info.processName, app.uid,
12754                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12755                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12756                }
12757                app.bad = true;
12758                app.removed = true;
12759                // Don't let services in this process be restarted and potentially
12760                // annoy the user repeatedly.  Unless it is persistent, since those
12761                // processes run critical code.
12762                removeProcessLocked(app, false, false, "crash");
12763                mStackSupervisor.resumeFocusedStackTopActivityLocked();
12764                return false;
12765            }
12766            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12767        } else {
12768            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12769        }
12770
12771        // Bump up the crash count of any services currently running in the proc.
12772        for (int i=app.services.size()-1; i>=0; i--) {
12773            // Any services running in the application need to be placed
12774            // back in the pending list.
12775            ServiceRecord sr = app.services.valueAt(i);
12776            sr.crashCount++;
12777        }
12778
12779        // If the crashing process is what we consider to be the "home process" and it has been
12780        // replaced by a third-party app, clear the package preferred activities from packages
12781        // with a home activity running in the process to prevent a repeatedly crashing app
12782        // from blocking the user to manually clear the list.
12783        final ArrayList<ActivityRecord> activities = app.activities;
12784        if (app == mHomeProcess && activities.size() > 0
12785                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12786            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12787                final ActivityRecord r = activities.get(activityNdx);
12788                if (r.isHomeActivity()) {
12789                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12790                    try {
12791                        ActivityThread.getPackageManager()
12792                                .clearPackagePreferredActivities(r.packageName);
12793                    } catch (RemoteException c) {
12794                        // pm is in same process, this will never happen.
12795                    }
12796                }
12797            }
12798        }
12799
12800        if (!app.isolated) {
12801            // XXX Can't keep track of crash times for isolated processes,
12802            // because they don't have a perisistent identity.
12803            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12804        }
12805
12806        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12807        return true;
12808    }
12809
12810    void startAppProblemLocked(ProcessRecord app) {
12811        // If this app is not running under the current user, then we
12812        // can't give it a report button because that would require
12813        // launching the report UI under a different user.
12814        app.errorReportReceiver = null;
12815
12816        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12817            if (app.userId == userId) {
12818                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12819                        mContext, app.info.packageName, app.info.flags);
12820            }
12821        }
12822        skipCurrentReceiverLocked(app);
12823    }
12824
12825    void skipCurrentReceiverLocked(ProcessRecord app) {
12826        for (BroadcastQueue queue : mBroadcastQueues) {
12827            queue.skipCurrentReceiverLocked(app);
12828        }
12829    }
12830
12831    /**
12832     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12833     * The application process will exit immediately after this call returns.
12834     * @param app object of the crashing app, null for the system server
12835     * @param crashInfo describing the exception
12836     */
12837    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12838        ProcessRecord r = findAppProcess(app, "Crash");
12839        final String processName = app == null ? "system_server"
12840                : (r == null ? "unknown" : r.processName);
12841
12842        handleApplicationCrashInner("crash", r, processName, crashInfo);
12843    }
12844
12845    /* Native crash reporting uses this inner version because it needs to be somewhat
12846     * decoupled from the AM-managed cleanup lifecycle
12847     */
12848    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12849            ApplicationErrorReport.CrashInfo crashInfo) {
12850        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12851                UserHandle.getUserId(Binder.getCallingUid()), processName,
12852                r == null ? -1 : r.info.flags,
12853                crashInfo.exceptionClassName,
12854                crashInfo.exceptionMessage,
12855                crashInfo.throwFileName,
12856                crashInfo.throwLineNumber);
12857
12858        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12859
12860        crashApplication(r, crashInfo);
12861    }
12862
12863    public void handleApplicationStrictModeViolation(
12864            IBinder app,
12865            int violationMask,
12866            StrictMode.ViolationInfo info) {
12867        ProcessRecord r = findAppProcess(app, "StrictMode");
12868        if (r == null) {
12869            return;
12870        }
12871
12872        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12873            Integer stackFingerprint = info.hashCode();
12874            boolean logIt = true;
12875            synchronized (mAlreadyLoggedViolatedStacks) {
12876                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12877                    logIt = false;
12878                    // TODO: sub-sample into EventLog for these, with
12879                    // the info.durationMillis?  Then we'd get
12880                    // the relative pain numbers, without logging all
12881                    // the stack traces repeatedly.  We'd want to do
12882                    // likewise in the client code, which also does
12883                    // dup suppression, before the Binder call.
12884                } else {
12885                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12886                        mAlreadyLoggedViolatedStacks.clear();
12887                    }
12888                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12889                }
12890            }
12891            if (logIt) {
12892                logStrictModeViolationToDropBox(r, info);
12893            }
12894        }
12895
12896        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12897            AppErrorResult result = new AppErrorResult();
12898            synchronized (this) {
12899                final long origId = Binder.clearCallingIdentity();
12900
12901                Message msg = Message.obtain();
12902                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12903                HashMap<String, Object> data = new HashMap<String, Object>();
12904                data.put("result", result);
12905                data.put("app", r);
12906                data.put("violationMask", violationMask);
12907                data.put("info", info);
12908                msg.obj = data;
12909                mUiHandler.sendMessage(msg);
12910
12911                Binder.restoreCallingIdentity(origId);
12912            }
12913            int res = result.get();
12914            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12915        }
12916    }
12917
12918    // Depending on the policy in effect, there could be a bunch of
12919    // these in quick succession so we try to batch these together to
12920    // minimize disk writes, number of dropbox entries, and maximize
12921    // compression, by having more fewer, larger records.
12922    private void logStrictModeViolationToDropBox(
12923            ProcessRecord process,
12924            StrictMode.ViolationInfo info) {
12925        if (info == null) {
12926            return;
12927        }
12928        final boolean isSystemApp = process == null ||
12929                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12930                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12931        final String processName = process == null ? "unknown" : process.processName;
12932        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12933        final DropBoxManager dbox = (DropBoxManager)
12934                mContext.getSystemService(Context.DROPBOX_SERVICE);
12935
12936        // Exit early if the dropbox isn't configured to accept this report type.
12937        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12938
12939        boolean bufferWasEmpty;
12940        boolean needsFlush;
12941        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12942        synchronized (sb) {
12943            bufferWasEmpty = sb.length() == 0;
12944            appendDropBoxProcessHeaders(process, processName, sb);
12945            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12946            sb.append("System-App: ").append(isSystemApp).append("\n");
12947            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12948            if (info.violationNumThisLoop != 0) {
12949                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12950            }
12951            if (info.numAnimationsRunning != 0) {
12952                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12953            }
12954            if (info.broadcastIntentAction != null) {
12955                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12956            }
12957            if (info.durationMillis != -1) {
12958                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12959            }
12960            if (info.numInstances != -1) {
12961                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12962            }
12963            if (info.tags != null) {
12964                for (String tag : info.tags) {
12965                    sb.append("Span-Tag: ").append(tag).append("\n");
12966                }
12967            }
12968            sb.append("\n");
12969            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12970                sb.append(info.crashInfo.stackTrace);
12971                sb.append("\n");
12972            }
12973            if (info.message != null) {
12974                sb.append(info.message);
12975                sb.append("\n");
12976            }
12977
12978            // Only buffer up to ~64k.  Various logging bits truncate
12979            // things at 128k.
12980            needsFlush = (sb.length() > 64 * 1024);
12981        }
12982
12983        // Flush immediately if the buffer's grown too large, or this
12984        // is a non-system app.  Non-system apps are isolated with a
12985        // different tag & policy and not batched.
12986        //
12987        // Batching is useful during internal testing with
12988        // StrictMode settings turned up high.  Without batching,
12989        // thousands of separate files could be created on boot.
12990        if (!isSystemApp || needsFlush) {
12991            new Thread("Error dump: " + dropboxTag) {
12992                @Override
12993                public void run() {
12994                    String report;
12995                    synchronized (sb) {
12996                        report = sb.toString();
12997                        sb.delete(0, sb.length());
12998                        sb.trimToSize();
12999                    }
13000                    if (report.length() != 0) {
13001                        dbox.addText(dropboxTag, report);
13002                    }
13003                }
13004            }.start();
13005            return;
13006        }
13007
13008        // System app batching:
13009        if (!bufferWasEmpty) {
13010            // An existing dropbox-writing thread is outstanding, so
13011            // we don't need to start it up.  The existing thread will
13012            // catch the buffer appends we just did.
13013            return;
13014        }
13015
13016        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13017        // (After this point, we shouldn't access AMS internal data structures.)
13018        new Thread("Error dump: " + dropboxTag) {
13019            @Override
13020            public void run() {
13021                // 5 second sleep to let stacks arrive and be batched together
13022                try {
13023                    Thread.sleep(5000);  // 5 seconds
13024                } catch (InterruptedException e) {}
13025
13026                String errorReport;
13027                synchronized (mStrictModeBuffer) {
13028                    errorReport = mStrictModeBuffer.toString();
13029                    if (errorReport.length() == 0) {
13030                        return;
13031                    }
13032                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13033                    mStrictModeBuffer.trimToSize();
13034                }
13035                dbox.addText(dropboxTag, errorReport);
13036            }
13037        }.start();
13038    }
13039
13040    /**
13041     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13042     * @param app object of the crashing app, null for the system server
13043     * @param tag reported by the caller
13044     * @param system whether this wtf is coming from the system
13045     * @param crashInfo describing the context of the error
13046     * @return true if the process should exit immediately (WTF is fatal)
13047     */
13048    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13049            final ApplicationErrorReport.CrashInfo crashInfo) {
13050        final int callingUid = Binder.getCallingUid();
13051        final int callingPid = Binder.getCallingPid();
13052
13053        if (system) {
13054            // If this is coming from the system, we could very well have low-level
13055            // system locks held, so we want to do this all asynchronously.  And we
13056            // never want this to become fatal, so there is that too.
13057            mHandler.post(new Runnable() {
13058                @Override public void run() {
13059                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13060                }
13061            });
13062            return false;
13063        }
13064
13065        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13066                crashInfo);
13067
13068        if (r != null && r.pid != Process.myPid() &&
13069                Settings.Global.getInt(mContext.getContentResolver(),
13070                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13071            crashApplication(r, crashInfo);
13072            return true;
13073        } else {
13074            return false;
13075        }
13076    }
13077
13078    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13079            final ApplicationErrorReport.CrashInfo crashInfo) {
13080        final ProcessRecord r = findAppProcess(app, "WTF");
13081        final String processName = app == null ? "system_server"
13082                : (r == null ? "unknown" : r.processName);
13083
13084        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13085                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13086
13087        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13088
13089        return r;
13090    }
13091
13092    /**
13093     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13094     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13095     */
13096    private ProcessRecord findAppProcess(IBinder app, String reason) {
13097        if (app == null) {
13098            return null;
13099        }
13100
13101        synchronized (this) {
13102            final int NP = mProcessNames.getMap().size();
13103            for (int ip=0; ip<NP; ip++) {
13104                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13105                final int NA = apps.size();
13106                for (int ia=0; ia<NA; ia++) {
13107                    ProcessRecord p = apps.valueAt(ia);
13108                    if (p.thread != null && p.thread.asBinder() == app) {
13109                        return p;
13110                    }
13111                }
13112            }
13113
13114            Slog.w(TAG, "Can't find mystery application for " + reason
13115                    + " from pid=" + Binder.getCallingPid()
13116                    + " uid=" + Binder.getCallingUid() + ": " + app);
13117            return null;
13118        }
13119    }
13120
13121    /**
13122     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13123     * to append various headers to the dropbox log text.
13124     */
13125    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13126            StringBuilder sb) {
13127        // Watchdog thread ends up invoking this function (with
13128        // a null ProcessRecord) to add the stack file to dropbox.
13129        // Do not acquire a lock on this (am) in such cases, as it
13130        // could cause a potential deadlock, if and when watchdog
13131        // is invoked due to unavailability of lock on am and it
13132        // would prevent watchdog from killing system_server.
13133        if (process == null) {
13134            sb.append("Process: ").append(processName).append("\n");
13135            return;
13136        }
13137        // Note: ProcessRecord 'process' is guarded by the service
13138        // instance.  (notably process.pkgList, which could otherwise change
13139        // concurrently during execution of this method)
13140        synchronized (this) {
13141            sb.append("Process: ").append(processName).append("\n");
13142            int flags = process.info.flags;
13143            IPackageManager pm = AppGlobals.getPackageManager();
13144            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13145            for (int ip=0; ip<process.pkgList.size(); ip++) {
13146                String pkg = process.pkgList.keyAt(ip);
13147                sb.append("Package: ").append(pkg);
13148                try {
13149                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13150                    if (pi != null) {
13151                        sb.append(" v").append(pi.versionCode);
13152                        if (pi.versionName != null) {
13153                            sb.append(" (").append(pi.versionName).append(")");
13154                        }
13155                    }
13156                } catch (RemoteException e) {
13157                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13158                }
13159                sb.append("\n");
13160            }
13161        }
13162    }
13163
13164    private static String processClass(ProcessRecord process) {
13165        if (process == null || process.pid == MY_PID) {
13166            return "system_server";
13167        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13168            return "system_app";
13169        } else {
13170            return "data_app";
13171        }
13172    }
13173
13174    /**
13175     * Write a description of an error (crash, WTF, ANR) to the drop box.
13176     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13177     * @param process which caused the error, null means the system server
13178     * @param activity which triggered the error, null if unknown
13179     * @param parent activity related to the error, null if unknown
13180     * @param subject line related to the error, null if absent
13181     * @param report in long form describing the error, null if absent
13182     * @param logFile to include in the report, null if none
13183     * @param crashInfo giving an application stack trace, null if absent
13184     */
13185    public void addErrorToDropBox(String eventType,
13186            ProcessRecord process, String processName, ActivityRecord activity,
13187            ActivityRecord parent, String subject,
13188            final String report, final File logFile,
13189            final ApplicationErrorReport.CrashInfo crashInfo) {
13190        // NOTE -- this must never acquire the ActivityManagerService lock,
13191        // otherwise the watchdog may be prevented from resetting the system.
13192
13193        final String dropboxTag = processClass(process) + "_" + eventType;
13194        final DropBoxManager dbox = (DropBoxManager)
13195                mContext.getSystemService(Context.DROPBOX_SERVICE);
13196
13197        // Exit early if the dropbox isn't configured to accept this report type.
13198        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13199
13200        final StringBuilder sb = new StringBuilder(1024);
13201        appendDropBoxProcessHeaders(process, processName, sb);
13202        if (activity != null) {
13203            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13204        }
13205        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13206            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13207        }
13208        if (parent != null && parent != activity) {
13209            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13210        }
13211        if (subject != null) {
13212            sb.append("Subject: ").append(subject).append("\n");
13213        }
13214        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13215        if (Debug.isDebuggerConnected()) {
13216            sb.append("Debugger: Connected\n");
13217        }
13218        sb.append("\n");
13219
13220        // Do the rest in a worker thread to avoid blocking the caller on I/O
13221        // (After this point, we shouldn't access AMS internal data structures.)
13222        Thread worker = new Thread("Error dump: " + dropboxTag) {
13223            @Override
13224            public void run() {
13225                if (report != null) {
13226                    sb.append(report);
13227                }
13228                if (logFile != null) {
13229                    try {
13230                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13231                                    "\n\n[[TRUNCATED]]"));
13232                    } catch (IOException e) {
13233                        Slog.e(TAG, "Error reading " + logFile, e);
13234                    }
13235                }
13236                if (crashInfo != null && crashInfo.stackTrace != null) {
13237                    sb.append(crashInfo.stackTrace);
13238                }
13239
13240                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13241                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13242                if (lines > 0) {
13243                    sb.append("\n");
13244
13245                    // Merge several logcat streams, and take the last N lines
13246                    InputStreamReader input = null;
13247                    try {
13248                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13249                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13250                                "-b", "crash",
13251                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13252
13253                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13254                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13255                        input = new InputStreamReader(logcat.getInputStream());
13256
13257                        int num;
13258                        char[] buf = new char[8192];
13259                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13260                    } catch (IOException e) {
13261                        Slog.e(TAG, "Error running logcat", e);
13262                    } finally {
13263                        if (input != null) try { input.close(); } catch (IOException e) {}
13264                    }
13265                }
13266
13267                dbox.addText(dropboxTag, sb.toString());
13268            }
13269        };
13270
13271        if (process == null) {
13272            // If process is null, we are being called from some internal code
13273            // and may be about to die -- run this synchronously.
13274            worker.run();
13275        } else {
13276            worker.start();
13277        }
13278    }
13279
13280    /**
13281     * Bring up the "unexpected error" dialog box for a crashing app.
13282     * Deal with edge cases (intercepts from instrumented applications,
13283     * ActivityController, error intent receivers, that sort of thing).
13284     * @param r the application crashing
13285     * @param crashInfo describing the failure
13286     */
13287    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13288        long timeMillis = System.currentTimeMillis();
13289        String shortMsg = crashInfo.exceptionClassName;
13290        String longMsg = crashInfo.exceptionMessage;
13291        String stackTrace = crashInfo.stackTrace;
13292        if (shortMsg != null && longMsg != null) {
13293            longMsg = shortMsg + ": " + longMsg;
13294        } else if (shortMsg != null) {
13295            longMsg = shortMsg;
13296        }
13297
13298        AppErrorResult result = new AppErrorResult();
13299        synchronized (this) {
13300            if (mController != null) {
13301                try {
13302                    String name = r != null ? r.processName : null;
13303                    int pid = r != null ? r.pid : Binder.getCallingPid();
13304                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13305                    if (!mController.appCrashed(name, pid,
13306                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13307                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13308                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13309                            Slog.w(TAG, "Skip killing native crashed app " + name
13310                                    + "(" + pid + ") during testing");
13311                        } else {
13312                            Slog.w(TAG, "Force-killing crashed app " + name
13313                                    + " at watcher's request");
13314                            if (r != null) {
13315                                r.kill("crash", true);
13316                            } else {
13317                                // Huh.
13318                                Process.killProcess(pid);
13319                                killProcessGroup(uid, pid);
13320                            }
13321                        }
13322                        return;
13323                    }
13324                } catch (RemoteException e) {
13325                    mController = null;
13326                    Watchdog.getInstance().setActivityController(null);
13327                }
13328            }
13329
13330            final long origId = Binder.clearCallingIdentity();
13331
13332            // If this process is running instrumentation, finish it.
13333            if (r != null && r.instrumentationClass != null) {
13334                Slog.w(TAG, "Error in app " + r.processName
13335                      + " running instrumentation " + r.instrumentationClass + ":");
13336                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13337                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13338                Bundle info = new Bundle();
13339                info.putString("shortMsg", shortMsg);
13340                info.putString("longMsg", longMsg);
13341                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13342                Binder.restoreCallingIdentity(origId);
13343                return;
13344            }
13345
13346            // Log crash in battery stats.
13347            if (r != null) {
13348                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13349            }
13350
13351            // If we can't identify the process or it's already exceeded its crash quota,
13352            // quit right away without showing a crash dialog.
13353            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13354                Binder.restoreCallingIdentity(origId);
13355                return;
13356            }
13357
13358            Message msg = Message.obtain();
13359            msg.what = SHOW_ERROR_UI_MSG;
13360            HashMap data = new HashMap();
13361            data.put("result", result);
13362            data.put("app", r);
13363            msg.obj = data;
13364            mUiHandler.sendMessage(msg);
13365
13366            Binder.restoreCallingIdentity(origId);
13367        }
13368
13369        int res = result.get();
13370
13371        Intent appErrorIntent = null;
13372        synchronized (this) {
13373            if (r != null && !r.isolated) {
13374                // XXX Can't keep track of crash time for isolated processes,
13375                // since they don't have a persistent identity.
13376                mProcessCrashTimes.put(r.info.processName, r.uid,
13377                        SystemClock.uptimeMillis());
13378            }
13379            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13380                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13381            }
13382        }
13383
13384        if (appErrorIntent != null) {
13385            try {
13386                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13387            } catch (ActivityNotFoundException e) {
13388                Slog.w(TAG, "bug report receiver dissappeared", e);
13389            }
13390        }
13391    }
13392
13393    Intent createAppErrorIntentLocked(ProcessRecord r,
13394            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13395        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13396        if (report == null) {
13397            return null;
13398        }
13399        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13400        result.setComponent(r.errorReportReceiver);
13401        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13402        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13403        return result;
13404    }
13405
13406    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13407            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13408        if (r.errorReportReceiver == null) {
13409            return null;
13410        }
13411
13412        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13413            return null;
13414        }
13415
13416        ApplicationErrorReport report = new ApplicationErrorReport();
13417        report.packageName = r.info.packageName;
13418        report.installerPackageName = r.errorReportReceiver.getPackageName();
13419        report.processName = r.processName;
13420        report.time = timeMillis;
13421        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13422
13423        if (r.crashing || r.forceCrashReport) {
13424            report.type = ApplicationErrorReport.TYPE_CRASH;
13425            report.crashInfo = crashInfo;
13426        } else if (r.notResponding) {
13427            report.type = ApplicationErrorReport.TYPE_ANR;
13428            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13429
13430            report.anrInfo.activity = r.notRespondingReport.tag;
13431            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13432            report.anrInfo.info = r.notRespondingReport.longMsg;
13433        }
13434
13435        return report;
13436    }
13437
13438    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13439        enforceNotIsolatedCaller("getProcessesInErrorState");
13440        // assume our apps are happy - lazy create the list
13441        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13442
13443        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13444                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13445        int userId = UserHandle.getUserId(Binder.getCallingUid());
13446
13447        synchronized (this) {
13448
13449            // iterate across all processes
13450            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13451                ProcessRecord app = mLruProcesses.get(i);
13452                if (!allUsers && app.userId != userId) {
13453                    continue;
13454                }
13455                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13456                    // This one's in trouble, so we'll generate a report for it
13457                    // crashes are higher priority (in case there's a crash *and* an anr)
13458                    ActivityManager.ProcessErrorStateInfo report = null;
13459                    if (app.crashing) {
13460                        report = app.crashingReport;
13461                    } else if (app.notResponding) {
13462                        report = app.notRespondingReport;
13463                    }
13464
13465                    if (report != null) {
13466                        if (errList == null) {
13467                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13468                        }
13469                        errList.add(report);
13470                    } else {
13471                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13472                                " crashing = " + app.crashing +
13473                                " notResponding = " + app.notResponding);
13474                    }
13475                }
13476            }
13477        }
13478
13479        return errList;
13480    }
13481
13482    static int procStateToImportance(int procState, int memAdj,
13483            ActivityManager.RunningAppProcessInfo currApp) {
13484        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13485        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13486            currApp.lru = memAdj;
13487        } else {
13488            currApp.lru = 0;
13489        }
13490        return imp;
13491    }
13492
13493    private void fillInProcMemInfo(ProcessRecord app,
13494            ActivityManager.RunningAppProcessInfo outInfo) {
13495        outInfo.pid = app.pid;
13496        outInfo.uid = app.info.uid;
13497        if (mHeavyWeightProcess == app) {
13498            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13499        }
13500        if (app.persistent) {
13501            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13502        }
13503        if (app.activities.size() > 0) {
13504            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13505        }
13506        outInfo.lastTrimLevel = app.trimMemoryLevel;
13507        int adj = app.curAdj;
13508        int procState = app.curProcState;
13509        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13510        outInfo.importanceReasonCode = app.adjTypeCode;
13511        outInfo.processState = app.curProcState;
13512    }
13513
13514    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13515        enforceNotIsolatedCaller("getRunningAppProcesses");
13516
13517        final int callingUid = Binder.getCallingUid();
13518
13519        // Lazy instantiation of list
13520        List<ActivityManager.RunningAppProcessInfo> runList = null;
13521        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13522                callingUid) == PackageManager.PERMISSION_GRANTED;
13523        final int userId = UserHandle.getUserId(callingUid);
13524        final boolean allUids = isGetTasksAllowed(
13525                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13526
13527        synchronized (this) {
13528            // Iterate across all processes
13529            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13530                ProcessRecord app = mLruProcesses.get(i);
13531                if ((!allUsers && app.userId != userId)
13532                        || (!allUids && app.uid != callingUid)) {
13533                    continue;
13534                }
13535                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13536                    // Generate process state info for running application
13537                    ActivityManager.RunningAppProcessInfo currApp =
13538                        new ActivityManager.RunningAppProcessInfo(app.processName,
13539                                app.pid, app.getPackageList());
13540                    fillInProcMemInfo(app, currApp);
13541                    if (app.adjSource instanceof ProcessRecord) {
13542                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13543                        currApp.importanceReasonImportance =
13544                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13545                                        app.adjSourceProcState);
13546                    } else if (app.adjSource instanceof ActivityRecord) {
13547                        ActivityRecord r = (ActivityRecord)app.adjSource;
13548                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13549                    }
13550                    if (app.adjTarget instanceof ComponentName) {
13551                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13552                    }
13553                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13554                    //        + " lru=" + currApp.lru);
13555                    if (runList == null) {
13556                        runList = new ArrayList<>();
13557                    }
13558                    runList.add(currApp);
13559                }
13560            }
13561        }
13562        return runList;
13563    }
13564
13565    public List<ApplicationInfo> getRunningExternalApplications() {
13566        enforceNotIsolatedCaller("getRunningExternalApplications");
13567        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13568        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13569        if (runningApps != null && runningApps.size() > 0) {
13570            Set<String> extList = new HashSet<String>();
13571            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13572                if (app.pkgList != null) {
13573                    for (String pkg : app.pkgList) {
13574                        extList.add(pkg);
13575                    }
13576                }
13577            }
13578            IPackageManager pm = AppGlobals.getPackageManager();
13579            for (String pkg : extList) {
13580                try {
13581                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13582                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13583                        retList.add(info);
13584                    }
13585                } catch (RemoteException e) {
13586                }
13587            }
13588        }
13589        return retList;
13590    }
13591
13592    @Override
13593    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13594        enforceNotIsolatedCaller("getMyMemoryState");
13595        synchronized (this) {
13596            ProcessRecord proc;
13597            synchronized (mPidsSelfLocked) {
13598                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13599            }
13600            fillInProcMemInfo(proc, outInfo);
13601        }
13602    }
13603
13604    @Override
13605    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13606            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13607        (new ActivityManagerShellCommand(this, false)).exec(
13608                this, in, out, err, args, resultReceiver);
13609    }
13610
13611    @Override
13612    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13613        if (checkCallingPermission(android.Manifest.permission.DUMP)
13614                != PackageManager.PERMISSION_GRANTED) {
13615            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13616                    + Binder.getCallingPid()
13617                    + ", uid=" + Binder.getCallingUid()
13618                    + " without permission "
13619                    + android.Manifest.permission.DUMP);
13620            return;
13621        }
13622
13623        boolean dumpAll = false;
13624        boolean dumpClient = false;
13625        String dumpPackage = null;
13626
13627        int opti = 0;
13628        while (opti < args.length) {
13629            String opt = args[opti];
13630            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13631                break;
13632            }
13633            opti++;
13634            if ("-a".equals(opt)) {
13635                dumpAll = true;
13636            } else if ("-c".equals(opt)) {
13637                dumpClient = true;
13638            } else if ("-p".equals(opt)) {
13639                if (opti < args.length) {
13640                    dumpPackage = args[opti];
13641                    opti++;
13642                } else {
13643                    pw.println("Error: -p option requires package argument");
13644                    return;
13645                }
13646                dumpClient = true;
13647            } else if ("-h".equals(opt)) {
13648                ActivityManagerShellCommand.dumpHelp(pw, true);
13649                return;
13650            } else {
13651                pw.println("Unknown argument: " + opt + "; use -h for help");
13652            }
13653        }
13654
13655        long origId = Binder.clearCallingIdentity();
13656        boolean more = false;
13657        // Is the caller requesting to dump a particular piece of data?
13658        if (opti < args.length) {
13659            String cmd = args[opti];
13660            opti++;
13661            if ("activities".equals(cmd) || "a".equals(cmd)) {
13662                synchronized (this) {
13663                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13664                }
13665            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13666                synchronized (this) {
13667                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13668                }
13669            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13670                String[] newArgs;
13671                String name;
13672                if (opti >= args.length) {
13673                    name = null;
13674                    newArgs = EMPTY_STRING_ARRAY;
13675                } else {
13676                    dumpPackage = args[opti];
13677                    opti++;
13678                    newArgs = new String[args.length - opti];
13679                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13680                            args.length - opti);
13681                }
13682                synchronized (this) {
13683                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13684                }
13685            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13686                String[] newArgs;
13687                String name;
13688                if (opti >= args.length) {
13689                    name = null;
13690                    newArgs = EMPTY_STRING_ARRAY;
13691                } else {
13692                    dumpPackage = args[opti];
13693                    opti++;
13694                    newArgs = new String[args.length - opti];
13695                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13696                            args.length - opti);
13697                }
13698                synchronized (this) {
13699                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13700                }
13701            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13702                String[] newArgs;
13703                String name;
13704                if (opti >= args.length) {
13705                    name = null;
13706                    newArgs = EMPTY_STRING_ARRAY;
13707                } else {
13708                    dumpPackage = args[opti];
13709                    opti++;
13710                    newArgs = new String[args.length - opti];
13711                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13712                            args.length - opti);
13713                }
13714                synchronized (this) {
13715                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13716                }
13717            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13718                synchronized (this) {
13719                    dumpOomLocked(fd, pw, args, opti, true);
13720                }
13721            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13722                synchronized (this) {
13723                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13724                }
13725            } else if ("provider".equals(cmd)) {
13726                String[] newArgs;
13727                String name;
13728                if (opti >= args.length) {
13729                    name = null;
13730                    newArgs = EMPTY_STRING_ARRAY;
13731                } else {
13732                    name = args[opti];
13733                    opti++;
13734                    newArgs = new String[args.length - opti];
13735                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13736                }
13737                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13738                    pw.println("No providers match: " + name);
13739                    pw.println("Use -h for help.");
13740                }
13741            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13742                synchronized (this) {
13743                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13744                }
13745            } else if ("service".equals(cmd)) {
13746                String[] newArgs;
13747                String name;
13748                if (opti >= args.length) {
13749                    name = null;
13750                    newArgs = EMPTY_STRING_ARRAY;
13751                } else {
13752                    name = args[opti];
13753                    opti++;
13754                    newArgs = new String[args.length - opti];
13755                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13756                            args.length - opti);
13757                }
13758                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13759                    pw.println("No services match: " + name);
13760                    pw.println("Use -h for help.");
13761                }
13762            } else if ("package".equals(cmd)) {
13763                String[] newArgs;
13764                if (opti >= args.length) {
13765                    pw.println("package: no package name specified");
13766                    pw.println("Use -h for help.");
13767                } else {
13768                    dumpPackage = args[opti];
13769                    opti++;
13770                    newArgs = new String[args.length - opti];
13771                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13772                            args.length - opti);
13773                    args = newArgs;
13774                    opti = 0;
13775                    more = true;
13776                }
13777            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13778                synchronized (this) {
13779                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13780                }
13781            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13782                synchronized (this) {
13783                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13784                }
13785            } else {
13786                // Dumping a single activity?
13787                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13788                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13789                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13790                    if (res < 0) {
13791                        pw.println("Bad activity command, or no activities match: " + cmd);
13792                        pw.println("Use -h for help.");
13793                    }
13794                }
13795            }
13796            if (!more) {
13797                Binder.restoreCallingIdentity(origId);
13798                return;
13799            }
13800        }
13801
13802        // No piece of data specified, dump everything.
13803        synchronized (this) {
13804            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13805            pw.println();
13806            if (dumpAll) {
13807                pw.println("-------------------------------------------------------------------------------");
13808            }
13809            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13810            pw.println();
13811            if (dumpAll) {
13812                pw.println("-------------------------------------------------------------------------------");
13813            }
13814            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13815            pw.println();
13816            if (dumpAll) {
13817                pw.println("-------------------------------------------------------------------------------");
13818            }
13819            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13820            pw.println();
13821            if (dumpAll) {
13822                pw.println("-------------------------------------------------------------------------------");
13823            }
13824            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13825            pw.println();
13826            if (dumpAll) {
13827                pw.println("-------------------------------------------------------------------------------");
13828            }
13829            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13830            pw.println();
13831            if (dumpAll) {
13832                pw.println("-------------------------------------------------------------------------------");
13833            }
13834            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13835            if (mAssociations.size() > 0) {
13836                pw.println();
13837                if (dumpAll) {
13838                    pw.println("-------------------------------------------------------------------------------");
13839                }
13840                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13841            }
13842            pw.println();
13843            if (dumpAll) {
13844                pw.println("-------------------------------------------------------------------------------");
13845            }
13846            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13847        }
13848        Binder.restoreCallingIdentity(origId);
13849    }
13850
13851    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13852            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13853        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13854
13855        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13856                dumpPackage);
13857        boolean needSep = printedAnything;
13858
13859        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13860                dumpPackage, needSep, "  mFocusedActivity: ");
13861        if (printed) {
13862            printedAnything = true;
13863            needSep = false;
13864        }
13865
13866        if (dumpPackage == null) {
13867            if (needSep) {
13868                pw.println();
13869            }
13870            needSep = true;
13871            printedAnything = true;
13872            mStackSupervisor.dump(pw, "  ");
13873        }
13874
13875        if (!printedAnything) {
13876            pw.println("  (nothing)");
13877        }
13878    }
13879
13880    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13881            int opti, boolean dumpAll, String dumpPackage) {
13882        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13883
13884        boolean printedAnything = false;
13885
13886        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13887            boolean printedHeader = false;
13888
13889            final int N = mRecentTasks.size();
13890            for (int i=0; i<N; i++) {
13891                TaskRecord tr = mRecentTasks.get(i);
13892                if (dumpPackage != null) {
13893                    if (tr.realActivity == null ||
13894                            !dumpPackage.equals(tr.realActivity)) {
13895                        continue;
13896                    }
13897                }
13898                if (!printedHeader) {
13899                    pw.println("  Recent tasks:");
13900                    printedHeader = true;
13901                    printedAnything = true;
13902                }
13903                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13904                        pw.println(tr);
13905                if (dumpAll) {
13906                    mRecentTasks.get(i).dump(pw, "    ");
13907                }
13908            }
13909        }
13910
13911        if (!printedAnything) {
13912            pw.println("  (nothing)");
13913        }
13914    }
13915
13916    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13917            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13918        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13919
13920        int dumpUid = 0;
13921        if (dumpPackage != null) {
13922            IPackageManager pm = AppGlobals.getPackageManager();
13923            try {
13924                dumpUid = pm.getPackageUid(dumpPackage, 0);
13925            } catch (RemoteException e) {
13926            }
13927        }
13928
13929        boolean printedAnything = false;
13930
13931        final long now = SystemClock.uptimeMillis();
13932
13933        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13934            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13935                    = mAssociations.valueAt(i1);
13936            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13937                SparseArray<ArrayMap<String, Association>> sourceUids
13938                        = targetComponents.valueAt(i2);
13939                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13940                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13941                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13942                        Association ass = sourceProcesses.valueAt(i4);
13943                        if (dumpPackage != null) {
13944                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13945                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13946                                continue;
13947                            }
13948                        }
13949                        printedAnything = true;
13950                        pw.print("  ");
13951                        pw.print(ass.mTargetProcess);
13952                        pw.print("/");
13953                        UserHandle.formatUid(pw, ass.mTargetUid);
13954                        pw.print(" <- ");
13955                        pw.print(ass.mSourceProcess);
13956                        pw.print("/");
13957                        UserHandle.formatUid(pw, ass.mSourceUid);
13958                        pw.println();
13959                        pw.print("    via ");
13960                        pw.print(ass.mTargetComponent.flattenToShortString());
13961                        pw.println();
13962                        pw.print("    ");
13963                        long dur = ass.mTime;
13964                        if (ass.mNesting > 0) {
13965                            dur += now - ass.mStartTime;
13966                        }
13967                        TimeUtils.formatDuration(dur, pw);
13968                        pw.print(" (");
13969                        pw.print(ass.mCount);
13970                        pw.println(" times)");
13971                        if (ass.mNesting > 0) {
13972                            pw.print("    ");
13973                            pw.print(" Currently active: ");
13974                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13975                            pw.println();
13976                        }
13977                    }
13978                }
13979            }
13980
13981        }
13982
13983        if (!printedAnything) {
13984            pw.println("  (nothing)");
13985        }
13986    }
13987
13988    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13989            String header, boolean needSep) {
13990        boolean printed = false;
13991        int whichAppId = -1;
13992        if (dumpPackage != null) {
13993            try {
13994                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13995                        dumpPackage, 0);
13996                whichAppId = UserHandle.getAppId(info.uid);
13997            } catch (NameNotFoundException e) {
13998                e.printStackTrace();
13999            }
14000        }
14001        for (int i=0; i<uids.size(); i++) {
14002            UidRecord uidRec = uids.valueAt(i);
14003            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14004                continue;
14005            }
14006            if (!printed) {
14007                printed = true;
14008                if (needSep) {
14009                    pw.println();
14010                }
14011                pw.print("  ");
14012                pw.println(header);
14013                needSep = true;
14014            }
14015            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14016            pw.print(": "); pw.println(uidRec);
14017        }
14018        return printed;
14019    }
14020
14021    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14022            int opti, boolean dumpAll, String dumpPackage) {
14023        boolean needSep = false;
14024        boolean printedAnything = false;
14025        int numPers = 0;
14026
14027        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14028
14029        if (dumpAll) {
14030            final int NP = mProcessNames.getMap().size();
14031            for (int ip=0; ip<NP; ip++) {
14032                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14033                final int NA = procs.size();
14034                for (int ia=0; ia<NA; ia++) {
14035                    ProcessRecord r = procs.valueAt(ia);
14036                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14037                        continue;
14038                    }
14039                    if (!needSep) {
14040                        pw.println("  All known processes:");
14041                        needSep = true;
14042                        printedAnything = true;
14043                    }
14044                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14045                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14046                        pw.print(" "); pw.println(r);
14047                    r.dump(pw, "    ");
14048                    if (r.persistent) {
14049                        numPers++;
14050                    }
14051                }
14052            }
14053        }
14054
14055        if (mIsolatedProcesses.size() > 0) {
14056            boolean printed = false;
14057            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14058                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14059                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14060                    continue;
14061                }
14062                if (!printed) {
14063                    if (needSep) {
14064                        pw.println();
14065                    }
14066                    pw.println("  Isolated process list (sorted by uid):");
14067                    printedAnything = true;
14068                    printed = true;
14069                    needSep = true;
14070                }
14071                pw.println(String.format("%sIsolated #%2d: %s",
14072                        "    ", i, r.toString()));
14073            }
14074        }
14075
14076        if (mActiveUids.size() > 0) {
14077            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14078                printedAnything = needSep = true;
14079            }
14080        }
14081        if (mValidateUids.size() > 0) {
14082            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14083                printedAnything = needSep = true;
14084            }
14085        }
14086
14087        if (mLruProcesses.size() > 0) {
14088            if (needSep) {
14089                pw.println();
14090            }
14091            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14092                    pw.print(" total, non-act at ");
14093                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14094                    pw.print(", non-svc at ");
14095                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14096                    pw.println("):");
14097            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14098            needSep = true;
14099            printedAnything = true;
14100        }
14101
14102        if (dumpAll || dumpPackage != null) {
14103            synchronized (mPidsSelfLocked) {
14104                boolean printed = false;
14105                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14106                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14107                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14108                        continue;
14109                    }
14110                    if (!printed) {
14111                        if (needSep) pw.println();
14112                        needSep = true;
14113                        pw.println("  PID mappings:");
14114                        printed = true;
14115                        printedAnything = true;
14116                    }
14117                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14118                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14119                }
14120            }
14121        }
14122
14123        if (mForegroundProcesses.size() > 0) {
14124            synchronized (mPidsSelfLocked) {
14125                boolean printed = false;
14126                for (int i=0; i<mForegroundProcesses.size(); i++) {
14127                    ProcessRecord r = mPidsSelfLocked.get(
14128                            mForegroundProcesses.valueAt(i).pid);
14129                    if (dumpPackage != null && (r == null
14130                            || !r.pkgList.containsKey(dumpPackage))) {
14131                        continue;
14132                    }
14133                    if (!printed) {
14134                        if (needSep) pw.println();
14135                        needSep = true;
14136                        pw.println("  Foreground Processes:");
14137                        printed = true;
14138                        printedAnything = true;
14139                    }
14140                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14141                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14142                }
14143            }
14144        }
14145
14146        if (mPersistentStartingProcesses.size() > 0) {
14147            if (needSep) pw.println();
14148            needSep = true;
14149            printedAnything = true;
14150            pw.println("  Persisent processes that are starting:");
14151            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14152                    "Starting Norm", "Restarting PERS", dumpPackage);
14153        }
14154
14155        if (mRemovedProcesses.size() > 0) {
14156            if (needSep) pw.println();
14157            needSep = true;
14158            printedAnything = true;
14159            pw.println("  Processes that are being removed:");
14160            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14161                    "Removed Norm", "Removed PERS", dumpPackage);
14162        }
14163
14164        if (mProcessesOnHold.size() > 0) {
14165            if (needSep) pw.println();
14166            needSep = true;
14167            printedAnything = true;
14168            pw.println("  Processes that are on old until the system is ready:");
14169            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14170                    "OnHold Norm", "OnHold PERS", dumpPackage);
14171        }
14172
14173        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14174
14175        if (mProcessCrashTimes.getMap().size() > 0) {
14176            boolean printed = false;
14177            long now = SystemClock.uptimeMillis();
14178            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14179            final int NP = pmap.size();
14180            for (int ip=0; ip<NP; ip++) {
14181                String pname = pmap.keyAt(ip);
14182                SparseArray<Long> uids = pmap.valueAt(ip);
14183                final int N = uids.size();
14184                for (int i=0; i<N; i++) {
14185                    int puid = uids.keyAt(i);
14186                    ProcessRecord r = mProcessNames.get(pname, puid);
14187                    if (dumpPackage != null && (r == null
14188                            || !r.pkgList.containsKey(dumpPackage))) {
14189                        continue;
14190                    }
14191                    if (!printed) {
14192                        if (needSep) pw.println();
14193                        needSep = true;
14194                        pw.println("  Time since processes crashed:");
14195                        printed = true;
14196                        printedAnything = true;
14197                    }
14198                    pw.print("    Process "); pw.print(pname);
14199                            pw.print(" uid "); pw.print(puid);
14200                            pw.print(": last crashed ");
14201                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14202                            pw.println(" ago");
14203                }
14204            }
14205        }
14206
14207        if (mBadProcesses.getMap().size() > 0) {
14208            boolean printed = false;
14209            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14210            final int NP = pmap.size();
14211            for (int ip=0; ip<NP; ip++) {
14212                String pname = pmap.keyAt(ip);
14213                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14214                final int N = uids.size();
14215                for (int i=0; i<N; i++) {
14216                    int puid = uids.keyAt(i);
14217                    ProcessRecord r = mProcessNames.get(pname, puid);
14218                    if (dumpPackage != null && (r == null
14219                            || !r.pkgList.containsKey(dumpPackage))) {
14220                        continue;
14221                    }
14222                    if (!printed) {
14223                        if (needSep) pw.println();
14224                        needSep = true;
14225                        pw.println("  Bad processes:");
14226                        printedAnything = true;
14227                    }
14228                    BadProcessInfo info = uids.valueAt(i);
14229                    pw.print("    Bad process "); pw.print(pname);
14230                            pw.print(" uid "); pw.print(puid);
14231                            pw.print(": crashed at time "); pw.println(info.time);
14232                    if (info.shortMsg != null) {
14233                        pw.print("      Short msg: "); pw.println(info.shortMsg);
14234                    }
14235                    if (info.longMsg != null) {
14236                        pw.print("      Long msg: "); pw.println(info.longMsg);
14237                    }
14238                    if (info.stack != null) {
14239                        pw.println("      Stack:");
14240                        int lastPos = 0;
14241                        for (int pos=0; pos<info.stack.length(); pos++) {
14242                            if (info.stack.charAt(pos) == '\n') {
14243                                pw.print("        ");
14244                                pw.write(info.stack, lastPos, pos-lastPos);
14245                                pw.println();
14246                                lastPos = pos+1;
14247                            }
14248                        }
14249                        if (lastPos < info.stack.length()) {
14250                            pw.print("        ");
14251                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14252                            pw.println();
14253                        }
14254                    }
14255                }
14256            }
14257        }
14258
14259        if (dumpPackage == null) {
14260            pw.println();
14261            needSep = false;
14262            mUserController.dump(pw, dumpAll);
14263        }
14264        if (mHomeProcess != null && (dumpPackage == null
14265                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14266            if (needSep) {
14267                pw.println();
14268                needSep = false;
14269            }
14270            pw.println("  mHomeProcess: " + mHomeProcess);
14271        }
14272        if (mPreviousProcess != null && (dumpPackage == null
14273                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14274            if (needSep) {
14275                pw.println();
14276                needSep = false;
14277            }
14278            pw.println("  mPreviousProcess: " + mPreviousProcess);
14279        }
14280        if (dumpAll) {
14281            StringBuilder sb = new StringBuilder(128);
14282            sb.append("  mPreviousProcessVisibleTime: ");
14283            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14284            pw.println(sb);
14285        }
14286        if (mHeavyWeightProcess != null && (dumpPackage == null
14287                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14288            if (needSep) {
14289                pw.println();
14290                needSep = false;
14291            }
14292            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14293        }
14294        if (dumpPackage == null) {
14295            pw.println("  mConfiguration: " + mConfiguration);
14296        }
14297        if (dumpAll) {
14298            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14299            if (mCompatModePackages.getPackages().size() > 0) {
14300                boolean printed = false;
14301                for (Map.Entry<String, Integer> entry
14302                        : mCompatModePackages.getPackages().entrySet()) {
14303                    String pkg = entry.getKey();
14304                    int mode = entry.getValue();
14305                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14306                        continue;
14307                    }
14308                    if (!printed) {
14309                        pw.println("  mScreenCompatPackages:");
14310                        printed = true;
14311                    }
14312                    pw.print("    "); pw.print(pkg); pw.print(": ");
14313                            pw.print(mode); pw.println();
14314                }
14315            }
14316        }
14317        if (dumpPackage == null) {
14318            pw.println("  mWakefulness="
14319                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14320            pw.println("  mSleepTokens=" + mSleepTokens);
14321            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14322                    + lockScreenShownToString());
14323            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14324            if (mRunningVoice != null) {
14325                pw.println("  mRunningVoice=" + mRunningVoice);
14326                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14327            }
14328        }
14329        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14330                || mOrigWaitForDebugger) {
14331            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14332                    || dumpPackage.equals(mOrigDebugApp)) {
14333                if (needSep) {
14334                    pw.println();
14335                    needSep = false;
14336                }
14337                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14338                        + " mDebugTransient=" + mDebugTransient
14339                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14340            }
14341        }
14342        if (mCurAppTimeTracker != null) {
14343            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14344        }
14345        if (mMemWatchProcesses.getMap().size() > 0) {
14346            pw.println("  Mem watch processes:");
14347            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14348                    = mMemWatchProcesses.getMap();
14349            for (int i=0; i<procs.size(); i++) {
14350                final String proc = procs.keyAt(i);
14351                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14352                for (int j=0; j<uids.size(); j++) {
14353                    if (needSep) {
14354                        pw.println();
14355                        needSep = false;
14356                    }
14357                    StringBuilder sb = new StringBuilder();
14358                    sb.append("    ").append(proc).append('/');
14359                    UserHandle.formatUid(sb, uids.keyAt(j));
14360                    Pair<Long, String> val = uids.valueAt(j);
14361                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14362                    if (val.second != null) {
14363                        sb.append(", report to ").append(val.second);
14364                    }
14365                    pw.println(sb.toString());
14366                }
14367            }
14368            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14369            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14370            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14371                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14372        }
14373        if (mTrackAllocationApp != null) {
14374            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14375                if (needSep) {
14376                    pw.println();
14377                    needSep = false;
14378                }
14379                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14380            }
14381        }
14382        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14383                || mProfileFd != null) {
14384            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14385                if (needSep) {
14386                    pw.println();
14387                    needSep = false;
14388                }
14389                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14390                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14391                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14392                        + mAutoStopProfiler);
14393                pw.println("  mProfileType=" + mProfileType);
14394            }
14395        }
14396        if (dumpPackage == null) {
14397            if (mAlwaysFinishActivities || mController != null) {
14398                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14399                        + " mController=" + mController);
14400            }
14401            if (dumpAll) {
14402                pw.println("  Total persistent processes: " + numPers);
14403                pw.println("  mProcessesReady=" + mProcessesReady
14404                        + " mSystemReady=" + mSystemReady
14405                        + " mBooted=" + mBooted
14406                        + " mFactoryTest=" + mFactoryTest);
14407                pw.println("  mBooting=" + mBooting
14408                        + " mCallFinishBooting=" + mCallFinishBooting
14409                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14410                pw.print("  mLastPowerCheckRealtime=");
14411                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14412                        pw.println("");
14413                pw.print("  mLastPowerCheckUptime=");
14414                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14415                        pw.println("");
14416                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14417                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14418                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14419                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14420                        + " (" + mLruProcesses.size() + " total)"
14421                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14422                        + " mNumServiceProcs=" + mNumServiceProcs
14423                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14424                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14425                        + " mLastMemoryLevel" + mLastMemoryLevel
14426                        + " mLastNumProcesses" + mLastNumProcesses);
14427                long now = SystemClock.uptimeMillis();
14428                pw.print("  mLastIdleTime=");
14429                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14430                        pw.print(" mLowRamSinceLastIdle=");
14431                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14432                        pw.println();
14433            }
14434        }
14435
14436        if (!printedAnything) {
14437            pw.println("  (nothing)");
14438        }
14439    }
14440
14441    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14442            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14443        if (mProcessesToGc.size() > 0) {
14444            boolean printed = false;
14445            long now = SystemClock.uptimeMillis();
14446            for (int i=0; i<mProcessesToGc.size(); i++) {
14447                ProcessRecord proc = mProcessesToGc.get(i);
14448                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14449                    continue;
14450                }
14451                if (!printed) {
14452                    if (needSep) pw.println();
14453                    needSep = true;
14454                    pw.println("  Processes that are waiting to GC:");
14455                    printed = true;
14456                }
14457                pw.print("    Process "); pw.println(proc);
14458                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14459                        pw.print(", last gced=");
14460                        pw.print(now-proc.lastRequestedGc);
14461                        pw.print(" ms ago, last lowMem=");
14462                        pw.print(now-proc.lastLowMemory);
14463                        pw.println(" ms ago");
14464
14465            }
14466        }
14467        return needSep;
14468    }
14469
14470    void printOomLevel(PrintWriter pw, String name, int adj) {
14471        pw.print("    ");
14472        if (adj >= 0) {
14473            pw.print(' ');
14474            if (adj < 10) pw.print(' ');
14475        } else {
14476            if (adj > -10) pw.print(' ');
14477        }
14478        pw.print(adj);
14479        pw.print(": ");
14480        pw.print(name);
14481        pw.print(" (");
14482        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14483        pw.println(")");
14484    }
14485
14486    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14487            int opti, boolean dumpAll) {
14488        boolean needSep = false;
14489
14490        if (mLruProcesses.size() > 0) {
14491            if (needSep) pw.println();
14492            needSep = true;
14493            pw.println("  OOM levels:");
14494            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14495            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14496            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14497            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14498            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14499            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14500            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14501            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14502            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14503            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14504            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14505            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14506            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14507            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14508
14509            if (needSep) pw.println();
14510            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14511                    pw.print(" total, non-act at ");
14512                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14513                    pw.print(", non-svc at ");
14514                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14515                    pw.println("):");
14516            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14517            needSep = true;
14518        }
14519
14520        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14521
14522        pw.println();
14523        pw.println("  mHomeProcess: " + mHomeProcess);
14524        pw.println("  mPreviousProcess: " + mPreviousProcess);
14525        if (mHeavyWeightProcess != null) {
14526            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14527        }
14528
14529        return true;
14530    }
14531
14532    /**
14533     * There are three ways to call this:
14534     *  - no provider specified: dump all the providers
14535     *  - a flattened component name that matched an existing provider was specified as the
14536     *    first arg: dump that one provider
14537     *  - the first arg isn't the flattened component name of an existing provider:
14538     *    dump all providers whose component contains the first arg as a substring
14539     */
14540    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14541            int opti, boolean dumpAll) {
14542        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14543    }
14544
14545    static class ItemMatcher {
14546        ArrayList<ComponentName> components;
14547        ArrayList<String> strings;
14548        ArrayList<Integer> objects;
14549        boolean all;
14550
14551        ItemMatcher() {
14552            all = true;
14553        }
14554
14555        void build(String name) {
14556            ComponentName componentName = ComponentName.unflattenFromString(name);
14557            if (componentName != null) {
14558                if (components == null) {
14559                    components = new ArrayList<ComponentName>();
14560                }
14561                components.add(componentName);
14562                all = false;
14563            } else {
14564                int objectId = 0;
14565                // Not a '/' separated full component name; maybe an object ID?
14566                try {
14567                    objectId = Integer.parseInt(name, 16);
14568                    if (objects == null) {
14569                        objects = new ArrayList<Integer>();
14570                    }
14571                    objects.add(objectId);
14572                    all = false;
14573                } catch (RuntimeException e) {
14574                    // Not an integer; just do string match.
14575                    if (strings == null) {
14576                        strings = new ArrayList<String>();
14577                    }
14578                    strings.add(name);
14579                    all = false;
14580                }
14581            }
14582        }
14583
14584        int build(String[] args, int opti) {
14585            for (; opti<args.length; opti++) {
14586                String name = args[opti];
14587                if ("--".equals(name)) {
14588                    return opti+1;
14589                }
14590                build(name);
14591            }
14592            return opti;
14593        }
14594
14595        boolean match(Object object, ComponentName comp) {
14596            if (all) {
14597                return true;
14598            }
14599            if (components != null) {
14600                for (int i=0; i<components.size(); i++) {
14601                    if (components.get(i).equals(comp)) {
14602                        return true;
14603                    }
14604                }
14605            }
14606            if (objects != null) {
14607                for (int i=0; i<objects.size(); i++) {
14608                    if (System.identityHashCode(object) == objects.get(i)) {
14609                        return true;
14610                    }
14611                }
14612            }
14613            if (strings != null) {
14614                String flat = comp.flattenToString();
14615                for (int i=0; i<strings.size(); i++) {
14616                    if (flat.contains(strings.get(i))) {
14617                        return true;
14618                    }
14619                }
14620            }
14621            return false;
14622        }
14623    }
14624
14625    /**
14626     * There are three things that cmd can be:
14627     *  - a flattened component name that matches an existing activity
14628     *  - the cmd arg isn't the flattened component name of an existing activity:
14629     *    dump all activity whose component contains the cmd as a substring
14630     *  - A hex number of the ActivityRecord object instance.
14631     */
14632    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14633            int opti, boolean dumpAll) {
14634        ArrayList<ActivityRecord> activities;
14635
14636        synchronized (this) {
14637            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14638        }
14639
14640        if (activities.size() <= 0) {
14641            return false;
14642        }
14643
14644        String[] newArgs = new String[args.length - opti];
14645        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14646
14647        TaskRecord lastTask = null;
14648        boolean needSep = false;
14649        for (int i=activities.size()-1; i>=0; i--) {
14650            ActivityRecord r = activities.get(i);
14651            if (needSep) {
14652                pw.println();
14653            }
14654            needSep = true;
14655            synchronized (this) {
14656                if (lastTask != r.task) {
14657                    lastTask = r.task;
14658                    pw.print("TASK "); pw.print(lastTask.affinity);
14659                            pw.print(" id="); pw.println(lastTask.taskId);
14660                    if (dumpAll) {
14661                        lastTask.dump(pw, "  ");
14662                    }
14663                }
14664            }
14665            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14666        }
14667        return true;
14668    }
14669
14670    /**
14671     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14672     * there is a thread associated with the activity.
14673     */
14674    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14675            final ActivityRecord r, String[] args, boolean dumpAll) {
14676        String innerPrefix = prefix + "  ";
14677        synchronized (this) {
14678            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14679                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14680                    pw.print(" pid=");
14681                    if (r.app != null) pw.println(r.app.pid);
14682                    else pw.println("(not running)");
14683            if (dumpAll) {
14684                r.dump(pw, innerPrefix);
14685            }
14686        }
14687        if (r.app != null && r.app.thread != null) {
14688            // flush anything that is already in the PrintWriter since the thread is going
14689            // to write to the file descriptor directly
14690            pw.flush();
14691            try {
14692                TransferPipe tp = new TransferPipe();
14693                try {
14694                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14695                            r.appToken, innerPrefix, args);
14696                    tp.go(fd);
14697                } finally {
14698                    tp.kill();
14699                }
14700            } catch (IOException e) {
14701                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14702            } catch (RemoteException e) {
14703                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14704            }
14705        }
14706    }
14707
14708    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14709            int opti, boolean dumpAll, String dumpPackage) {
14710        boolean needSep = false;
14711        boolean onlyHistory = false;
14712        boolean printedAnything = false;
14713
14714        if ("history".equals(dumpPackage)) {
14715            if (opti < args.length && "-s".equals(args[opti])) {
14716                dumpAll = false;
14717            }
14718            onlyHistory = true;
14719            dumpPackage = null;
14720        }
14721
14722        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14723        if (!onlyHistory && dumpAll) {
14724            if (mRegisteredReceivers.size() > 0) {
14725                boolean printed = false;
14726                Iterator it = mRegisteredReceivers.values().iterator();
14727                while (it.hasNext()) {
14728                    ReceiverList r = (ReceiverList)it.next();
14729                    if (dumpPackage != null && (r.app == null ||
14730                            !dumpPackage.equals(r.app.info.packageName))) {
14731                        continue;
14732                    }
14733                    if (!printed) {
14734                        pw.println("  Registered Receivers:");
14735                        needSep = true;
14736                        printed = true;
14737                        printedAnything = true;
14738                    }
14739                    pw.print("  * "); pw.println(r);
14740                    r.dump(pw, "    ");
14741                }
14742            }
14743
14744            if (mReceiverResolver.dump(pw, needSep ?
14745                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14746                    "    ", dumpPackage, false, false)) {
14747                needSep = true;
14748                printedAnything = true;
14749            }
14750        }
14751
14752        for (BroadcastQueue q : mBroadcastQueues) {
14753            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14754            printedAnything |= needSep;
14755        }
14756
14757        needSep = true;
14758
14759        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14760            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14761                if (needSep) {
14762                    pw.println();
14763                }
14764                needSep = true;
14765                printedAnything = true;
14766                pw.print("  Sticky broadcasts for user ");
14767                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14768                StringBuilder sb = new StringBuilder(128);
14769                for (Map.Entry<String, ArrayList<Intent>> ent
14770                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14771                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14772                    if (dumpAll) {
14773                        pw.println(":");
14774                        ArrayList<Intent> intents = ent.getValue();
14775                        final int N = intents.size();
14776                        for (int i=0; i<N; i++) {
14777                            sb.setLength(0);
14778                            sb.append("    Intent: ");
14779                            intents.get(i).toShortString(sb, false, true, false, false);
14780                            pw.println(sb.toString());
14781                            Bundle bundle = intents.get(i).getExtras();
14782                            if (bundle != null) {
14783                                pw.print("      ");
14784                                pw.println(bundle.toString());
14785                            }
14786                        }
14787                    } else {
14788                        pw.println("");
14789                    }
14790                }
14791            }
14792        }
14793
14794        if (!onlyHistory && dumpAll) {
14795            pw.println();
14796            for (BroadcastQueue queue : mBroadcastQueues) {
14797                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14798                        + queue.mBroadcastsScheduled);
14799            }
14800            pw.println("  mHandler:");
14801            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14802            needSep = true;
14803            printedAnything = true;
14804        }
14805
14806        if (!printedAnything) {
14807            pw.println("  (nothing)");
14808        }
14809    }
14810
14811    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14812            int opti, boolean dumpAll, String dumpPackage) {
14813        boolean needSep;
14814        boolean printedAnything = false;
14815
14816        ItemMatcher matcher = new ItemMatcher();
14817        matcher.build(args, opti);
14818
14819        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14820
14821        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14822        printedAnything |= needSep;
14823
14824        if (mLaunchingProviders.size() > 0) {
14825            boolean printed = false;
14826            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14827                ContentProviderRecord r = mLaunchingProviders.get(i);
14828                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14829                    continue;
14830                }
14831                if (!printed) {
14832                    if (needSep) pw.println();
14833                    needSep = true;
14834                    pw.println("  Launching content providers:");
14835                    printed = true;
14836                    printedAnything = true;
14837                }
14838                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14839                        pw.println(r);
14840            }
14841        }
14842
14843        if (!printedAnything) {
14844            pw.println("  (nothing)");
14845        }
14846    }
14847
14848    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14849            int opti, boolean dumpAll, String dumpPackage) {
14850        boolean needSep = false;
14851        boolean printedAnything = false;
14852
14853        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14854
14855        if (mGrantedUriPermissions.size() > 0) {
14856            boolean printed = false;
14857            int dumpUid = -2;
14858            if (dumpPackage != null) {
14859                try {
14860                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14861                } catch (NameNotFoundException e) {
14862                    dumpUid = -1;
14863                }
14864            }
14865            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14866                int uid = mGrantedUriPermissions.keyAt(i);
14867                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14868                    continue;
14869                }
14870                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14871                if (!printed) {
14872                    if (needSep) pw.println();
14873                    needSep = true;
14874                    pw.println("  Granted Uri Permissions:");
14875                    printed = true;
14876                    printedAnything = true;
14877                }
14878                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14879                for (UriPermission perm : perms.values()) {
14880                    pw.print("    "); pw.println(perm);
14881                    if (dumpAll) {
14882                        perm.dump(pw, "      ");
14883                    }
14884                }
14885            }
14886        }
14887
14888        if (!printedAnything) {
14889            pw.println("  (nothing)");
14890        }
14891    }
14892
14893    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14894            int opti, boolean dumpAll, String dumpPackage) {
14895        boolean printed = false;
14896
14897        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14898
14899        if (mIntentSenderRecords.size() > 0) {
14900            Iterator<WeakReference<PendingIntentRecord>> it
14901                    = mIntentSenderRecords.values().iterator();
14902            while (it.hasNext()) {
14903                WeakReference<PendingIntentRecord> ref = it.next();
14904                PendingIntentRecord rec = ref != null ? ref.get(): null;
14905                if (dumpPackage != null && (rec == null
14906                        || !dumpPackage.equals(rec.key.packageName))) {
14907                    continue;
14908                }
14909                printed = true;
14910                if (rec != null) {
14911                    pw.print("  * "); pw.println(rec);
14912                    if (dumpAll) {
14913                        rec.dump(pw, "    ");
14914                    }
14915                } else {
14916                    pw.print("  * "); pw.println(ref);
14917                }
14918            }
14919        }
14920
14921        if (!printed) {
14922            pw.println("  (nothing)");
14923        }
14924    }
14925
14926    private static final int dumpProcessList(PrintWriter pw,
14927            ActivityManagerService service, List list,
14928            String prefix, String normalLabel, String persistentLabel,
14929            String dumpPackage) {
14930        int numPers = 0;
14931        final int N = list.size()-1;
14932        for (int i=N; i>=0; i--) {
14933            ProcessRecord r = (ProcessRecord)list.get(i);
14934            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14935                continue;
14936            }
14937            pw.println(String.format("%s%s #%2d: %s",
14938                    prefix, (r.persistent ? persistentLabel : normalLabel),
14939                    i, r.toString()));
14940            if (r.persistent) {
14941                numPers++;
14942            }
14943        }
14944        return numPers;
14945    }
14946
14947    private static final boolean dumpProcessOomList(PrintWriter pw,
14948            ActivityManagerService service, List<ProcessRecord> origList,
14949            String prefix, String normalLabel, String persistentLabel,
14950            boolean inclDetails, String dumpPackage) {
14951
14952        ArrayList<Pair<ProcessRecord, Integer>> list
14953                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14954        for (int i=0; i<origList.size(); i++) {
14955            ProcessRecord r = origList.get(i);
14956            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14957                continue;
14958            }
14959            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14960        }
14961
14962        if (list.size() <= 0) {
14963            return false;
14964        }
14965
14966        Comparator<Pair<ProcessRecord, Integer>> comparator
14967                = new Comparator<Pair<ProcessRecord, Integer>>() {
14968            @Override
14969            public int compare(Pair<ProcessRecord, Integer> object1,
14970                    Pair<ProcessRecord, Integer> object2) {
14971                if (object1.first.setAdj != object2.first.setAdj) {
14972                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14973                }
14974                if (object1.first.setProcState != object2.first.setProcState) {
14975                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14976                }
14977                if (object1.second.intValue() != object2.second.intValue()) {
14978                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14979                }
14980                return 0;
14981            }
14982        };
14983
14984        Collections.sort(list, comparator);
14985
14986        final long curRealtime = SystemClock.elapsedRealtime();
14987        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14988        final long curUptime = SystemClock.uptimeMillis();
14989        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14990
14991        for (int i=list.size()-1; i>=0; i--) {
14992            ProcessRecord r = list.get(i).first;
14993            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14994            char schedGroup;
14995            switch (r.setSchedGroup) {
14996                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14997                    schedGroup = 'B';
14998                    break;
14999                case Process.THREAD_GROUP_DEFAULT:
15000                    schedGroup = 'F';
15001                    break;
15002                default:
15003                    schedGroup = '?';
15004                    break;
15005            }
15006            char foreground;
15007            if (r.foregroundActivities) {
15008                foreground = 'A';
15009            } else if (r.foregroundServices) {
15010                foreground = 'S';
15011            } else {
15012                foreground = ' ';
15013            }
15014            String procState = ProcessList.makeProcStateString(r.curProcState);
15015            pw.print(prefix);
15016            pw.print(r.persistent ? persistentLabel : normalLabel);
15017            pw.print(" #");
15018            int num = (origList.size()-1)-list.get(i).second;
15019            if (num < 10) pw.print(' ');
15020            pw.print(num);
15021            pw.print(": ");
15022            pw.print(oomAdj);
15023            pw.print(' ');
15024            pw.print(schedGroup);
15025            pw.print('/');
15026            pw.print(foreground);
15027            pw.print('/');
15028            pw.print(procState);
15029            pw.print(" trm:");
15030            if (r.trimMemoryLevel < 10) pw.print(' ');
15031            pw.print(r.trimMemoryLevel);
15032            pw.print(' ');
15033            pw.print(r.toShortString());
15034            pw.print(" (");
15035            pw.print(r.adjType);
15036            pw.println(')');
15037            if (r.adjSource != null || r.adjTarget != null) {
15038                pw.print(prefix);
15039                pw.print("    ");
15040                if (r.adjTarget instanceof ComponentName) {
15041                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15042                } else if (r.adjTarget != null) {
15043                    pw.print(r.adjTarget.toString());
15044                } else {
15045                    pw.print("{null}");
15046                }
15047                pw.print("<=");
15048                if (r.adjSource instanceof ProcessRecord) {
15049                    pw.print("Proc{");
15050                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15051                    pw.println("}");
15052                } else if (r.adjSource != null) {
15053                    pw.println(r.adjSource.toString());
15054                } else {
15055                    pw.println("{null}");
15056                }
15057            }
15058            if (inclDetails) {
15059                pw.print(prefix);
15060                pw.print("    ");
15061                pw.print("oom: max="); pw.print(r.maxAdj);
15062                pw.print(" curRaw="); pw.print(r.curRawAdj);
15063                pw.print(" setRaw="); pw.print(r.setRawAdj);
15064                pw.print(" cur="); pw.print(r.curAdj);
15065                pw.print(" set="); pw.println(r.setAdj);
15066                pw.print(prefix);
15067                pw.print("    ");
15068                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15069                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15070                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15071                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15072                pw.println();
15073                pw.print(prefix);
15074                pw.print("    ");
15075                pw.print("cached="); pw.print(r.cached);
15076                pw.print(" empty="); pw.print(r.empty);
15077                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15078
15079                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15080                    if (r.lastWakeTime != 0) {
15081                        long wtime;
15082                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15083                        synchronized (stats) {
15084                            wtime = stats.getProcessWakeTime(r.info.uid,
15085                                    r.pid, curRealtime);
15086                        }
15087                        long timeUsed = wtime - r.lastWakeTime;
15088                        pw.print(prefix);
15089                        pw.print("    ");
15090                        pw.print("keep awake over ");
15091                        TimeUtils.formatDuration(realtimeSince, pw);
15092                        pw.print(" used ");
15093                        TimeUtils.formatDuration(timeUsed, pw);
15094                        pw.print(" (");
15095                        pw.print((timeUsed*100)/realtimeSince);
15096                        pw.println("%)");
15097                    }
15098                    if (r.lastCpuTime != 0) {
15099                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15100                        pw.print(prefix);
15101                        pw.print("    ");
15102                        pw.print("run cpu over ");
15103                        TimeUtils.formatDuration(uptimeSince, pw);
15104                        pw.print(" used ");
15105                        TimeUtils.formatDuration(timeUsed, pw);
15106                        pw.print(" (");
15107                        pw.print((timeUsed*100)/uptimeSince);
15108                        pw.println("%)");
15109                    }
15110                }
15111            }
15112        }
15113        return true;
15114    }
15115
15116    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15117            String[] args) {
15118        ArrayList<ProcessRecord> procs;
15119        synchronized (this) {
15120            if (args != null && args.length > start
15121                    && args[start].charAt(0) != '-') {
15122                procs = new ArrayList<ProcessRecord>();
15123                int pid = -1;
15124                try {
15125                    pid = Integer.parseInt(args[start]);
15126                } catch (NumberFormatException e) {
15127                }
15128                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15129                    ProcessRecord proc = mLruProcesses.get(i);
15130                    if (proc.pid == pid) {
15131                        procs.add(proc);
15132                    } else if (allPkgs && proc.pkgList != null
15133                            && proc.pkgList.containsKey(args[start])) {
15134                        procs.add(proc);
15135                    } else if (proc.processName.equals(args[start])) {
15136                        procs.add(proc);
15137                    }
15138                }
15139                if (procs.size() <= 0) {
15140                    return null;
15141                }
15142            } else {
15143                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15144            }
15145        }
15146        return procs;
15147    }
15148
15149    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15150            PrintWriter pw, String[] args) {
15151        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15152        if (procs == null) {
15153            pw.println("No process found for: " + args[0]);
15154            return;
15155        }
15156
15157        long uptime = SystemClock.uptimeMillis();
15158        long realtime = SystemClock.elapsedRealtime();
15159        pw.println("Applications Graphics Acceleration Info:");
15160        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15161
15162        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15163            ProcessRecord r = procs.get(i);
15164            if (r.thread != null) {
15165                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15166                pw.flush();
15167                try {
15168                    TransferPipe tp = new TransferPipe();
15169                    try {
15170                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15171                        tp.go(fd);
15172                    } finally {
15173                        tp.kill();
15174                    }
15175                } catch (IOException e) {
15176                    pw.println("Failure while dumping the app: " + r);
15177                    pw.flush();
15178                } catch (RemoteException e) {
15179                    pw.println("Got a RemoteException while dumping the app " + r);
15180                    pw.flush();
15181                }
15182            }
15183        }
15184    }
15185
15186    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15187        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15188        if (procs == null) {
15189            pw.println("No process found for: " + args[0]);
15190            return;
15191        }
15192
15193        pw.println("Applications Database Info:");
15194
15195        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15196            ProcessRecord r = procs.get(i);
15197            if (r.thread != null) {
15198                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15199                pw.flush();
15200                try {
15201                    TransferPipe tp = new TransferPipe();
15202                    try {
15203                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15204                        tp.go(fd);
15205                    } finally {
15206                        tp.kill();
15207                    }
15208                } catch (IOException e) {
15209                    pw.println("Failure while dumping the app: " + r);
15210                    pw.flush();
15211                } catch (RemoteException e) {
15212                    pw.println("Got a RemoteException while dumping the app " + r);
15213                    pw.flush();
15214                }
15215            }
15216        }
15217    }
15218
15219    final static class MemItem {
15220        final boolean isProc;
15221        final String label;
15222        final String shortLabel;
15223        final long pss;
15224        final int id;
15225        final boolean hasActivities;
15226        ArrayList<MemItem> subitems;
15227
15228        public MemItem(String _label, String _shortLabel, long _pss, int _id,
15229                boolean _hasActivities) {
15230            isProc = true;
15231            label = _label;
15232            shortLabel = _shortLabel;
15233            pss = _pss;
15234            id = _id;
15235            hasActivities = _hasActivities;
15236        }
15237
15238        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
15239            isProc = false;
15240            label = _label;
15241            shortLabel = _shortLabel;
15242            pss = _pss;
15243            id = _id;
15244            hasActivities = false;
15245        }
15246    }
15247
15248    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15249            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
15250        if (sort && !isCompact) {
15251            Collections.sort(items, new Comparator<MemItem>() {
15252                @Override
15253                public int compare(MemItem lhs, MemItem rhs) {
15254                    if (lhs.pss < rhs.pss) {
15255                        return 1;
15256                    } else if (lhs.pss > rhs.pss) {
15257                        return -1;
15258                    }
15259                    return 0;
15260                }
15261            });
15262        }
15263
15264        for (int i=0; i<items.size(); i++) {
15265            MemItem mi = items.get(i);
15266            if (!isCompact) {
15267                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15268            } else if (mi.isProc) {
15269                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15270                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
15271                pw.println(mi.hasActivities ? ",a" : ",e");
15272            } else {
15273                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15274                pw.println(mi.pss);
15275            }
15276            if (mi.subitems != null) {
15277                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
15278                        true, isCompact);
15279            }
15280        }
15281    }
15282
15283    // These are in KB.
15284    static final long[] DUMP_MEM_BUCKETS = new long[] {
15285        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15286        120*1024, 160*1024, 200*1024,
15287        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15288        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15289    };
15290
15291    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15292            boolean stackLike) {
15293        int start = label.lastIndexOf('.');
15294        if (start >= 0) start++;
15295        else start = 0;
15296        int end = label.length();
15297        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15298            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15299                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15300                out.append(bucket);
15301                out.append(stackLike ? "MB." : "MB ");
15302                out.append(label, start, end);
15303                return;
15304            }
15305        }
15306        out.append(memKB/1024);
15307        out.append(stackLike ? "MB." : "MB ");
15308        out.append(label, start, end);
15309    }
15310
15311    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15312            ProcessList.NATIVE_ADJ,
15313            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15314            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15315            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15316            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15317            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15318            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15319    };
15320    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15321            "Native",
15322            "System", "Persistent", "Persistent Service", "Foreground",
15323            "Visible", "Perceptible",
15324            "Heavy Weight", "Backup",
15325            "A Services", "Home",
15326            "Previous", "B Services", "Cached"
15327    };
15328    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15329            "native",
15330            "sys", "pers", "persvc", "fore",
15331            "vis", "percept",
15332            "heavy", "backup",
15333            "servicea", "home",
15334            "prev", "serviceb", "cached"
15335    };
15336
15337    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15338            long realtime, boolean isCheckinRequest, boolean isCompact) {
15339        if (isCheckinRequest || isCompact) {
15340            // short checkin version
15341            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15342        } else {
15343            pw.println("Applications Memory Usage (in Kilobytes):");
15344            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15345        }
15346    }
15347
15348    private static final int KSM_SHARED = 0;
15349    private static final int KSM_SHARING = 1;
15350    private static final int KSM_UNSHARED = 2;
15351    private static final int KSM_VOLATILE = 3;
15352
15353    private final long[] getKsmInfo() {
15354        long[] longOut = new long[4];
15355        final int[] SINGLE_LONG_FORMAT = new int[] {
15356            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15357        };
15358        long[] longTmp = new long[1];
15359        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15360                SINGLE_LONG_FORMAT, null, longTmp, null);
15361        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15362        longTmp[0] = 0;
15363        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15364                SINGLE_LONG_FORMAT, null, longTmp, null);
15365        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15366        longTmp[0] = 0;
15367        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15368                SINGLE_LONG_FORMAT, null, longTmp, null);
15369        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15370        longTmp[0] = 0;
15371        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15372                SINGLE_LONG_FORMAT, null, longTmp, null);
15373        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15374        return longOut;
15375    }
15376
15377    private static String stringifySize(long size, int order) {
15378        Locale locale = Locale.US;
15379        switch (order) {
15380            case 1:
15381                return String.format(locale, "%,13d", size);
15382            case 1024:
15383                return String.format(locale, "%,9dK", size / 1024);
15384            case 1024 * 1024:
15385                return String.format(locale, "%,5dM", size / 1024 / 1024);
15386            case 1024 * 1024 * 1024:
15387                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15388            default:
15389                throw new IllegalArgumentException("Invalid size order");
15390        }
15391    }
15392
15393    private static String stringifyKBSize(long size) {
15394        return stringifySize(size * 1024, 1024);
15395    }
15396
15397    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15398            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15399        boolean dumpDetails = false;
15400        boolean dumpFullDetails = false;
15401        boolean dumpDalvik = false;
15402        boolean dumpSummaryOnly = false;
15403        boolean oomOnly = false;
15404        boolean isCompact = false;
15405        boolean localOnly = false;
15406        boolean packages = false;
15407
15408        int opti = 0;
15409        while (opti < args.length) {
15410            String opt = args[opti];
15411            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15412                break;
15413            }
15414            opti++;
15415            if ("-a".equals(opt)) {
15416                dumpDetails = true;
15417                dumpFullDetails = true;
15418                dumpDalvik = true;
15419            } else if ("-d".equals(opt)) {
15420                dumpDalvik = true;
15421            } else if ("-c".equals(opt)) {
15422                isCompact = true;
15423            } else if ("-s".equals(opt)) {
15424                dumpDetails = true;
15425                dumpSummaryOnly = true;
15426            } else if ("--oom".equals(opt)) {
15427                oomOnly = true;
15428            } else if ("--local".equals(opt)) {
15429                localOnly = true;
15430            } else if ("--package".equals(opt)) {
15431                packages = true;
15432            } else if ("-h".equals(opt)) {
15433                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15434                pw.println("  -a: include all available information for each process.");
15435                pw.println("  -d: include dalvik details.");
15436                pw.println("  -c: dump in a compact machine-parseable representation.");
15437                pw.println("  -s: dump only summary of application memory usage.");
15438                pw.println("  --oom: only show processes organized by oom adj.");
15439                pw.println("  --local: only collect details locally, don't call process.");
15440                pw.println("  --package: interpret process arg as package, dumping all");
15441                pw.println("             processes that have loaded that package.");
15442                pw.println("If [process] is specified it can be the name or ");
15443                pw.println("pid of a specific process to dump.");
15444                return;
15445            } else {
15446                pw.println("Unknown argument: " + opt + "; use -h for help");
15447            }
15448        }
15449
15450        final boolean isCheckinRequest = scanArgs(args, "--checkin");
15451        long uptime = SystemClock.uptimeMillis();
15452        long realtime = SystemClock.elapsedRealtime();
15453        final long[] tmpLong = new long[1];
15454
15455        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15456        if (procs == null) {
15457            // No Java processes.  Maybe they want to print a native process.
15458            if (args != null && args.length > opti
15459                    && args[opti].charAt(0) != '-') {
15460                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15461                        = new ArrayList<ProcessCpuTracker.Stats>();
15462                updateCpuStatsNow();
15463                int findPid = -1;
15464                try {
15465                    findPid = Integer.parseInt(args[opti]);
15466                } catch (NumberFormatException e) {
15467                }
15468                synchronized (mProcessCpuTracker) {
15469                    final int N = mProcessCpuTracker.countStats();
15470                    for (int i=0; i<N; i++) {
15471                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15472                        if (st.pid == findPid || (st.baseName != null
15473                                && st.baseName.equals(args[opti]))) {
15474                            nativeProcs.add(st);
15475                        }
15476                    }
15477                }
15478                if (nativeProcs.size() > 0) {
15479                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15480                            isCompact);
15481                    Debug.MemoryInfo mi = null;
15482                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15483                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15484                        final int pid = r.pid;
15485                        if (!isCheckinRequest && dumpDetails) {
15486                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15487                        }
15488                        if (mi == null) {
15489                            mi = new Debug.MemoryInfo();
15490                        }
15491                        if (dumpDetails || (!brief && !oomOnly)) {
15492                            Debug.getMemoryInfo(pid, mi);
15493                        } else {
15494                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15495                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15496                        }
15497                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15498                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15499                        if (isCheckinRequest) {
15500                            pw.println();
15501                        }
15502                    }
15503                    return;
15504                }
15505            }
15506            pw.println("No process found for: " + args[opti]);
15507            return;
15508        }
15509
15510        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15511            dumpDetails = true;
15512        }
15513
15514        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15515
15516        String[] innerArgs = new String[args.length-opti];
15517        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15518
15519        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15520        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15521        long nativePss = 0;
15522        long dalvikPss = 0;
15523        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15524                EmptyArray.LONG;
15525        long otherPss = 0;
15526        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15527
15528        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15529        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15530                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15531
15532        long totalPss = 0;
15533        long cachedPss = 0;
15534
15535        Debug.MemoryInfo mi = null;
15536        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15537            final ProcessRecord r = procs.get(i);
15538            final IApplicationThread thread;
15539            final int pid;
15540            final int oomAdj;
15541            final boolean hasActivities;
15542            synchronized (this) {
15543                thread = r.thread;
15544                pid = r.pid;
15545                oomAdj = r.getSetAdjWithServices();
15546                hasActivities = r.activities.size() > 0;
15547            }
15548            if (thread != null) {
15549                if (!isCheckinRequest && dumpDetails) {
15550                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15551                }
15552                if (mi == null) {
15553                    mi = new Debug.MemoryInfo();
15554                }
15555                if (dumpDetails || (!brief && !oomOnly)) {
15556                    Debug.getMemoryInfo(pid, mi);
15557                } else {
15558                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15559                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15560                }
15561                if (dumpDetails) {
15562                    if (localOnly) {
15563                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15564                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15565                        if (isCheckinRequest) {
15566                            pw.println();
15567                        }
15568                    } else {
15569                        try {
15570                            pw.flush();
15571                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15572                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15573                        } catch (RemoteException e) {
15574                            if (!isCheckinRequest) {
15575                                pw.println("Got RemoteException!");
15576                                pw.flush();
15577                            }
15578                        }
15579                    }
15580                }
15581
15582                final long myTotalPss = mi.getTotalPss();
15583                final long myTotalUss = mi.getTotalUss();
15584
15585                synchronized (this) {
15586                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15587                        // Record this for posterity if the process has been stable.
15588                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15589                    }
15590                }
15591
15592                if (!isCheckinRequest && mi != null) {
15593                    totalPss += myTotalPss;
15594                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15595                            (hasActivities ? " / activities)" : ")"),
15596                            r.processName, myTotalPss, pid, hasActivities);
15597                    procMems.add(pssItem);
15598                    procMemsMap.put(pid, pssItem);
15599
15600                    nativePss += mi.nativePss;
15601                    dalvikPss += mi.dalvikPss;
15602                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15603                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15604                    }
15605                    otherPss += mi.otherPss;
15606                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15607                        long mem = mi.getOtherPss(j);
15608                        miscPss[j] += mem;
15609                        otherPss -= mem;
15610                    }
15611
15612                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15613                        cachedPss += myTotalPss;
15614                    }
15615
15616                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15617                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15618                                || oomIndex == (oomPss.length-1)) {
15619                            oomPss[oomIndex] += myTotalPss;
15620                            if (oomProcs[oomIndex] == null) {
15621                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15622                            }
15623                            oomProcs[oomIndex].add(pssItem);
15624                            break;
15625                        }
15626                    }
15627                }
15628            }
15629        }
15630
15631        long nativeProcTotalPss = 0;
15632
15633        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15634            // If we are showing aggregations, also look for native processes to
15635            // include so that our aggregations are more accurate.
15636            updateCpuStatsNow();
15637            mi = null;
15638            synchronized (mProcessCpuTracker) {
15639                final int N = mProcessCpuTracker.countStats();
15640                for (int i=0; i<N; i++) {
15641                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15642                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15643                        if (mi == null) {
15644                            mi = new Debug.MemoryInfo();
15645                        }
15646                        if (!brief && !oomOnly) {
15647                            Debug.getMemoryInfo(st.pid, mi);
15648                        } else {
15649                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15650                            mi.nativePrivateDirty = (int)tmpLong[0];
15651                        }
15652
15653                        final long myTotalPss = mi.getTotalPss();
15654                        totalPss += myTotalPss;
15655                        nativeProcTotalPss += myTotalPss;
15656
15657                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15658                                st.name, myTotalPss, st.pid, false);
15659                        procMems.add(pssItem);
15660
15661                        nativePss += mi.nativePss;
15662                        dalvikPss += mi.dalvikPss;
15663                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15664                            dalvikSubitemPss[j] += mi.getOtherPss(
15665                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15666                        }
15667                        otherPss += mi.otherPss;
15668                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15669                            long mem = mi.getOtherPss(j);
15670                            miscPss[j] += mem;
15671                            otherPss -= mem;
15672                        }
15673                        oomPss[0] += myTotalPss;
15674                        if (oomProcs[0] == null) {
15675                            oomProcs[0] = new ArrayList<MemItem>();
15676                        }
15677                        oomProcs[0].add(pssItem);
15678                    }
15679                }
15680            }
15681
15682            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15683
15684            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15685            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15686            if (dalvikSubitemPss.length > 0) {
15687                dalvikItem.subitems = new ArrayList<MemItem>();
15688                for (int j=0; j<dalvikSubitemPss.length; j++) {
15689                    final String name = Debug.MemoryInfo.getOtherLabel(
15690                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15691                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15692                }
15693            }
15694            catMems.add(dalvikItem);
15695            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15696            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15697                String label = Debug.MemoryInfo.getOtherLabel(j);
15698                catMems.add(new MemItem(label, label, miscPss[j], j));
15699            }
15700
15701            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15702            for (int j=0; j<oomPss.length; j++) {
15703                if (oomPss[j] != 0) {
15704                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15705                            : DUMP_MEM_OOM_LABEL[j];
15706                    MemItem item = new MemItem(label, label, oomPss[j],
15707                            DUMP_MEM_OOM_ADJ[j]);
15708                    item.subitems = oomProcs[j];
15709                    oomMems.add(item);
15710                }
15711            }
15712
15713            if (!brief && !oomOnly && !isCompact) {
15714                pw.println();
15715                pw.println("Total PSS by process:");
15716                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15717                pw.println();
15718            }
15719            if (!isCompact) {
15720                pw.println("Total PSS by OOM adjustment:");
15721            }
15722            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15723            if (!brief && !oomOnly) {
15724                PrintWriter out = categoryPw != null ? categoryPw : pw;
15725                if (!isCompact) {
15726                    out.println();
15727                    out.println("Total PSS by category:");
15728                }
15729                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15730            }
15731            if (!isCompact) {
15732                pw.println();
15733            }
15734            MemInfoReader memInfo = new MemInfoReader();
15735            memInfo.readMemInfo();
15736            if (nativeProcTotalPss > 0) {
15737                synchronized (this) {
15738                    final long cachedKb = memInfo.getCachedSizeKb();
15739                    final long freeKb = memInfo.getFreeSizeKb();
15740                    final long zramKb = memInfo.getZramTotalSizeKb();
15741                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15742                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15743                            kernelKb*1024, nativeProcTotalPss*1024);
15744                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15745                            nativeProcTotalPss);
15746                }
15747            }
15748            if (!brief) {
15749                if (!isCompact) {
15750                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15751                    pw.print(" (status ");
15752                    switch (mLastMemoryLevel) {
15753                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15754                            pw.println("normal)");
15755                            break;
15756                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15757                            pw.println("moderate)");
15758                            break;
15759                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15760                            pw.println("low)");
15761                            break;
15762                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15763                            pw.println("critical)");
15764                            break;
15765                        default:
15766                            pw.print(mLastMemoryLevel);
15767                            pw.println(")");
15768                            break;
15769                    }
15770                    pw.print(" Free RAM: ");
15771                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15772                            + memInfo.getFreeSizeKb()));
15773                    pw.print(" (");
15774                    pw.print(stringifyKBSize(cachedPss));
15775                    pw.print(" cached pss + ");
15776                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15777                    pw.print(" cached kernel + ");
15778                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15779                    pw.println(" free)");
15780                } else {
15781                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15782                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15783                            + memInfo.getFreeSizeKb()); pw.print(",");
15784                    pw.println(totalPss - cachedPss);
15785                }
15786            }
15787            if (!isCompact) {
15788                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15789                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15790                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15791                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15792                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15793                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15794                        - memInfo.getKernelUsedSizeKb()));
15795            } else {
15796                pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15797                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15798                        - memInfo.getKernelUsedSizeKb());
15799            }
15800            if (!brief) {
15801                if (memInfo.getZramTotalSizeKb() != 0) {
15802                    if (!isCompact) {
15803                        pw.print("     ZRAM: ");
15804                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15805                                pw.print(" physical used for ");
15806                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15807                                        - memInfo.getSwapFreeSizeKb()));
15808                                pw.print(" in swap (");
15809                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15810                                pw.println(" total swap)");
15811                    } else {
15812                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15813                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15814                                pw.println(memInfo.getSwapFreeSizeKb());
15815                    }
15816                }
15817                final long[] ksm = getKsmInfo();
15818                if (!isCompact) {
15819                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15820                            || ksm[KSM_VOLATILE] != 0) {
15821                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15822                                pw.print(" saved from shared ");
15823                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15824                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15825                                pw.print(" unshared; ");
15826                                pw.print(stringifyKBSize(
15827                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15828                    }
15829                    pw.print("   Tuning: ");
15830                    pw.print(ActivityManager.staticGetMemoryClass());
15831                    pw.print(" (large ");
15832                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15833                    pw.print("), oom ");
15834                    pw.print(stringifySize(
15835                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15836                    pw.print(", restore limit ");
15837                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15838                    if (ActivityManager.isLowRamDeviceStatic()) {
15839                        pw.print(" (low-ram)");
15840                    }
15841                    if (ActivityManager.isHighEndGfx()) {
15842                        pw.print(" (high-end-gfx)");
15843                    }
15844                    pw.println();
15845                } else {
15846                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15847                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15848                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15849                    pw.print("tuning,");
15850                    pw.print(ActivityManager.staticGetMemoryClass());
15851                    pw.print(',');
15852                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15853                    pw.print(',');
15854                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15855                    if (ActivityManager.isLowRamDeviceStatic()) {
15856                        pw.print(",low-ram");
15857                    }
15858                    if (ActivityManager.isHighEndGfx()) {
15859                        pw.print(",high-end-gfx");
15860                    }
15861                    pw.println();
15862                }
15863            }
15864        }
15865    }
15866
15867    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15868            long memtrack, String name) {
15869        sb.append("  ");
15870        sb.append(ProcessList.makeOomAdjString(oomAdj));
15871        sb.append(' ');
15872        sb.append(ProcessList.makeProcStateString(procState));
15873        sb.append(' ');
15874        ProcessList.appendRamKb(sb, pss);
15875        sb.append(": ");
15876        sb.append(name);
15877        if (memtrack > 0) {
15878            sb.append(" (");
15879            sb.append(stringifyKBSize(memtrack));
15880            sb.append(" memtrack)");
15881        }
15882    }
15883
15884    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15885        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15886        sb.append(" (pid ");
15887        sb.append(mi.pid);
15888        sb.append(") ");
15889        sb.append(mi.adjType);
15890        sb.append('\n');
15891        if (mi.adjReason != null) {
15892            sb.append("                      ");
15893            sb.append(mi.adjReason);
15894            sb.append('\n');
15895        }
15896    }
15897
15898    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15899        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15900        for (int i=0, N=memInfos.size(); i<N; i++) {
15901            ProcessMemInfo mi = memInfos.get(i);
15902            infoMap.put(mi.pid, mi);
15903        }
15904        updateCpuStatsNow();
15905        long[] memtrackTmp = new long[1];
15906        synchronized (mProcessCpuTracker) {
15907            final int N = mProcessCpuTracker.countStats();
15908            for (int i=0; i<N; i++) {
15909                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15910                if (st.vsize > 0) {
15911                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15912                    if (pss > 0) {
15913                        if (infoMap.indexOfKey(st.pid) < 0) {
15914                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15915                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15916                            mi.pss = pss;
15917                            mi.memtrack = memtrackTmp[0];
15918                            memInfos.add(mi);
15919                        }
15920                    }
15921                }
15922            }
15923        }
15924
15925        long totalPss = 0;
15926        long totalMemtrack = 0;
15927        for (int i=0, N=memInfos.size(); i<N; i++) {
15928            ProcessMemInfo mi = memInfos.get(i);
15929            if (mi.pss == 0) {
15930                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15931                mi.memtrack = memtrackTmp[0];
15932            }
15933            totalPss += mi.pss;
15934            totalMemtrack += mi.memtrack;
15935        }
15936        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15937            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15938                if (lhs.oomAdj != rhs.oomAdj) {
15939                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15940                }
15941                if (lhs.pss != rhs.pss) {
15942                    return lhs.pss < rhs.pss ? 1 : -1;
15943                }
15944                return 0;
15945            }
15946        });
15947
15948        StringBuilder tag = new StringBuilder(128);
15949        StringBuilder stack = new StringBuilder(128);
15950        tag.append("Low on memory -- ");
15951        appendMemBucket(tag, totalPss, "total", false);
15952        appendMemBucket(stack, totalPss, "total", true);
15953
15954        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15955        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15956        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15957
15958        boolean firstLine = true;
15959        int lastOomAdj = Integer.MIN_VALUE;
15960        long extraNativeRam = 0;
15961        long extraNativeMemtrack = 0;
15962        long cachedPss = 0;
15963        for (int i=0, N=memInfos.size(); i<N; i++) {
15964            ProcessMemInfo mi = memInfos.get(i);
15965
15966            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15967                cachedPss += mi.pss;
15968            }
15969
15970            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15971                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15972                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15973                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15974                if (lastOomAdj != mi.oomAdj) {
15975                    lastOomAdj = mi.oomAdj;
15976                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15977                        tag.append(" / ");
15978                    }
15979                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15980                        if (firstLine) {
15981                            stack.append(":");
15982                            firstLine = false;
15983                        }
15984                        stack.append("\n\t at ");
15985                    } else {
15986                        stack.append("$");
15987                    }
15988                } else {
15989                    tag.append(" ");
15990                    stack.append("$");
15991                }
15992                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15993                    appendMemBucket(tag, mi.pss, mi.name, false);
15994                }
15995                appendMemBucket(stack, mi.pss, mi.name, true);
15996                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15997                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15998                    stack.append("(");
15999                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16000                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16001                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16002                            stack.append(":");
16003                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16004                        }
16005                    }
16006                    stack.append(")");
16007                }
16008            }
16009
16010            appendMemInfo(fullNativeBuilder, mi);
16011            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16012                // The short form only has native processes that are >= 512K.
16013                if (mi.pss >= 512) {
16014                    appendMemInfo(shortNativeBuilder, mi);
16015                } else {
16016                    extraNativeRam += mi.pss;
16017                    extraNativeMemtrack += mi.memtrack;
16018                }
16019            } else {
16020                // Short form has all other details, but if we have collected RAM
16021                // from smaller native processes let's dump a summary of that.
16022                if (extraNativeRam > 0) {
16023                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16024                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16025                    shortNativeBuilder.append('\n');
16026                    extraNativeRam = 0;
16027                }
16028                appendMemInfo(fullJavaBuilder, mi);
16029            }
16030        }
16031
16032        fullJavaBuilder.append("           ");
16033        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16034        fullJavaBuilder.append(": TOTAL");
16035        if (totalMemtrack > 0) {
16036            fullJavaBuilder.append(" (");
16037            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16038            fullJavaBuilder.append(" memtrack)");
16039        } else {
16040        }
16041        fullJavaBuilder.append("\n");
16042
16043        MemInfoReader memInfo = new MemInfoReader();
16044        memInfo.readMemInfo();
16045        final long[] infos = memInfo.getRawInfo();
16046
16047        StringBuilder memInfoBuilder = new StringBuilder(1024);
16048        Debug.getMemInfo(infos);
16049        memInfoBuilder.append("  MemInfo: ");
16050        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16051        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16052        memInfoBuilder.append(stringifyKBSize(
16053                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16054        memInfoBuilder.append(stringifyKBSize(
16055                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16056        memInfoBuilder.append(stringifyKBSize(
16057                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16058        memInfoBuilder.append("           ");
16059        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16060        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16061        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16062        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16063        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16064            memInfoBuilder.append("  ZRAM: ");
16065            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16066            memInfoBuilder.append(" RAM, ");
16067            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16068            memInfoBuilder.append(" swap total, ");
16069            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16070            memInfoBuilder.append(" swap free\n");
16071        }
16072        final long[] ksm = getKsmInfo();
16073        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16074                || ksm[KSM_VOLATILE] != 0) {
16075            memInfoBuilder.append("  KSM: ");
16076            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16077            memInfoBuilder.append(" saved from shared ");
16078            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16079            memInfoBuilder.append("\n       ");
16080            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16081            memInfoBuilder.append(" unshared; ");
16082            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16083            memInfoBuilder.append(" volatile\n");
16084        }
16085        memInfoBuilder.append("  Free RAM: ");
16086        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16087                + memInfo.getFreeSizeKb()));
16088        memInfoBuilder.append("\n");
16089        memInfoBuilder.append("  Used RAM: ");
16090        memInfoBuilder.append(stringifyKBSize(
16091                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16092        memInfoBuilder.append("\n");
16093        memInfoBuilder.append("  Lost RAM: ");
16094        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16095                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16096                - memInfo.getKernelUsedSizeKb()));
16097        memInfoBuilder.append("\n");
16098        Slog.i(TAG, "Low on memory:");
16099        Slog.i(TAG, shortNativeBuilder.toString());
16100        Slog.i(TAG, fullJavaBuilder.toString());
16101        Slog.i(TAG, memInfoBuilder.toString());
16102
16103        StringBuilder dropBuilder = new StringBuilder(1024);
16104        /*
16105        StringWriter oomSw = new StringWriter();
16106        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16107        StringWriter catSw = new StringWriter();
16108        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16109        String[] emptyArgs = new String[] { };
16110        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16111        oomPw.flush();
16112        String oomString = oomSw.toString();
16113        */
16114        dropBuilder.append("Low on memory:");
16115        dropBuilder.append(stack);
16116        dropBuilder.append('\n');
16117        dropBuilder.append(fullNativeBuilder);
16118        dropBuilder.append(fullJavaBuilder);
16119        dropBuilder.append('\n');
16120        dropBuilder.append(memInfoBuilder);
16121        dropBuilder.append('\n');
16122        /*
16123        dropBuilder.append(oomString);
16124        dropBuilder.append('\n');
16125        */
16126        StringWriter catSw = new StringWriter();
16127        synchronized (ActivityManagerService.this) {
16128            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16129            String[] emptyArgs = new String[] { };
16130            catPw.println();
16131            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16132            catPw.println();
16133            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16134                    false, false, null);
16135            catPw.println();
16136            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16137            catPw.flush();
16138        }
16139        dropBuilder.append(catSw.toString());
16140        addErrorToDropBox("lowmem", null, "system_server", null,
16141                null, tag.toString(), dropBuilder.toString(), null, null);
16142        //Slog.i(TAG, "Sent to dropbox:");
16143        //Slog.i(TAG, dropBuilder.toString());
16144        synchronized (ActivityManagerService.this) {
16145            long now = SystemClock.uptimeMillis();
16146            if (mLastMemUsageReportTime < now) {
16147                mLastMemUsageReportTime = now;
16148            }
16149        }
16150    }
16151
16152    /**
16153     * Searches array of arguments for the specified string
16154     * @param args array of argument strings
16155     * @param value value to search for
16156     * @return true if the value is contained in the array
16157     */
16158    private static boolean scanArgs(String[] args, String value) {
16159        if (args != null) {
16160            for (String arg : args) {
16161                if (value.equals(arg)) {
16162                    return true;
16163                }
16164            }
16165        }
16166        return false;
16167    }
16168
16169    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16170            ContentProviderRecord cpr, boolean always) {
16171        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16172
16173        if (!inLaunching || always) {
16174            synchronized (cpr) {
16175                cpr.launchingApp = null;
16176                cpr.notifyAll();
16177            }
16178            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16179            String names[] = cpr.info.authority.split(";");
16180            for (int j = 0; j < names.length; j++) {
16181                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16182            }
16183        }
16184
16185        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16186            ContentProviderConnection conn = cpr.connections.get(i);
16187            if (conn.waiting) {
16188                // If this connection is waiting for the provider, then we don't
16189                // need to mess with its process unless we are always removing
16190                // or for some reason the provider is not currently launching.
16191                if (inLaunching && !always) {
16192                    continue;
16193                }
16194            }
16195            ProcessRecord capp = conn.client;
16196            conn.dead = true;
16197            if (conn.stableCount > 0) {
16198                if (!capp.persistent && capp.thread != null
16199                        && capp.pid != 0
16200                        && capp.pid != MY_PID) {
16201                    capp.kill("depends on provider "
16202                            + cpr.name.flattenToShortString()
16203                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16204                }
16205            } else if (capp.thread != null && conn.provider.provider != null) {
16206                try {
16207                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16208                } catch (RemoteException e) {
16209                }
16210                // In the protocol here, we don't expect the client to correctly
16211                // clean up this connection, we'll just remove it.
16212                cpr.connections.remove(i);
16213                if (conn.client.conProviders.remove(conn)) {
16214                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16215                }
16216            }
16217        }
16218
16219        if (inLaunching && always) {
16220            mLaunchingProviders.remove(cpr);
16221        }
16222        return inLaunching;
16223    }
16224
16225    /**
16226     * Main code for cleaning up a process when it has gone away.  This is
16227     * called both as a result of the process dying, or directly when stopping
16228     * a process when running in single process mode.
16229     *
16230     * @return Returns true if the given process has been restarted, so the
16231     * app that was passed in must remain on the process lists.
16232     */
16233    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16234            boolean restarting, boolean allowRestart, int index) {
16235        if (index >= 0) {
16236            removeLruProcessLocked(app);
16237            ProcessList.remove(app.pid);
16238        }
16239
16240        mProcessesToGc.remove(app);
16241        mPendingPssProcesses.remove(app);
16242
16243        // Dismiss any open dialogs.
16244        if (app.crashDialog != null && !app.forceCrashReport) {
16245            app.crashDialog.dismiss();
16246            app.crashDialog = null;
16247        }
16248        if (app.anrDialog != null) {
16249            app.anrDialog.dismiss();
16250            app.anrDialog = null;
16251        }
16252        if (app.waitDialog != null) {
16253            app.waitDialog.dismiss();
16254            app.waitDialog = null;
16255        }
16256
16257        app.crashing = false;
16258        app.notResponding = false;
16259
16260        app.resetPackageList(mProcessStats);
16261        app.unlinkDeathRecipient();
16262        app.makeInactive(mProcessStats);
16263        app.waitingToKill = null;
16264        app.forcingToForeground = null;
16265        updateProcessForegroundLocked(app, false, false);
16266        app.foregroundActivities = false;
16267        app.hasShownUi = false;
16268        app.treatLikeActivity = false;
16269        app.hasAboveClient = false;
16270        app.hasClientActivities = false;
16271
16272        mServices.killServicesLocked(app, allowRestart);
16273
16274        boolean restart = false;
16275
16276        // Remove published content providers.
16277        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16278            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16279            final boolean always = app.bad || !allowRestart;
16280            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16281            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16282                // We left the provider in the launching list, need to
16283                // restart it.
16284                restart = true;
16285            }
16286
16287            cpr.provider = null;
16288            cpr.proc = null;
16289        }
16290        app.pubProviders.clear();
16291
16292        // Take care of any launching providers waiting for this process.
16293        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16294            restart = true;
16295        }
16296
16297        // Unregister from connected content providers.
16298        if (!app.conProviders.isEmpty()) {
16299            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16300                ContentProviderConnection conn = app.conProviders.get(i);
16301                conn.provider.connections.remove(conn);
16302                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16303                        conn.provider.name);
16304            }
16305            app.conProviders.clear();
16306        }
16307
16308        // At this point there may be remaining entries in mLaunchingProviders
16309        // where we were the only one waiting, so they are no longer of use.
16310        // Look for these and clean up if found.
16311        // XXX Commented out for now.  Trying to figure out a way to reproduce
16312        // the actual situation to identify what is actually going on.
16313        if (false) {
16314            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16315                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16316                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16317                    synchronized (cpr) {
16318                        cpr.launchingApp = null;
16319                        cpr.notifyAll();
16320                    }
16321                }
16322            }
16323        }
16324
16325        skipCurrentReceiverLocked(app);
16326
16327        // Unregister any receivers.
16328        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16329            removeReceiverLocked(app.receivers.valueAt(i));
16330        }
16331        app.receivers.clear();
16332
16333        // If the app is undergoing backup, tell the backup manager about it
16334        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16335            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16336                    + mBackupTarget.appInfo + " died during backup");
16337            try {
16338                IBackupManager bm = IBackupManager.Stub.asInterface(
16339                        ServiceManager.getService(Context.BACKUP_SERVICE));
16340                bm.agentDisconnected(app.info.packageName);
16341            } catch (RemoteException e) {
16342                // can't happen; backup manager is local
16343            }
16344        }
16345
16346        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16347            ProcessChangeItem item = mPendingProcessChanges.get(i);
16348            if (item.pid == app.pid) {
16349                mPendingProcessChanges.remove(i);
16350                mAvailProcessChanges.add(item);
16351            }
16352        }
16353        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16354                null).sendToTarget();
16355
16356        // If the caller is restarting this app, then leave it in its
16357        // current lists and let the caller take care of it.
16358        if (restarting) {
16359            return false;
16360        }
16361
16362        if (!app.persistent || app.isolated) {
16363            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16364                    "Removing non-persistent process during cleanup: " + app);
16365            removeProcessNameLocked(app.processName, app.uid);
16366            if (mHeavyWeightProcess == app) {
16367                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16368                        mHeavyWeightProcess.userId, 0));
16369                mHeavyWeightProcess = null;
16370            }
16371        } else if (!app.removed) {
16372            // This app is persistent, so we need to keep its record around.
16373            // If it is not already on the pending app list, add it there
16374            // and start a new process for it.
16375            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16376                mPersistentStartingProcesses.add(app);
16377                restart = true;
16378            }
16379        }
16380        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16381                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16382        mProcessesOnHold.remove(app);
16383
16384        if (app == mHomeProcess) {
16385            mHomeProcess = null;
16386        }
16387        if (app == mPreviousProcess) {
16388            mPreviousProcess = null;
16389        }
16390
16391        if (restart && !app.isolated) {
16392            // We have components that still need to be running in the
16393            // process, so re-launch it.
16394            if (index < 0) {
16395                ProcessList.remove(app.pid);
16396            }
16397            addProcessNameLocked(app);
16398            startProcessLocked(app, "restart", app.processName);
16399            return true;
16400        } else if (app.pid > 0 && app.pid != MY_PID) {
16401            // Goodbye!
16402            boolean removed;
16403            synchronized (mPidsSelfLocked) {
16404                mPidsSelfLocked.remove(app.pid);
16405                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16406            }
16407            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16408            if (app.isolated) {
16409                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16410            }
16411            app.setPid(0);
16412        }
16413        return false;
16414    }
16415
16416    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16417        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16418            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16419            if (cpr.launchingApp == app) {
16420                return true;
16421            }
16422        }
16423        return false;
16424    }
16425
16426    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16427        // Look through the content providers we are waiting to have launched,
16428        // and if any run in this process then either schedule a restart of
16429        // the process or kill the client waiting for it if this process has
16430        // gone bad.
16431        boolean restart = false;
16432        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16433            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16434            if (cpr.launchingApp == app) {
16435                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16436                    restart = true;
16437                } else {
16438                    removeDyingProviderLocked(app, cpr, true);
16439                }
16440            }
16441        }
16442        return restart;
16443    }
16444
16445    // =========================================================
16446    // SERVICES
16447    // =========================================================
16448
16449    @Override
16450    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16451            int flags) {
16452        enforceNotIsolatedCaller("getServices");
16453        synchronized (this) {
16454            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16455        }
16456    }
16457
16458    @Override
16459    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16460        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16461        synchronized (this) {
16462            return mServices.getRunningServiceControlPanelLocked(name);
16463        }
16464    }
16465
16466    @Override
16467    public ComponentName startService(IApplicationThread caller, Intent service,
16468            String resolvedType, String callingPackage, int userId)
16469            throws TransactionTooLargeException {
16470        enforceNotIsolatedCaller("startService");
16471        // Refuse possible leaked file descriptors
16472        if (service != null && service.hasFileDescriptors() == true) {
16473            throw new IllegalArgumentException("File descriptors passed in Intent");
16474        }
16475
16476        if (callingPackage == null) {
16477            throw new IllegalArgumentException("callingPackage cannot be null");
16478        }
16479
16480        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16481                "startService: " + service + " type=" + resolvedType);
16482        synchronized(this) {
16483            final int callingPid = Binder.getCallingPid();
16484            final int callingUid = Binder.getCallingUid();
16485            final long origId = Binder.clearCallingIdentity();
16486            ComponentName res = mServices.startServiceLocked(caller, service,
16487                    resolvedType, callingPid, callingUid, callingPackage, userId);
16488            Binder.restoreCallingIdentity(origId);
16489            return res;
16490        }
16491    }
16492
16493    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16494            String callingPackage, int userId)
16495            throws TransactionTooLargeException {
16496        synchronized(this) {
16497            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16498                    "startServiceInPackage: " + service + " type=" + resolvedType);
16499            final long origId = Binder.clearCallingIdentity();
16500            ComponentName res = mServices.startServiceLocked(null, service,
16501                    resolvedType, -1, uid, callingPackage, userId);
16502            Binder.restoreCallingIdentity(origId);
16503            return res;
16504        }
16505    }
16506
16507    @Override
16508    public int stopService(IApplicationThread caller, Intent service,
16509            String resolvedType, int userId) {
16510        enforceNotIsolatedCaller("stopService");
16511        // Refuse possible leaked file descriptors
16512        if (service != null && service.hasFileDescriptors() == true) {
16513            throw new IllegalArgumentException("File descriptors passed in Intent");
16514        }
16515
16516        synchronized(this) {
16517            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16518        }
16519    }
16520
16521    @Override
16522    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16523        enforceNotIsolatedCaller("peekService");
16524        // Refuse possible leaked file descriptors
16525        if (service != null && service.hasFileDescriptors() == true) {
16526            throw new IllegalArgumentException("File descriptors passed in Intent");
16527        }
16528
16529        if (callingPackage == null) {
16530            throw new IllegalArgumentException("callingPackage cannot be null");
16531        }
16532
16533        synchronized(this) {
16534            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16535        }
16536    }
16537
16538    @Override
16539    public boolean stopServiceToken(ComponentName className, IBinder token,
16540            int startId) {
16541        synchronized(this) {
16542            return mServices.stopServiceTokenLocked(className, token, startId);
16543        }
16544    }
16545
16546    @Override
16547    public void setServiceForeground(ComponentName className, IBinder token,
16548            int id, Notification notification, boolean removeNotification) {
16549        synchronized(this) {
16550            mServices.setServiceForegroundLocked(className, token, id, notification,
16551                    removeNotification);
16552        }
16553    }
16554
16555    @Override
16556    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16557            boolean requireFull, String name, String callerPackage) {
16558        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16559                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16560    }
16561
16562    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16563            String className, int flags) {
16564        boolean result = false;
16565        // For apps that don't have pre-defined UIDs, check for permission
16566        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16567            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16568                if (ActivityManager.checkUidPermission(
16569                        INTERACT_ACROSS_USERS,
16570                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16571                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16572                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16573                            + " requests FLAG_SINGLE_USER, but app does not hold "
16574                            + INTERACT_ACROSS_USERS;
16575                    Slog.w(TAG, msg);
16576                    throw new SecurityException(msg);
16577                }
16578                // Permission passed
16579                result = true;
16580            }
16581        } else if ("system".equals(componentProcessName)) {
16582            result = true;
16583        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16584            // Phone app and persistent apps are allowed to export singleuser providers.
16585            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16586                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16587        }
16588        if (DEBUG_MU) Slog.v(TAG_MU,
16589                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16590                + Integer.toHexString(flags) + ") = " + result);
16591        return result;
16592    }
16593
16594    /**
16595     * Checks to see if the caller is in the same app as the singleton
16596     * component, or the component is in a special app. It allows special apps
16597     * to export singleton components but prevents exporting singleton
16598     * components for regular apps.
16599     */
16600    boolean isValidSingletonCall(int callingUid, int componentUid) {
16601        int componentAppId = UserHandle.getAppId(componentUid);
16602        return UserHandle.isSameApp(callingUid, componentUid)
16603                || componentAppId == Process.SYSTEM_UID
16604                || componentAppId == Process.PHONE_UID
16605                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16606                        == PackageManager.PERMISSION_GRANTED;
16607    }
16608
16609    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16610            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16611            int userId) throws TransactionTooLargeException {
16612        enforceNotIsolatedCaller("bindService");
16613
16614        // Refuse possible leaked file descriptors
16615        if (service != null && service.hasFileDescriptors() == true) {
16616            throw new IllegalArgumentException("File descriptors passed in Intent");
16617        }
16618
16619        if (callingPackage == null) {
16620            throw new IllegalArgumentException("callingPackage cannot be null");
16621        }
16622
16623        synchronized(this) {
16624            return mServices.bindServiceLocked(caller, token, service,
16625                    resolvedType, connection, flags, callingPackage, userId);
16626        }
16627    }
16628
16629    public boolean unbindService(IServiceConnection connection) {
16630        synchronized (this) {
16631            return mServices.unbindServiceLocked(connection);
16632        }
16633    }
16634
16635    public void publishService(IBinder token, Intent intent, IBinder service) {
16636        // Refuse possible leaked file descriptors
16637        if (intent != null && intent.hasFileDescriptors() == true) {
16638            throw new IllegalArgumentException("File descriptors passed in Intent");
16639        }
16640
16641        synchronized(this) {
16642            if (!(token instanceof ServiceRecord)) {
16643                throw new IllegalArgumentException("Invalid service token");
16644            }
16645            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16646        }
16647    }
16648
16649    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16650        // Refuse possible leaked file descriptors
16651        if (intent != null && intent.hasFileDescriptors() == true) {
16652            throw new IllegalArgumentException("File descriptors passed in Intent");
16653        }
16654
16655        synchronized(this) {
16656            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16657        }
16658    }
16659
16660    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16661        synchronized(this) {
16662            if (!(token instanceof ServiceRecord)) {
16663                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16664                throw new IllegalArgumentException("Invalid service token");
16665            }
16666            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16667        }
16668    }
16669
16670    // =========================================================
16671    // BACKUP AND RESTORE
16672    // =========================================================
16673
16674    // Cause the target app to be launched if necessary and its backup agent
16675    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16676    // activity manager to announce its creation.
16677    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16678        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16679                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16680        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16681
16682        synchronized(this) {
16683            // !!! TODO: currently no check here that we're already bound
16684            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16685            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16686            synchronized (stats) {
16687                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16688            }
16689
16690            // Backup agent is now in use, its package can't be stopped.
16691            try {
16692                AppGlobals.getPackageManager().setPackageStoppedState(
16693                        app.packageName, false, UserHandle.getUserId(app.uid));
16694            } catch (RemoteException e) {
16695            } catch (IllegalArgumentException e) {
16696                Slog.w(TAG, "Failed trying to unstop package "
16697                        + app.packageName + ": " + e);
16698            }
16699
16700            BackupRecord r = new BackupRecord(ss, app, backupMode);
16701            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16702                    ? new ComponentName(app.packageName, app.backupAgentName)
16703                    : new ComponentName("android", "FullBackupAgent");
16704            // startProcessLocked() returns existing proc's record if it's already running
16705            ProcessRecord proc = startProcessLocked(app.processName, app,
16706                    false, 0, "backup", hostingName, false, false, false);
16707            if (proc == null) {
16708                Slog.e(TAG, "Unable to start backup agent process " + r);
16709                return false;
16710            }
16711
16712            r.app = proc;
16713            mBackupTarget = r;
16714            mBackupAppName = app.packageName;
16715
16716            // Try not to kill the process during backup
16717            updateOomAdjLocked(proc);
16718
16719            // If the process is already attached, schedule the creation of the backup agent now.
16720            // If it is not yet live, this will be done when it attaches to the framework.
16721            if (proc.thread != null) {
16722                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16723                try {
16724                    proc.thread.scheduleCreateBackupAgent(app,
16725                            compatibilityInfoForPackageLocked(app), backupMode);
16726                } catch (RemoteException e) {
16727                    // Will time out on the backup manager side
16728                }
16729            } else {
16730                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16731            }
16732            // Invariants: at this point, the target app process exists and the application
16733            // is either already running or in the process of coming up.  mBackupTarget and
16734            // mBackupAppName describe the app, so that when it binds back to the AM we
16735            // know that it's scheduled for a backup-agent operation.
16736        }
16737
16738        return true;
16739    }
16740
16741    @Override
16742    public void clearPendingBackup() {
16743        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16744        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16745
16746        synchronized (this) {
16747            mBackupTarget = null;
16748            mBackupAppName = null;
16749        }
16750    }
16751
16752    // A backup agent has just come up
16753    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16754        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16755                + " = " + agent);
16756
16757        synchronized(this) {
16758            if (!agentPackageName.equals(mBackupAppName)) {
16759                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16760                return;
16761            }
16762        }
16763
16764        long oldIdent = Binder.clearCallingIdentity();
16765        try {
16766            IBackupManager bm = IBackupManager.Stub.asInterface(
16767                    ServiceManager.getService(Context.BACKUP_SERVICE));
16768            bm.agentConnected(agentPackageName, agent);
16769        } catch (RemoteException e) {
16770            // can't happen; the backup manager service is local
16771        } catch (Exception e) {
16772            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16773            e.printStackTrace();
16774        } finally {
16775            Binder.restoreCallingIdentity(oldIdent);
16776        }
16777    }
16778
16779    // done with this agent
16780    public void unbindBackupAgent(ApplicationInfo appInfo) {
16781        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16782        if (appInfo == null) {
16783            Slog.w(TAG, "unbind backup agent for null app");
16784            return;
16785        }
16786
16787        synchronized(this) {
16788            try {
16789                if (mBackupAppName == null) {
16790                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16791                    return;
16792                }
16793
16794                if (!mBackupAppName.equals(appInfo.packageName)) {
16795                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16796                    return;
16797                }
16798
16799                // Not backing this app up any more; reset its OOM adjustment
16800                final ProcessRecord proc = mBackupTarget.app;
16801                updateOomAdjLocked(proc);
16802
16803                // If the app crashed during backup, 'thread' will be null here
16804                if (proc.thread != null) {
16805                    try {
16806                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16807                                compatibilityInfoForPackageLocked(appInfo));
16808                    } catch (Exception e) {
16809                        Slog.e(TAG, "Exception when unbinding backup agent:");
16810                        e.printStackTrace();
16811                    }
16812                }
16813            } finally {
16814                mBackupTarget = null;
16815                mBackupAppName = null;
16816            }
16817        }
16818    }
16819    // =========================================================
16820    // BROADCASTS
16821    // =========================================================
16822
16823    boolean isPendingBroadcastProcessLocked(int pid) {
16824        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16825                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16826    }
16827
16828    void skipPendingBroadcastLocked(int pid) {
16829            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16830            for (BroadcastQueue queue : mBroadcastQueues) {
16831                queue.skipPendingBroadcastLocked(pid);
16832            }
16833    }
16834
16835    // The app just attached; send any pending broadcasts that it should receive
16836    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16837        boolean didSomething = false;
16838        for (BroadcastQueue queue : mBroadcastQueues) {
16839            didSomething |= queue.sendPendingBroadcastsLocked(app);
16840        }
16841        return didSomething;
16842    }
16843
16844    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16845            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16846        enforceNotIsolatedCaller("registerReceiver");
16847        ArrayList<Intent> stickyIntents = null;
16848        ProcessRecord callerApp = null;
16849        int callingUid;
16850        int callingPid;
16851        synchronized(this) {
16852            if (caller != null) {
16853                callerApp = getRecordForAppLocked(caller);
16854                if (callerApp == null) {
16855                    throw new SecurityException(
16856                            "Unable to find app for caller " + caller
16857                            + " (pid=" + Binder.getCallingPid()
16858                            + ") when registering receiver " + receiver);
16859                }
16860                if (callerApp.info.uid != Process.SYSTEM_UID &&
16861                        !callerApp.pkgList.containsKey(callerPackage) &&
16862                        !"android".equals(callerPackage)) {
16863                    throw new SecurityException("Given caller package " + callerPackage
16864                            + " is not running in process " + callerApp);
16865                }
16866                callingUid = callerApp.info.uid;
16867                callingPid = callerApp.pid;
16868            } else {
16869                callerPackage = null;
16870                callingUid = Binder.getCallingUid();
16871                callingPid = Binder.getCallingPid();
16872            }
16873
16874            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16875                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16876
16877            Iterator<String> actions = filter.actionsIterator();
16878            if (actions == null) {
16879                ArrayList<String> noAction = new ArrayList<String>(1);
16880                noAction.add(null);
16881                actions = noAction.iterator();
16882            }
16883
16884            // Collect stickies of users
16885            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16886            while (actions.hasNext()) {
16887                String action = actions.next();
16888                for (int id : userIds) {
16889                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16890                    if (stickies != null) {
16891                        ArrayList<Intent> intents = stickies.get(action);
16892                        if (intents != null) {
16893                            if (stickyIntents == null) {
16894                                stickyIntents = new ArrayList<Intent>();
16895                            }
16896                            stickyIntents.addAll(intents);
16897                        }
16898                    }
16899                }
16900            }
16901        }
16902
16903        ArrayList<Intent> allSticky = null;
16904        if (stickyIntents != null) {
16905            final ContentResolver resolver = mContext.getContentResolver();
16906            // Look for any matching sticky broadcasts...
16907            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16908                Intent intent = stickyIntents.get(i);
16909                // If intent has scheme "content", it will need to acccess
16910                // provider that needs to lock mProviderMap in ActivityThread
16911                // and also it may need to wait application response, so we
16912                // cannot lock ActivityManagerService here.
16913                if (filter.match(resolver, intent, true, TAG) >= 0) {
16914                    if (allSticky == null) {
16915                        allSticky = new ArrayList<Intent>();
16916                    }
16917                    allSticky.add(intent);
16918                }
16919            }
16920        }
16921
16922        // The first sticky in the list is returned directly back to the client.
16923        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16924        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16925        if (receiver == null) {
16926            return sticky;
16927        }
16928
16929        synchronized (this) {
16930            if (callerApp != null && (callerApp.thread == null
16931                    || callerApp.thread.asBinder() != caller.asBinder())) {
16932                // Original caller already died
16933                return null;
16934            }
16935            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16936            if (rl == null) {
16937                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16938                        userId, receiver);
16939                if (rl.app != null) {
16940                    rl.app.receivers.add(rl);
16941                } else {
16942                    try {
16943                        receiver.asBinder().linkToDeath(rl, 0);
16944                    } catch (RemoteException e) {
16945                        return sticky;
16946                    }
16947                    rl.linkedToDeath = true;
16948                }
16949                mRegisteredReceivers.put(receiver.asBinder(), rl);
16950            } else if (rl.uid != callingUid) {
16951                throw new IllegalArgumentException(
16952                        "Receiver requested to register for uid " + callingUid
16953                        + " was previously registered for uid " + rl.uid);
16954            } else if (rl.pid != callingPid) {
16955                throw new IllegalArgumentException(
16956                        "Receiver requested to register for pid " + callingPid
16957                        + " was previously registered for pid " + rl.pid);
16958            } else if (rl.userId != userId) {
16959                throw new IllegalArgumentException(
16960                        "Receiver requested to register for user " + userId
16961                        + " was previously registered for user " + rl.userId);
16962            }
16963            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16964                    permission, callingUid, userId);
16965            rl.add(bf);
16966            if (!bf.debugCheck()) {
16967                Slog.w(TAG, "==> For Dynamic broadcast");
16968            }
16969            mReceiverResolver.addFilter(bf);
16970
16971            // Enqueue broadcasts for all existing stickies that match
16972            // this filter.
16973            if (allSticky != null) {
16974                ArrayList receivers = new ArrayList();
16975                receivers.add(bf);
16976
16977                final int stickyCount = allSticky.size();
16978                for (int i = 0; i < stickyCount; i++) {
16979                    Intent intent = allSticky.get(i);
16980                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16981                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16982                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16983                            null, 0, null, null, false, true, true, -1);
16984                    queue.enqueueParallelBroadcastLocked(r);
16985                    queue.scheduleBroadcastsLocked();
16986                }
16987            }
16988
16989            return sticky;
16990        }
16991    }
16992
16993    public void unregisterReceiver(IIntentReceiver receiver) {
16994        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16995
16996        final long origId = Binder.clearCallingIdentity();
16997        try {
16998            boolean doTrim = false;
16999
17000            synchronized(this) {
17001                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17002                if (rl != null) {
17003                    final BroadcastRecord r = rl.curBroadcast;
17004                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17005                        final boolean doNext = r.queue.finishReceiverLocked(
17006                                r, r.resultCode, r.resultData, r.resultExtras,
17007                                r.resultAbort, false);
17008                        if (doNext) {
17009                            doTrim = true;
17010                            r.queue.processNextBroadcast(false);
17011                        }
17012                    }
17013
17014                    if (rl.app != null) {
17015                        rl.app.receivers.remove(rl);
17016                    }
17017                    removeReceiverLocked(rl);
17018                    if (rl.linkedToDeath) {
17019                        rl.linkedToDeath = false;
17020                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17021                    }
17022                }
17023            }
17024
17025            // If we actually concluded any broadcasts, we might now be able
17026            // to trim the recipients' apps from our working set
17027            if (doTrim) {
17028                trimApplications();
17029                return;
17030            }
17031
17032        } finally {
17033            Binder.restoreCallingIdentity(origId);
17034        }
17035    }
17036
17037    void removeReceiverLocked(ReceiverList rl) {
17038        mRegisteredReceivers.remove(rl.receiver.asBinder());
17039        for (int i = rl.size() - 1; i >= 0; i--) {
17040            mReceiverResolver.removeFilter(rl.get(i));
17041        }
17042    }
17043
17044    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17045        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17046            ProcessRecord r = mLruProcesses.get(i);
17047            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17048                try {
17049                    r.thread.dispatchPackageBroadcast(cmd, packages);
17050                } catch (RemoteException ex) {
17051                }
17052            }
17053        }
17054    }
17055
17056    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17057            int callingUid, int[] users) {
17058        // TODO: come back and remove this assumption to triage all broadcasts
17059        int pmFlags = STOCK_PM_FLAGS | PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
17060
17061        List<ResolveInfo> receivers = null;
17062        try {
17063            HashSet<ComponentName> singleUserReceivers = null;
17064            boolean scannedFirstReceivers = false;
17065            for (int user : users) {
17066                // Skip users that have Shell restrictions
17067                if (callingUid == Process.SHELL_UID
17068                        && mUserController.hasUserRestriction(
17069                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
17070                    continue;
17071                }
17072                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17073                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
17074                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17075                    // If this is not the system user, we need to check for
17076                    // any receivers that should be filtered out.
17077                    for (int i=0; i<newReceivers.size(); i++) {
17078                        ResolveInfo ri = newReceivers.get(i);
17079                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17080                            newReceivers.remove(i);
17081                            i--;
17082                        }
17083                    }
17084                }
17085                if (newReceivers != null && newReceivers.size() == 0) {
17086                    newReceivers = null;
17087                }
17088                if (receivers == null) {
17089                    receivers = newReceivers;
17090                } else if (newReceivers != null) {
17091                    // We need to concatenate the additional receivers
17092                    // found with what we have do far.  This would be easy,
17093                    // but we also need to de-dup any receivers that are
17094                    // singleUser.
17095                    if (!scannedFirstReceivers) {
17096                        // Collect any single user receivers we had already retrieved.
17097                        scannedFirstReceivers = true;
17098                        for (int i=0; i<receivers.size(); i++) {
17099                            ResolveInfo ri = receivers.get(i);
17100                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17101                                ComponentName cn = new ComponentName(
17102                                        ri.activityInfo.packageName, ri.activityInfo.name);
17103                                if (singleUserReceivers == null) {
17104                                    singleUserReceivers = new HashSet<ComponentName>();
17105                                }
17106                                singleUserReceivers.add(cn);
17107                            }
17108                        }
17109                    }
17110                    // Add the new results to the existing results, tracking
17111                    // and de-dupping single user receivers.
17112                    for (int i=0; i<newReceivers.size(); i++) {
17113                        ResolveInfo ri = newReceivers.get(i);
17114                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17115                            ComponentName cn = new ComponentName(
17116                                    ri.activityInfo.packageName, ri.activityInfo.name);
17117                            if (singleUserReceivers == null) {
17118                                singleUserReceivers = new HashSet<ComponentName>();
17119                            }
17120                            if (!singleUserReceivers.contains(cn)) {
17121                                singleUserReceivers.add(cn);
17122                                receivers.add(ri);
17123                            }
17124                        } else {
17125                            receivers.add(ri);
17126                        }
17127                    }
17128                }
17129            }
17130        } catch (RemoteException ex) {
17131            // pm is in same process, this will never happen.
17132        }
17133        return receivers;
17134    }
17135
17136    final int broadcastIntentLocked(ProcessRecord callerApp,
17137            String callerPackage, Intent intent, String resolvedType,
17138            IIntentReceiver resultTo, int resultCode, String resultData,
17139            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17140            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17141        intent = new Intent(intent);
17142
17143        // By default broadcasts do not go to stopped apps.
17144        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17145
17146        // If we have not finished booting, don't allow this to launch new processes.
17147        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17148            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17149        }
17150
17151        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17152                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17153                + " ordered=" + ordered + " userid=" + userId);
17154        if ((resultTo != null) && !ordered) {
17155            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17156        }
17157
17158        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17159                ALLOW_NON_FULL, "broadcast", callerPackage);
17160
17161        // Make sure that the user who is receiving this broadcast is running.
17162        // If not, we will just skip it. Make an exception for shutdown broadcasts
17163        // and upgrade steps.
17164
17165        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17166            if ((callingUid != Process.SYSTEM_UID
17167                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17168                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17169                Slog.w(TAG, "Skipping broadcast of " + intent
17170                        + ": user " + userId + " is stopped");
17171                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17172            }
17173        }
17174
17175        BroadcastOptions brOptions = null;
17176        if (bOptions != null) {
17177            brOptions = new BroadcastOptions(bOptions);
17178            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17179                // See if the caller is allowed to do this.  Note we are checking against
17180                // the actual real caller (not whoever provided the operation as say a
17181                // PendingIntent), because that who is actually supplied the arguments.
17182                if (checkComponentPermission(
17183                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17184                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17185                        != PackageManager.PERMISSION_GRANTED) {
17186                    String msg = "Permission Denial: " + intent.getAction()
17187                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17188                            + ", uid=" + callingUid + ")"
17189                            + " requires "
17190                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17191                    Slog.w(TAG, msg);
17192                    throw new SecurityException(msg);
17193                }
17194            }
17195        }
17196
17197        // Verify that protected broadcasts are only being sent by system code,
17198        // and that system code is only sending protected broadcasts.
17199        final String action = intent.getAction();
17200        final boolean isProtectedBroadcast;
17201        try {
17202            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17203        } catch (RemoteException e) {
17204            Slog.w(TAG, "Remote exception", e);
17205            return ActivityManager.BROADCAST_SUCCESS;
17206        }
17207
17208        final boolean isCallerSystem;
17209        switch (UserHandle.getAppId(callingUid)) {
17210            case Process.ROOT_UID:
17211            case Process.SYSTEM_UID:
17212            case Process.PHONE_UID:
17213            case Process.SHELL_UID:
17214            case Process.BLUETOOTH_UID:
17215            case Process.NFC_UID:
17216                isCallerSystem = true;
17217                break;
17218            default:
17219                isCallerSystem = (callerApp != null) && callerApp.persistent;
17220                break;
17221        }
17222
17223        if (isCallerSystem) {
17224            if (isProtectedBroadcast
17225                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17226                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17227                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17228                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17229                // Broadcast is either protected, or it's a public action that
17230                // we've relaxed, so it's fine for system internals to send.
17231            } else {
17232                // The vast majority of broadcasts sent from system internals
17233                // should be protected to avoid security holes, so yell loudly
17234                // to ensure we examine these cases.
17235                Log.wtf(TAG, "Sending non-protected broadcast " + action
17236                        + " from system", new Throwable());
17237            }
17238
17239        } else {
17240            if (isProtectedBroadcast) {
17241                String msg = "Permission Denial: not allowed to send broadcast "
17242                        + action + " from pid="
17243                        + callingPid + ", uid=" + callingUid;
17244                Slog.w(TAG, msg);
17245                throw new SecurityException(msg);
17246
17247            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17248                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17249                // Special case for compatibility: we don't want apps to send this,
17250                // but historically it has not been protected and apps may be using it
17251                // to poke their own app widget.  So, instead of making it protected,
17252                // just limit it to the caller.
17253                if (callerApp == null) {
17254                    String msg = "Permission Denial: not allowed to send broadcast "
17255                            + action + " from unknown caller.";
17256                    Slog.w(TAG, msg);
17257                    throw new SecurityException(msg);
17258                } else if (intent.getComponent() != null) {
17259                    // They are good enough to send to an explicit component...  verify
17260                    // it is being sent to the calling app.
17261                    if (!intent.getComponent().getPackageName().equals(
17262                            callerApp.info.packageName)) {
17263                        String msg = "Permission Denial: not allowed to send broadcast "
17264                                + action + " to "
17265                                + intent.getComponent().getPackageName() + " from "
17266                                + callerApp.info.packageName;
17267                        Slog.w(TAG, msg);
17268                        throw new SecurityException(msg);
17269                    }
17270                } else {
17271                    // Limit broadcast to their own package.
17272                    intent.setPackage(callerApp.info.packageName);
17273                }
17274            }
17275        }
17276
17277        if (action != null) {
17278            switch (action) {
17279                case Intent.ACTION_UID_REMOVED:
17280                case Intent.ACTION_PACKAGE_REMOVED:
17281                case Intent.ACTION_PACKAGE_CHANGED:
17282                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17283                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17284                    // Handle special intents: if this broadcast is from the package
17285                    // manager about a package being removed, we need to remove all of
17286                    // its activities from the history stack.
17287                    if (checkComponentPermission(
17288                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17289                            callingPid, callingUid, -1, true)
17290                            != PackageManager.PERMISSION_GRANTED) {
17291                        String msg = "Permission Denial: " + intent.getAction()
17292                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17293                                + ", uid=" + callingUid + ")"
17294                                + " requires "
17295                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17296                        Slog.w(TAG, msg);
17297                        throw new SecurityException(msg);
17298                    }
17299                    switch (action) {
17300                        case Intent.ACTION_UID_REMOVED:
17301                            final Bundle intentExtras = intent.getExtras();
17302                            final int uid = intentExtras != null
17303                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17304                            if (uid >= 0) {
17305                                mBatteryStatsService.removeUid(uid);
17306                                mAppOpsService.uidRemoved(uid);
17307                            }
17308                            break;
17309                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17310                            // If resources are unavailable just force stop all those packages
17311                            // and flush the attribute cache as well.
17312                            String list[] =
17313                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17314                            if (list != null && list.length > 0) {
17315                                for (int i = 0; i < list.length; i++) {
17316                                    forceStopPackageLocked(list[i], -1, false, true, true,
17317                                            false, false, userId, "storage unmount");
17318                                }
17319                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17320                                sendPackageBroadcastLocked(
17321                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17322                                        userId);
17323                            }
17324                            break;
17325                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17326                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17327                            break;
17328                        case Intent.ACTION_PACKAGE_REMOVED:
17329                        case Intent.ACTION_PACKAGE_CHANGED:
17330                            Uri data = intent.getData();
17331                            String ssp;
17332                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17333                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17334                                boolean fullUninstall = removed &&
17335                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17336                                final boolean killProcess =
17337                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17338                                if (killProcess) {
17339                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17340                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17341                                            false, true, true, false, fullUninstall, userId,
17342                                            removed ? "pkg removed" : "pkg changed");
17343                                }
17344                                if (removed) {
17345                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17346                                            new String[] {ssp}, userId);
17347                                    if (fullUninstall) {
17348                                        mAppOpsService.packageRemoved(
17349                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17350
17351                                        // Remove all permissions granted from/to this package
17352                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17353
17354                                        removeTasksByPackageNameLocked(ssp, userId);
17355                                        mBatteryStatsService.notePackageUninstalled(ssp);
17356                                    }
17357                                } else {
17358                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17359                                            intent.getStringArrayExtra(
17360                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17361                                }
17362                            }
17363                            break;
17364                    }
17365                    break;
17366                case Intent.ACTION_PACKAGE_ADDED:
17367                    // Special case for adding a package: by default turn on compatibility mode.
17368                    Uri data = intent.getData();
17369                    String ssp;
17370                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17371                        final boolean replacing =
17372                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17373                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17374
17375                        try {
17376                            ApplicationInfo ai = AppGlobals.getPackageManager().
17377                                    getApplicationInfo(ssp, 0, 0);
17378                            mBatteryStatsService.notePackageInstalled(ssp,
17379                                    ai != null ? ai.versionCode : 0);
17380                        } catch (RemoteException e) {
17381                        }
17382                    }
17383                    break;
17384                case Intent.ACTION_TIMEZONE_CHANGED:
17385                    // If this is the time zone changed action, queue up a message that will reset
17386                    // the timezone of all currently running processes. This message will get
17387                    // queued up before the broadcast happens.
17388                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17389                    break;
17390                case Intent.ACTION_TIME_CHANGED:
17391                    // If the user set the time, let all running processes know.
17392                    final int is24Hour =
17393                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17394                                    : 0;
17395                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17396                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17397                    synchronized (stats) {
17398                        stats.noteCurrentTimeChangedLocked();
17399                    }
17400                    break;
17401                case Intent.ACTION_CLEAR_DNS_CACHE:
17402                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17403                    break;
17404                case Proxy.PROXY_CHANGE_ACTION:
17405                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17406                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17407                    break;
17408            }
17409        }
17410
17411        // Add to the sticky list if requested.
17412        if (sticky) {
17413            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17414                    callingPid, callingUid)
17415                    != PackageManager.PERMISSION_GRANTED) {
17416                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17417                        + callingPid + ", uid=" + callingUid
17418                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17419                Slog.w(TAG, msg);
17420                throw new SecurityException(msg);
17421            }
17422            if (requiredPermissions != null && requiredPermissions.length > 0) {
17423                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17424                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17425                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17426            }
17427            if (intent.getComponent() != null) {
17428                throw new SecurityException(
17429                        "Sticky broadcasts can't target a specific component");
17430            }
17431            // We use userId directly here, since the "all" target is maintained
17432            // as a separate set of sticky broadcasts.
17433            if (userId != UserHandle.USER_ALL) {
17434                // But first, if this is not a broadcast to all users, then
17435                // make sure it doesn't conflict with an existing broadcast to
17436                // all users.
17437                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17438                        UserHandle.USER_ALL);
17439                if (stickies != null) {
17440                    ArrayList<Intent> list = stickies.get(intent.getAction());
17441                    if (list != null) {
17442                        int N = list.size();
17443                        int i;
17444                        for (i=0; i<N; i++) {
17445                            if (intent.filterEquals(list.get(i))) {
17446                                throw new IllegalArgumentException(
17447                                        "Sticky broadcast " + intent + " for user "
17448                                        + userId + " conflicts with existing global broadcast");
17449                            }
17450                        }
17451                    }
17452                }
17453            }
17454            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17455            if (stickies == null) {
17456                stickies = new ArrayMap<>();
17457                mStickyBroadcasts.put(userId, stickies);
17458            }
17459            ArrayList<Intent> list = stickies.get(intent.getAction());
17460            if (list == null) {
17461                list = new ArrayList<>();
17462                stickies.put(intent.getAction(), list);
17463            }
17464            final int stickiesCount = list.size();
17465            int i;
17466            for (i = 0; i < stickiesCount; i++) {
17467                if (intent.filterEquals(list.get(i))) {
17468                    // This sticky already exists, replace it.
17469                    list.set(i, new Intent(intent));
17470                    break;
17471                }
17472            }
17473            if (i >= stickiesCount) {
17474                list.add(new Intent(intent));
17475            }
17476        }
17477
17478        int[] users;
17479        if (userId == UserHandle.USER_ALL) {
17480            // Caller wants broadcast to go to all started users.
17481            users = mUserController.getStartedUserArrayLocked();
17482        } else {
17483            // Caller wants broadcast to go to one specific user.
17484            users = new int[] {userId};
17485        }
17486
17487        // Figure out who all will receive this broadcast.
17488        List receivers = null;
17489        List<BroadcastFilter> registeredReceivers = null;
17490        // Need to resolve the intent to interested receivers...
17491        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17492                 == 0) {
17493            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17494        }
17495        if (intent.getComponent() == null) {
17496            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17497                // Query one target user at a time, excluding shell-restricted users
17498                for (int i = 0; i < users.length; i++) {
17499                    if (mUserController.hasUserRestriction(
17500                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17501                        continue;
17502                    }
17503                    List<BroadcastFilter> registeredReceiversForUser =
17504                            mReceiverResolver.queryIntent(intent,
17505                                    resolvedType, false, users[i]);
17506                    if (registeredReceivers == null) {
17507                        registeredReceivers = registeredReceiversForUser;
17508                    } else if (registeredReceiversForUser != null) {
17509                        registeredReceivers.addAll(registeredReceiversForUser);
17510                    }
17511                }
17512            } else {
17513                registeredReceivers = mReceiverResolver.queryIntent(intent,
17514                        resolvedType, false, userId);
17515            }
17516        }
17517
17518        final boolean replacePending =
17519                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17520
17521        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17522                + " replacePending=" + replacePending);
17523
17524        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17525        if (!ordered && NR > 0) {
17526            // If we are not serializing this broadcast, then send the
17527            // registered receivers separately so they don't wait for the
17528            // components to be launched.
17529            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17530            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17531                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17532                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17533                    resultExtras, ordered, sticky, false, userId);
17534            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17535            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17536            if (!replaced) {
17537                queue.enqueueParallelBroadcastLocked(r);
17538                queue.scheduleBroadcastsLocked();
17539            }
17540            registeredReceivers = null;
17541            NR = 0;
17542        }
17543
17544        // Merge into one list.
17545        int ir = 0;
17546        if (receivers != null) {
17547            // A special case for PACKAGE_ADDED: do not allow the package
17548            // being added to see this broadcast.  This prevents them from
17549            // using this as a back door to get run as soon as they are
17550            // installed.  Maybe in the future we want to have a special install
17551            // broadcast or such for apps, but we'd like to deliberately make
17552            // this decision.
17553            String skipPackages[] = null;
17554            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17555                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17556                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17557                Uri data = intent.getData();
17558                if (data != null) {
17559                    String pkgName = data.getSchemeSpecificPart();
17560                    if (pkgName != null) {
17561                        skipPackages = new String[] { pkgName };
17562                    }
17563                }
17564            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17565                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17566            }
17567            if (skipPackages != null && (skipPackages.length > 0)) {
17568                for (String skipPackage : skipPackages) {
17569                    if (skipPackage != null) {
17570                        int NT = receivers.size();
17571                        for (int it=0; it<NT; it++) {
17572                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17573                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17574                                receivers.remove(it);
17575                                it--;
17576                                NT--;
17577                            }
17578                        }
17579                    }
17580                }
17581            }
17582
17583            int NT = receivers != null ? receivers.size() : 0;
17584            int it = 0;
17585            ResolveInfo curt = null;
17586            BroadcastFilter curr = null;
17587            while (it < NT && ir < NR) {
17588                if (curt == null) {
17589                    curt = (ResolveInfo)receivers.get(it);
17590                }
17591                if (curr == null) {
17592                    curr = registeredReceivers.get(ir);
17593                }
17594                if (curr.getPriority() >= curt.priority) {
17595                    // Insert this broadcast record into the final list.
17596                    receivers.add(it, curr);
17597                    ir++;
17598                    curr = null;
17599                    it++;
17600                    NT++;
17601                } else {
17602                    // Skip to the next ResolveInfo in the final list.
17603                    it++;
17604                    curt = null;
17605                }
17606            }
17607        }
17608        while (ir < NR) {
17609            if (receivers == null) {
17610                receivers = new ArrayList();
17611            }
17612            receivers.add(registeredReceivers.get(ir));
17613            ir++;
17614        }
17615
17616        if ((receivers != null && receivers.size() > 0)
17617                || resultTo != null) {
17618            BroadcastQueue queue = broadcastQueueForIntent(intent);
17619            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17620                    callerPackage, callingPid, callingUid, resolvedType,
17621                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17622                    resultData, resultExtras, ordered, sticky, false, userId);
17623
17624            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17625                    + ": prev had " + queue.mOrderedBroadcasts.size());
17626            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17627                    "Enqueueing broadcast " + r.intent.getAction());
17628
17629            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17630            if (!replaced) {
17631                queue.enqueueOrderedBroadcastLocked(r);
17632                queue.scheduleBroadcastsLocked();
17633            }
17634        }
17635
17636        return ActivityManager.BROADCAST_SUCCESS;
17637    }
17638
17639    final Intent verifyBroadcastLocked(Intent intent) {
17640        // Refuse possible leaked file descriptors
17641        if (intent != null && intent.hasFileDescriptors() == true) {
17642            throw new IllegalArgumentException("File descriptors passed in Intent");
17643        }
17644
17645        int flags = intent.getFlags();
17646
17647        if (!mProcessesReady) {
17648            // if the caller really truly claims to know what they're doing, go
17649            // ahead and allow the broadcast without launching any receivers
17650            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17651                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17652            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17653                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17654                        + " before boot completion");
17655                throw new IllegalStateException("Cannot broadcast before boot completed");
17656            }
17657        }
17658
17659        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17660            throw new IllegalArgumentException(
17661                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17662        }
17663
17664        return intent;
17665    }
17666
17667    public final int broadcastIntent(IApplicationThread caller,
17668            Intent intent, String resolvedType, IIntentReceiver resultTo,
17669            int resultCode, String resultData, Bundle resultExtras,
17670            String[] requiredPermissions, int appOp, Bundle bOptions,
17671            boolean serialized, boolean sticky, int userId) {
17672        enforceNotIsolatedCaller("broadcastIntent");
17673        synchronized(this) {
17674            intent = verifyBroadcastLocked(intent);
17675
17676            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17677            final int callingPid = Binder.getCallingPid();
17678            final int callingUid = Binder.getCallingUid();
17679            final long origId = Binder.clearCallingIdentity();
17680            int res = broadcastIntentLocked(callerApp,
17681                    callerApp != null ? callerApp.info.packageName : null,
17682                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17683                    requiredPermissions, appOp, null, serialized, sticky,
17684                    callingPid, callingUid, userId);
17685            Binder.restoreCallingIdentity(origId);
17686            return res;
17687        }
17688    }
17689
17690
17691    int broadcastIntentInPackage(String packageName, int uid,
17692            Intent intent, String resolvedType, IIntentReceiver resultTo,
17693            int resultCode, String resultData, Bundle resultExtras,
17694            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17695            int userId) {
17696        synchronized(this) {
17697            intent = verifyBroadcastLocked(intent);
17698
17699            final long origId = Binder.clearCallingIdentity();
17700            String[] requiredPermissions = requiredPermission == null ? null
17701                    : new String[] {requiredPermission};
17702            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17703                    resultTo, resultCode, resultData, resultExtras,
17704                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17705                    sticky, -1, uid, userId);
17706            Binder.restoreCallingIdentity(origId);
17707            return res;
17708        }
17709    }
17710
17711    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17712        // Refuse possible leaked file descriptors
17713        if (intent != null && intent.hasFileDescriptors() == true) {
17714            throw new IllegalArgumentException("File descriptors passed in Intent");
17715        }
17716
17717        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17718                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17719
17720        synchronized(this) {
17721            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17722                    != PackageManager.PERMISSION_GRANTED) {
17723                String msg = "Permission Denial: unbroadcastIntent() from pid="
17724                        + Binder.getCallingPid()
17725                        + ", uid=" + Binder.getCallingUid()
17726                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17727                Slog.w(TAG, msg);
17728                throw new SecurityException(msg);
17729            }
17730            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17731            if (stickies != null) {
17732                ArrayList<Intent> list = stickies.get(intent.getAction());
17733                if (list != null) {
17734                    int N = list.size();
17735                    int i;
17736                    for (i=0; i<N; i++) {
17737                        if (intent.filterEquals(list.get(i))) {
17738                            list.remove(i);
17739                            break;
17740                        }
17741                    }
17742                    if (list.size() <= 0) {
17743                        stickies.remove(intent.getAction());
17744                    }
17745                }
17746                if (stickies.size() <= 0) {
17747                    mStickyBroadcasts.remove(userId);
17748                }
17749            }
17750        }
17751    }
17752
17753    void backgroundServicesFinishedLocked(int userId) {
17754        for (BroadcastQueue queue : mBroadcastQueues) {
17755            queue.backgroundServicesFinishedLocked(userId);
17756        }
17757    }
17758
17759    public void finishReceiver(IBinder who, int resultCode, String resultData,
17760            Bundle resultExtras, boolean resultAbort, int flags) {
17761        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17762
17763        // Refuse possible leaked file descriptors
17764        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17765            throw new IllegalArgumentException("File descriptors passed in Bundle");
17766        }
17767
17768        final long origId = Binder.clearCallingIdentity();
17769        try {
17770            boolean doNext = false;
17771            BroadcastRecord r;
17772
17773            synchronized(this) {
17774                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17775                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17776                r = queue.getMatchingOrderedReceiver(who);
17777                if (r != null) {
17778                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17779                        resultData, resultExtras, resultAbort, true);
17780                }
17781            }
17782
17783            if (doNext) {
17784                r.queue.processNextBroadcast(false);
17785            }
17786            trimApplications();
17787        } finally {
17788            Binder.restoreCallingIdentity(origId);
17789        }
17790    }
17791
17792    // =========================================================
17793    // INSTRUMENTATION
17794    // =========================================================
17795
17796    public boolean startInstrumentation(ComponentName className,
17797            String profileFile, int flags, Bundle arguments,
17798            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17799            int userId, String abiOverride) {
17800        enforceNotIsolatedCaller("startInstrumentation");
17801        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17802                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17803        // Refuse possible leaked file descriptors
17804        if (arguments != null && arguments.hasFileDescriptors()) {
17805            throw new IllegalArgumentException("File descriptors passed in Bundle");
17806        }
17807
17808        synchronized(this) {
17809            InstrumentationInfo ii = null;
17810            ApplicationInfo ai = null;
17811            try {
17812                ii = mContext.getPackageManager().getInstrumentationInfo(
17813                    className, STOCK_PM_FLAGS);
17814                ai = AppGlobals.getPackageManager().getApplicationInfo(
17815                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17816            } catch (PackageManager.NameNotFoundException e) {
17817            } catch (RemoteException e) {
17818            }
17819            if (ii == null) {
17820                reportStartInstrumentationFailure(watcher, className,
17821                        "Unable to find instrumentation info for: " + className);
17822                return false;
17823            }
17824            if (ai == null) {
17825                reportStartInstrumentationFailure(watcher, className,
17826                        "Unable to find instrumentation target package: " + ii.targetPackage);
17827                return false;
17828            }
17829
17830            int match = mContext.getPackageManager().checkSignatures(
17831                    ii.targetPackage, ii.packageName);
17832            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17833                String msg = "Permission Denial: starting instrumentation "
17834                        + className + " from pid="
17835                        + Binder.getCallingPid()
17836                        + ", uid=" + Binder.getCallingPid()
17837                        + " not allowed because package " + ii.packageName
17838                        + " does not have a signature matching the target "
17839                        + ii.targetPackage;
17840                reportStartInstrumentationFailure(watcher, className, msg);
17841                throw new SecurityException(msg);
17842            }
17843
17844            final long origId = Binder.clearCallingIdentity();
17845            // Instrumentation can kill and relaunch even persistent processes
17846            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17847                    "start instr");
17848            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17849            app.instrumentationClass = className;
17850            app.instrumentationInfo = ai;
17851            app.instrumentationProfileFile = profileFile;
17852            app.instrumentationArguments = arguments;
17853            app.instrumentationWatcher = watcher;
17854            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17855            app.instrumentationResultClass = className;
17856            Binder.restoreCallingIdentity(origId);
17857        }
17858
17859        return true;
17860    }
17861
17862    /**
17863     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17864     * error to the logs, but if somebody is watching, send the report there too.  This enables
17865     * the "am" command to report errors with more information.
17866     *
17867     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17868     * @param cn The component name of the instrumentation.
17869     * @param report The error report.
17870     */
17871    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17872            ComponentName cn, String report) {
17873        Slog.w(TAG, report);
17874        try {
17875            if (watcher != null) {
17876                Bundle results = new Bundle();
17877                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17878                results.putString("Error", report);
17879                watcher.instrumentationStatus(cn, -1, results);
17880            }
17881        } catch (RemoteException e) {
17882            Slog.w(TAG, e);
17883        }
17884    }
17885
17886    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17887        if (app.instrumentationWatcher != null) {
17888            try {
17889                // NOTE:  IInstrumentationWatcher *must* be oneway here
17890                app.instrumentationWatcher.instrumentationFinished(
17891                    app.instrumentationClass,
17892                    resultCode,
17893                    results);
17894            } catch (RemoteException e) {
17895            }
17896        }
17897
17898        // Can't call out of the system process with a lock held, so post a message.
17899        if (app.instrumentationUiAutomationConnection != null) {
17900            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17901                    app.instrumentationUiAutomationConnection).sendToTarget();
17902        }
17903
17904        app.instrumentationWatcher = null;
17905        app.instrumentationUiAutomationConnection = null;
17906        app.instrumentationClass = null;
17907        app.instrumentationInfo = null;
17908        app.instrumentationProfileFile = null;
17909        app.instrumentationArguments = null;
17910
17911        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17912                "finished inst");
17913    }
17914
17915    public void finishInstrumentation(IApplicationThread target,
17916            int resultCode, Bundle results) {
17917        int userId = UserHandle.getCallingUserId();
17918        // Refuse possible leaked file descriptors
17919        if (results != null && results.hasFileDescriptors()) {
17920            throw new IllegalArgumentException("File descriptors passed in Intent");
17921        }
17922
17923        synchronized(this) {
17924            ProcessRecord app = getRecordForAppLocked(target);
17925            if (app == null) {
17926                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17927                return;
17928            }
17929            final long origId = Binder.clearCallingIdentity();
17930            finishInstrumentationLocked(app, resultCode, results);
17931            Binder.restoreCallingIdentity(origId);
17932        }
17933    }
17934
17935    // =========================================================
17936    // CONFIGURATION
17937    // =========================================================
17938
17939    public ConfigurationInfo getDeviceConfigurationInfo() {
17940        ConfigurationInfo config = new ConfigurationInfo();
17941        synchronized (this) {
17942            config.reqTouchScreen = mConfiguration.touchscreen;
17943            config.reqKeyboardType = mConfiguration.keyboard;
17944            config.reqNavigation = mConfiguration.navigation;
17945            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17946                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17947                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17948            }
17949            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17950                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17951                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17952            }
17953            config.reqGlEsVersion = GL_ES_VERSION;
17954        }
17955        return config;
17956    }
17957
17958    ActivityStack getFocusedStack() {
17959        return mStackSupervisor.getFocusedStack();
17960    }
17961
17962    @Override
17963    public int getFocusedStackId() throws RemoteException {
17964        ActivityStack focusedStack = getFocusedStack();
17965        if (focusedStack != null) {
17966            return focusedStack.getStackId();
17967        }
17968        return -1;
17969    }
17970
17971    public Configuration getConfiguration() {
17972        Configuration ci;
17973        synchronized(this) {
17974            ci = new Configuration(mConfiguration);
17975            ci.userSetLocale = false;
17976        }
17977        return ci;
17978    }
17979
17980    @Override
17981    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17982        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17983        synchronized (this) {
17984            mSuppressResizeConfigChanges = suppress;
17985        }
17986    }
17987
17988    @Override
17989    public void moveTasksToFullscreenStack(int fromStackId) {
17990        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17991        if (fromStackId == HOME_STACK_ID) {
17992            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17993        }
17994        synchronized (this) {
17995            final long origId = Binder.clearCallingIdentity();
17996            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17997            if (stack != null) {
17998                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17999                for (int i = tasks.size() - 1; i >= 0; i--) {
18000                    mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18001                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
18002                }
18003            }
18004            Binder.restoreCallingIdentity(origId);
18005        }
18006    }
18007
18008    @Override
18009    public void updatePersistentConfiguration(Configuration values) {
18010        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18011                "updateConfiguration()");
18012        enforceWriteSettingsPermission("updateConfiguration()");
18013        if (values == null) {
18014            throw new NullPointerException("Configuration must not be null");
18015        }
18016
18017        int userId = UserHandle.getCallingUserId();
18018
18019        synchronized(this) {
18020            final long origId = Binder.clearCallingIdentity();
18021            updateConfigurationLocked(values, null, false, true, userId);
18022            Binder.restoreCallingIdentity(origId);
18023        }
18024    }
18025
18026    private void enforceWriteSettingsPermission(String func) {
18027        int uid = Binder.getCallingUid();
18028        if (uid == Process.ROOT_UID) {
18029            return;
18030        }
18031
18032        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18033                Settings.getPackageNameForUid(mContext, uid), false)) {
18034            return;
18035        }
18036
18037        String msg = "Permission Denial: " + func + " from pid="
18038                + Binder.getCallingPid()
18039                + ", uid=" + uid
18040                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18041        Slog.w(TAG, msg);
18042        throw new SecurityException(msg);
18043    }
18044
18045    public void updateConfiguration(Configuration values) {
18046        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18047                "updateConfiguration()");
18048
18049        synchronized(this) {
18050            if (values == null && mWindowManager != null) {
18051                // sentinel: fetch the current configuration from the window manager
18052                values = mWindowManager.computeNewConfiguration();
18053            }
18054
18055            if (mWindowManager != null) {
18056                mProcessList.applyDisplaySize(mWindowManager);
18057            }
18058
18059            final long origId = Binder.clearCallingIdentity();
18060            if (values != null) {
18061                Settings.System.clearConfiguration(values);
18062            }
18063            updateConfigurationLocked(values, null, false);
18064            Binder.restoreCallingIdentity(origId);
18065        }
18066    }
18067
18068    void updateUserConfigurationLocked() {
18069        Configuration configuration = new Configuration(mConfiguration);
18070        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18071                mUserController.getCurrentUserIdLocked());
18072        updateConfigurationLocked(configuration, null, false);
18073    }
18074
18075    boolean updateConfigurationLocked(Configuration values,
18076            ActivityRecord starting, boolean initLocale) {
18077        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18078        return updateConfigurationLocked(values, starting, initLocale, false,
18079                UserHandle.USER_NULL);
18080    }
18081
18082    // To cache the list of supported system locales
18083    private String[] mSupportedSystemLocales = null;
18084
18085    /**
18086     * Do either or both things: (1) change the current configuration, and (2)
18087     * make sure the given activity is running with the (now) current
18088     * configuration.  Returns true if the activity has been left running, or
18089     * false if <var>starting</var> is being destroyed to match the new
18090     * configuration.
18091     *
18092     * @param userId is only used when persistent parameter is set to true to persist configuration
18093     *               for that particular user
18094     */
18095    private boolean updateConfigurationLocked(Configuration values,
18096            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18097        int changes = 0;
18098
18099        if (values != null) {
18100            Configuration newConfig = new Configuration(mConfiguration);
18101            changes = newConfig.updateFrom(values);
18102            if (changes != 0) {
18103                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18104                        "Updating configuration to: " + values);
18105
18106                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18107
18108                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18109                    if (mSupportedSystemLocales == null) {
18110                        mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
18111                    }
18112                    final Locale locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18113                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18114                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18115                            locale));
18116                }
18117
18118                mConfigurationSeq++;
18119                if (mConfigurationSeq <= 0) {
18120                    mConfigurationSeq = 1;
18121                }
18122                newConfig.seq = mConfigurationSeq;
18123                mConfiguration = newConfig;
18124                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18125                mUsageStatsService.reportConfigurationChange(newConfig,
18126                        mUserController.getCurrentUserIdLocked());
18127                //mUsageStatsService.noteStartConfig(newConfig);
18128
18129                final Configuration configCopy = new Configuration(mConfiguration);
18130
18131                // TODO: If our config changes, should we auto dismiss any currently
18132                // showing dialogs?
18133                mShowDialogs = shouldShowDialogs(newConfig);
18134
18135                AttributeCache ac = AttributeCache.instance();
18136                if (ac != null) {
18137                    ac.updateConfiguration(configCopy);
18138                }
18139
18140                // Make sure all resources in our process are updated
18141                // right now, so that anyone who is going to retrieve
18142                // resource values after we return will be sure to get
18143                // the new ones.  This is especially important during
18144                // boot, where the first config change needs to guarantee
18145                // all resources have that config before following boot
18146                // code is executed.
18147                mSystemThread.applyConfigurationToResources(configCopy);
18148
18149                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18150                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18151                    msg.obj = new Configuration(configCopy);
18152                    msg.arg1 = userId;
18153                    mHandler.sendMessage(msg);
18154                }
18155
18156                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18157                    ProcessRecord app = mLruProcesses.get(i);
18158                    try {
18159                        if (app.thread != null) {
18160                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18161                                    + app.processName + " new config " + mConfiguration);
18162                            app.thread.scheduleConfigurationChanged(configCopy);
18163                        }
18164                    } catch (Exception e) {
18165                    }
18166                }
18167                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18168                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18169                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18170                        | Intent.FLAG_RECEIVER_FOREGROUND);
18171                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18172                        null, AppOpsManager.OP_NONE, null, false, false,
18173                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18174                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18175                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18176                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18177                    if (!mProcessesReady) {
18178                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18179                    }
18180                    broadcastIntentLocked(null, null, intent,
18181                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18182                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18183                }
18184            }
18185        }
18186
18187        boolean kept = true;
18188        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18189        // mainStack is null during startup.
18190        if (mainStack != null) {
18191            if (changes != 0 && starting == null) {
18192                // If the configuration changed, and the caller is not already
18193                // in the process of starting an activity, then find the top
18194                // activity to check if its configuration needs to change.
18195                starting = mainStack.topRunningActivityLocked();
18196            }
18197
18198            if (starting != null) {
18199                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18200                // And we need to make sure at this point that all other activities
18201                // are made visible with the correct configuration.
18202                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18203                        !PRESERVE_WINDOWS);
18204            }
18205        }
18206
18207        if (values != null && mWindowManager != null) {
18208            mWindowManager.setNewConfiguration(mConfiguration);
18209        }
18210
18211        return kept;
18212    }
18213
18214    /**
18215     * Decide based on the configuration whether we should shouw the ANR,
18216     * crash, etc dialogs.  The idea is that if there is no affordnace to
18217     * press the on-screen buttons, we shouldn't show the dialog.
18218     *
18219     * A thought: SystemUI might also want to get told about this, the Power
18220     * dialog / global actions also might want different behaviors.
18221     */
18222    private static final boolean shouldShowDialogs(Configuration config) {
18223        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18224                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18225                && config.navigation == Configuration.NAVIGATION_NONAV);
18226    }
18227
18228    @Override
18229    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18230        synchronized (this) {
18231            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18232            if (srec != null) {
18233                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18234            }
18235        }
18236        return false;
18237    }
18238
18239    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18240            Intent resultData) {
18241
18242        synchronized (this) {
18243            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18244            if (r != null) {
18245                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18246            }
18247            return false;
18248        }
18249    }
18250
18251    public int getLaunchedFromUid(IBinder activityToken) {
18252        ActivityRecord srec;
18253        synchronized (this) {
18254            srec = ActivityRecord.forTokenLocked(activityToken);
18255        }
18256        if (srec == null) {
18257            return -1;
18258        }
18259        return srec.launchedFromUid;
18260    }
18261
18262    public String getLaunchedFromPackage(IBinder activityToken) {
18263        ActivityRecord srec;
18264        synchronized (this) {
18265            srec = ActivityRecord.forTokenLocked(activityToken);
18266        }
18267        if (srec == null) {
18268            return null;
18269        }
18270        return srec.launchedFromPackage;
18271    }
18272
18273    // =========================================================
18274    // LIFETIME MANAGEMENT
18275    // =========================================================
18276
18277    // Returns which broadcast queue the app is the current [or imminent] receiver
18278    // on, or 'null' if the app is not an active broadcast recipient.
18279    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18280        BroadcastRecord r = app.curReceiver;
18281        if (r != null) {
18282            return r.queue;
18283        }
18284
18285        // It's not the current receiver, but it might be starting up to become one
18286        synchronized (this) {
18287            for (BroadcastQueue queue : mBroadcastQueues) {
18288                r = queue.mPendingBroadcast;
18289                if (r != null && r.curApp == app) {
18290                    // found it; report which queue it's in
18291                    return queue;
18292                }
18293            }
18294        }
18295
18296        return null;
18297    }
18298
18299    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18300            ComponentName targetComponent, String targetProcess) {
18301        if (!mTrackingAssociations) {
18302            return null;
18303        }
18304        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18305                = mAssociations.get(targetUid);
18306        if (components == null) {
18307            components = new ArrayMap<>();
18308            mAssociations.put(targetUid, components);
18309        }
18310        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18311        if (sourceUids == null) {
18312            sourceUids = new SparseArray<>();
18313            components.put(targetComponent, sourceUids);
18314        }
18315        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18316        if (sourceProcesses == null) {
18317            sourceProcesses = new ArrayMap<>();
18318            sourceUids.put(sourceUid, sourceProcesses);
18319        }
18320        Association ass = sourceProcesses.get(sourceProcess);
18321        if (ass == null) {
18322            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18323                    targetProcess);
18324            sourceProcesses.put(sourceProcess, ass);
18325        }
18326        ass.mCount++;
18327        ass.mNesting++;
18328        if (ass.mNesting == 1) {
18329            ass.mStartTime = SystemClock.uptimeMillis();
18330        }
18331        return ass;
18332    }
18333
18334    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18335            ComponentName targetComponent) {
18336        if (!mTrackingAssociations) {
18337            return;
18338        }
18339        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18340                = mAssociations.get(targetUid);
18341        if (components == null) {
18342            return;
18343        }
18344        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18345        if (sourceUids == null) {
18346            return;
18347        }
18348        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18349        if (sourceProcesses == null) {
18350            return;
18351        }
18352        Association ass = sourceProcesses.get(sourceProcess);
18353        if (ass == null || ass.mNesting <= 0) {
18354            return;
18355        }
18356        ass.mNesting--;
18357        if (ass.mNesting == 0) {
18358            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18359        }
18360    }
18361
18362    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18363            boolean doingAll, long now) {
18364        if (mAdjSeq == app.adjSeq) {
18365            // This adjustment has already been computed.
18366            return app.curRawAdj;
18367        }
18368
18369        if (app.thread == null) {
18370            app.adjSeq = mAdjSeq;
18371            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18372            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18373            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18374        }
18375
18376        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18377        app.adjSource = null;
18378        app.adjTarget = null;
18379        app.empty = false;
18380        app.cached = false;
18381
18382        final int activitiesSize = app.activities.size();
18383
18384        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18385            // The max adjustment doesn't allow this app to be anything
18386            // below foreground, so it is not worth doing work for it.
18387            app.adjType = "fixed";
18388            app.adjSeq = mAdjSeq;
18389            app.curRawAdj = app.maxAdj;
18390            app.foregroundActivities = false;
18391            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18392            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18393            // System processes can do UI, and when they do we want to have
18394            // them trim their memory after the user leaves the UI.  To
18395            // facilitate this, here we need to determine whether or not it
18396            // is currently showing UI.
18397            app.systemNoUi = true;
18398            if (app == TOP_APP) {
18399                app.systemNoUi = false;
18400            } else if (activitiesSize > 0) {
18401                for (int j = 0; j < activitiesSize; j++) {
18402                    final ActivityRecord r = app.activities.get(j);
18403                    if (r.visible) {
18404                        app.systemNoUi = false;
18405                    }
18406                }
18407            }
18408            if (!app.systemNoUi) {
18409                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18410            }
18411            return (app.curAdj=app.maxAdj);
18412        }
18413
18414        app.systemNoUi = false;
18415
18416        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18417
18418        // Determine the importance of the process, starting with most
18419        // important to least, and assign an appropriate OOM adjustment.
18420        int adj;
18421        int schedGroup;
18422        int procState;
18423        boolean foregroundActivities = false;
18424        BroadcastQueue queue;
18425        if (app == TOP_APP) {
18426            // The last app on the list is the foreground app.
18427            adj = ProcessList.FOREGROUND_APP_ADJ;
18428            schedGroup = Process.THREAD_GROUP_DEFAULT;
18429            app.adjType = "top-activity";
18430            foregroundActivities = true;
18431            procState = PROCESS_STATE_CUR_TOP;
18432        } else if (app.instrumentationClass != null) {
18433            // Don't want to kill running instrumentation.
18434            adj = ProcessList.FOREGROUND_APP_ADJ;
18435            schedGroup = Process.THREAD_GROUP_DEFAULT;
18436            app.adjType = "instrumentation";
18437            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18438        } else if ((queue = isReceivingBroadcast(app)) != null) {
18439            // An app that is currently receiving a broadcast also
18440            // counts as being in the foreground for OOM killer purposes.
18441            // It's placed in a sched group based on the nature of the
18442            // broadcast as reflected by which queue it's active in.
18443            adj = ProcessList.FOREGROUND_APP_ADJ;
18444            schedGroup = (queue == mFgBroadcastQueue)
18445                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18446            app.adjType = "broadcast";
18447            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18448        } else if (app.executingServices.size() > 0) {
18449            // An app that is currently executing a service callback also
18450            // counts as being in the foreground.
18451            adj = ProcessList.FOREGROUND_APP_ADJ;
18452            schedGroup = app.execServicesFg ?
18453                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18454            app.adjType = "exec-service";
18455            procState = ActivityManager.PROCESS_STATE_SERVICE;
18456            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18457        } else {
18458            // As far as we know the process is empty.  We may change our mind later.
18459            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18460            // At this point we don't actually know the adjustment.  Use the cached adj
18461            // value that the caller wants us to.
18462            adj = cachedAdj;
18463            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18464            app.cached = true;
18465            app.empty = true;
18466            app.adjType = "cch-empty";
18467        }
18468
18469        // Examine all activities if not already foreground.
18470        if (!foregroundActivities && activitiesSize > 0) {
18471            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18472            for (int j = 0; j < activitiesSize; j++) {
18473                final ActivityRecord r = app.activities.get(j);
18474                if (r.app != app) {
18475                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18476                            + app + "?!? Using " + r.app + " instead.");
18477                    continue;
18478                }
18479                if (r.visible) {
18480                    // App has a visible activity; only upgrade adjustment.
18481                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18482                        adj = ProcessList.VISIBLE_APP_ADJ;
18483                        app.adjType = "visible";
18484                    }
18485                    if (procState > PROCESS_STATE_CUR_TOP) {
18486                        procState = PROCESS_STATE_CUR_TOP;
18487                    }
18488                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18489                    app.cached = false;
18490                    app.empty = false;
18491                    foregroundActivities = true;
18492                    if (r.task != null && minLayer > 0) {
18493                        final int layer = r.task.mLayerRank;
18494                        if (layer >= 0 && minLayer > layer) {
18495                            minLayer = layer;
18496                        }
18497                    }
18498                    break;
18499                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18500                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18501                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18502                        app.adjType = "pausing";
18503                    }
18504                    if (procState > PROCESS_STATE_CUR_TOP) {
18505                        procState = PROCESS_STATE_CUR_TOP;
18506                    }
18507                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18508                    app.cached = false;
18509                    app.empty = false;
18510                    foregroundActivities = true;
18511                } else if (r.state == ActivityState.STOPPING) {
18512                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18513                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18514                        app.adjType = "stopping";
18515                    }
18516                    // For the process state, we will at this point consider the
18517                    // process to be cached.  It will be cached either as an activity
18518                    // or empty depending on whether the activity is finishing.  We do
18519                    // this so that we can treat the process as cached for purposes of
18520                    // memory trimming (determing current memory level, trim command to
18521                    // send to process) since there can be an arbitrary number of stopping
18522                    // processes and they should soon all go into the cached state.
18523                    if (!r.finishing) {
18524                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18525                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18526                        }
18527                    }
18528                    app.cached = false;
18529                    app.empty = false;
18530                    foregroundActivities = true;
18531                } else {
18532                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18533                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18534                        app.adjType = "cch-act";
18535                    }
18536                }
18537            }
18538            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18539                adj += minLayer;
18540            }
18541        }
18542
18543        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18544                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18545            if (app.foregroundServices) {
18546                // The user is aware of this app, so make it visible.
18547                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18548                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18549                app.cached = false;
18550                app.adjType = "fg-service";
18551                schedGroup = Process.THREAD_GROUP_DEFAULT;
18552            } else if (app.forcingToForeground != null) {
18553                // The user is aware of this app, so make it visible.
18554                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18555                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18556                app.cached = false;
18557                app.adjType = "force-fg";
18558                app.adjSource = app.forcingToForeground;
18559                schedGroup = Process.THREAD_GROUP_DEFAULT;
18560            }
18561        }
18562
18563        if (app == mHeavyWeightProcess) {
18564            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18565                // We don't want to kill the current heavy-weight process.
18566                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18567                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18568                app.cached = false;
18569                app.adjType = "heavy";
18570            }
18571            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18572                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18573            }
18574        }
18575
18576        if (app == mHomeProcess) {
18577            if (adj > ProcessList.HOME_APP_ADJ) {
18578                // This process is hosting what we currently consider to be the
18579                // home app, so we don't want to let it go into the background.
18580                adj = ProcessList.HOME_APP_ADJ;
18581                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18582                app.cached = false;
18583                app.adjType = "home";
18584            }
18585            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18586                procState = ActivityManager.PROCESS_STATE_HOME;
18587            }
18588        }
18589
18590        if (app == mPreviousProcess && app.activities.size() > 0) {
18591            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18592                // This was the previous process that showed UI to the user.
18593                // We want to try to keep it around more aggressively, to give
18594                // a good experience around switching between two apps.
18595                adj = ProcessList.PREVIOUS_APP_ADJ;
18596                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18597                app.cached = false;
18598                app.adjType = "previous";
18599            }
18600            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18601                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18602            }
18603        }
18604
18605        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18606                + " reason=" + app.adjType);
18607
18608        // By default, we use the computed adjustment.  It may be changed if
18609        // there are applications dependent on our services or providers, but
18610        // this gives us a baseline and makes sure we don't get into an
18611        // infinite recursion.
18612        app.adjSeq = mAdjSeq;
18613        app.curRawAdj = adj;
18614        app.hasStartedServices = false;
18615
18616        if (mBackupTarget != null && app == mBackupTarget.app) {
18617            // If possible we want to avoid killing apps while they're being backed up
18618            if (adj > ProcessList.BACKUP_APP_ADJ) {
18619                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18620                adj = ProcessList.BACKUP_APP_ADJ;
18621                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18622                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18623                }
18624                app.adjType = "backup";
18625                app.cached = false;
18626            }
18627            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18628                procState = ActivityManager.PROCESS_STATE_BACKUP;
18629            }
18630        }
18631
18632        boolean mayBeTop = false;
18633
18634        for (int is = app.services.size()-1;
18635                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18636                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18637                        || procState > ActivityManager.PROCESS_STATE_TOP);
18638                is--) {
18639            ServiceRecord s = app.services.valueAt(is);
18640            if (s.startRequested) {
18641                app.hasStartedServices = true;
18642                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18643                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18644                }
18645                if (app.hasShownUi && app != mHomeProcess) {
18646                    // If this process has shown some UI, let it immediately
18647                    // go to the LRU list because it may be pretty heavy with
18648                    // UI stuff.  We'll tag it with a label just to help
18649                    // debug and understand what is going on.
18650                    if (adj > ProcessList.SERVICE_ADJ) {
18651                        app.adjType = "cch-started-ui-services";
18652                    }
18653                } else {
18654                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18655                        // This service has seen some activity within
18656                        // recent memory, so we will keep its process ahead
18657                        // of the background processes.
18658                        if (adj > ProcessList.SERVICE_ADJ) {
18659                            adj = ProcessList.SERVICE_ADJ;
18660                            app.adjType = "started-services";
18661                            app.cached = false;
18662                        }
18663                    }
18664                    // If we have let the service slide into the background
18665                    // state, still have some text describing what it is doing
18666                    // even though the service no longer has an impact.
18667                    if (adj > ProcessList.SERVICE_ADJ) {
18668                        app.adjType = "cch-started-services";
18669                    }
18670                }
18671            }
18672            for (int conni = s.connections.size()-1;
18673                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18674                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18675                            || procState > ActivityManager.PROCESS_STATE_TOP);
18676                    conni--) {
18677                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18678                for (int i = 0;
18679                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18680                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18681                                || procState > ActivityManager.PROCESS_STATE_TOP);
18682                        i++) {
18683                    // XXX should compute this based on the max of
18684                    // all connected clients.
18685                    ConnectionRecord cr = clist.get(i);
18686                    if (cr.binding.client == app) {
18687                        // Binding to ourself is not interesting.
18688                        continue;
18689                    }
18690                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18691                        ProcessRecord client = cr.binding.client;
18692                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18693                                TOP_APP, doingAll, now);
18694                        int clientProcState = client.curProcState;
18695                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18696                            // If the other app is cached for any reason, for purposes here
18697                            // we are going to consider it empty.  The specific cached state
18698                            // doesn't propagate except under certain conditions.
18699                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18700                        }
18701                        String adjType = null;
18702                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18703                            // Not doing bind OOM management, so treat
18704                            // this guy more like a started service.
18705                            if (app.hasShownUi && app != mHomeProcess) {
18706                                // If this process has shown some UI, let it immediately
18707                                // go to the LRU list because it may be pretty heavy with
18708                                // UI stuff.  We'll tag it with a label just to help
18709                                // debug and understand what is going on.
18710                                if (adj > clientAdj) {
18711                                    adjType = "cch-bound-ui-services";
18712                                }
18713                                app.cached = false;
18714                                clientAdj = adj;
18715                                clientProcState = procState;
18716                            } else {
18717                                if (now >= (s.lastActivity
18718                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18719                                    // This service has not seen activity within
18720                                    // recent memory, so allow it to drop to the
18721                                    // LRU list if there is no other reason to keep
18722                                    // it around.  We'll also tag it with a label just
18723                                    // to help debug and undertand what is going on.
18724                                    if (adj > clientAdj) {
18725                                        adjType = "cch-bound-services";
18726                                    }
18727                                    clientAdj = adj;
18728                                }
18729                            }
18730                        }
18731                        if (adj > clientAdj) {
18732                            // If this process has recently shown UI, and
18733                            // the process that is binding to it is less
18734                            // important than being visible, then we don't
18735                            // care about the binding as much as we care
18736                            // about letting this process get into the LRU
18737                            // list to be killed and restarted if needed for
18738                            // memory.
18739                            if (app.hasShownUi && app != mHomeProcess
18740                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18741                                adjType = "cch-bound-ui-services";
18742                            } else {
18743                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18744                                        |Context.BIND_IMPORTANT)) != 0) {
18745                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18746                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18747                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18748                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18749                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18750                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18751                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18752                                    adj = clientAdj;
18753                                } else {
18754                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18755                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18756                                    }
18757                                }
18758                                if (!client.cached) {
18759                                    app.cached = false;
18760                                }
18761                                adjType = "service";
18762                            }
18763                        }
18764                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18765                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18766                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18767                            }
18768                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18769                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18770                                    // Special handling of clients who are in the top state.
18771                                    // We *may* want to consider this process to be in the
18772                                    // top state as well, but only if there is not another
18773                                    // reason for it to be running.  Being on the top is a
18774                                    // special state, meaning you are specifically running
18775                                    // for the current top app.  If the process is already
18776                                    // running in the background for some other reason, it
18777                                    // is more important to continue considering it to be
18778                                    // in the background state.
18779                                    mayBeTop = true;
18780                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18781                                } else {
18782                                    // Special handling for above-top states (persistent
18783                                    // processes).  These should not bring the current process
18784                                    // into the top state, since they are not on top.  Instead
18785                                    // give them the best state after that.
18786                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18787                                        clientProcState =
18788                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18789                                    } else if (mWakefulness
18790                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18791                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18792                                                    != 0) {
18793                                        clientProcState =
18794                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18795                                    } else {
18796                                        clientProcState =
18797                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18798                                    }
18799                                }
18800                            }
18801                        } else {
18802                            if (clientProcState <
18803                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18804                                clientProcState =
18805                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18806                            }
18807                        }
18808                        if (procState > clientProcState) {
18809                            procState = clientProcState;
18810                        }
18811                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18812                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18813                            app.pendingUiClean = true;
18814                        }
18815                        if (adjType != null) {
18816                            app.adjType = adjType;
18817                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18818                                    .REASON_SERVICE_IN_USE;
18819                            app.adjSource = cr.binding.client;
18820                            app.adjSourceProcState = clientProcState;
18821                            app.adjTarget = s.name;
18822                        }
18823                    }
18824                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18825                        app.treatLikeActivity = true;
18826                    }
18827                    final ActivityRecord a = cr.activity;
18828                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18829                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18830                                (a.visible || a.state == ActivityState.RESUMED
18831                                 || a.state == ActivityState.PAUSING)) {
18832                            adj = ProcessList.FOREGROUND_APP_ADJ;
18833                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18834                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18835                            }
18836                            app.cached = false;
18837                            app.adjType = "service";
18838                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18839                                    .REASON_SERVICE_IN_USE;
18840                            app.adjSource = a;
18841                            app.adjSourceProcState = procState;
18842                            app.adjTarget = s.name;
18843                        }
18844                    }
18845                }
18846            }
18847        }
18848
18849        for (int provi = app.pubProviders.size()-1;
18850                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18851                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18852                        || procState > ActivityManager.PROCESS_STATE_TOP);
18853                provi--) {
18854            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18855            for (int i = cpr.connections.size()-1;
18856                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18857                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18858                            || procState > ActivityManager.PROCESS_STATE_TOP);
18859                    i--) {
18860                ContentProviderConnection conn = cpr.connections.get(i);
18861                ProcessRecord client = conn.client;
18862                if (client == app) {
18863                    // Being our own client is not interesting.
18864                    continue;
18865                }
18866                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18867                int clientProcState = client.curProcState;
18868                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18869                    // If the other app is cached for any reason, for purposes here
18870                    // we are going to consider it empty.
18871                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18872                }
18873                if (adj > clientAdj) {
18874                    if (app.hasShownUi && app != mHomeProcess
18875                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18876                        app.adjType = "cch-ui-provider";
18877                    } else {
18878                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18879                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18880                        app.adjType = "provider";
18881                    }
18882                    app.cached &= client.cached;
18883                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18884                            .REASON_PROVIDER_IN_USE;
18885                    app.adjSource = client;
18886                    app.adjSourceProcState = clientProcState;
18887                    app.adjTarget = cpr.name;
18888                }
18889                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18890                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18891                        // Special handling of clients who are in the top state.
18892                        // We *may* want to consider this process to be in the
18893                        // top state as well, but only if there is not another
18894                        // reason for it to be running.  Being on the top is a
18895                        // special state, meaning you are specifically running
18896                        // for the current top app.  If the process is already
18897                        // running in the background for some other reason, it
18898                        // is more important to continue considering it to be
18899                        // in the background state.
18900                        mayBeTop = true;
18901                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18902                    } else {
18903                        // Special handling for above-top states (persistent
18904                        // processes).  These should not bring the current process
18905                        // into the top state, since they are not on top.  Instead
18906                        // give them the best state after that.
18907                        clientProcState =
18908                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18909                    }
18910                }
18911                if (procState > clientProcState) {
18912                    procState = clientProcState;
18913                }
18914                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18915                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18916                }
18917            }
18918            // If the provider has external (non-framework) process
18919            // dependencies, ensure that its adjustment is at least
18920            // FOREGROUND_APP_ADJ.
18921            if (cpr.hasExternalProcessHandles()) {
18922                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18923                    adj = ProcessList.FOREGROUND_APP_ADJ;
18924                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18925                    app.cached = false;
18926                    app.adjType = "provider";
18927                    app.adjTarget = cpr.name;
18928                }
18929                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18930                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18931                }
18932            }
18933        }
18934
18935        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18936            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18937                adj = ProcessList.PREVIOUS_APP_ADJ;
18938                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18939                app.cached = false;
18940                app.adjType = "provider";
18941            }
18942            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18943                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18944            }
18945        }
18946
18947        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18948            // A client of one of our services or providers is in the top state.  We
18949            // *may* want to be in the top state, but not if we are already running in
18950            // the background for some other reason.  For the decision here, we are going
18951            // to pick out a few specific states that we want to remain in when a client
18952            // is top (states that tend to be longer-term) and otherwise allow it to go
18953            // to the top state.
18954            switch (procState) {
18955                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18956                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18957                case ActivityManager.PROCESS_STATE_SERVICE:
18958                    // These all are longer-term states, so pull them up to the top
18959                    // of the background states, but not all the way to the top state.
18960                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18961                    break;
18962                default:
18963                    // Otherwise, top is a better choice, so take it.
18964                    procState = ActivityManager.PROCESS_STATE_TOP;
18965                    break;
18966            }
18967        }
18968
18969        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18970            if (app.hasClientActivities) {
18971                // This is a cached process, but with client activities.  Mark it so.
18972                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18973                app.adjType = "cch-client-act";
18974            } else if (app.treatLikeActivity) {
18975                // This is a cached process, but somebody wants us to treat it like it has
18976                // an activity, okay!
18977                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18978                app.adjType = "cch-as-act";
18979            }
18980        }
18981
18982        if (adj == ProcessList.SERVICE_ADJ) {
18983            if (doingAll) {
18984                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18985                mNewNumServiceProcs++;
18986                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18987                if (!app.serviceb) {
18988                    // This service isn't far enough down on the LRU list to
18989                    // normally be a B service, but if we are low on RAM and it
18990                    // is large we want to force it down since we would prefer to
18991                    // keep launcher over it.
18992                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18993                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18994                        app.serviceHighRam = true;
18995                        app.serviceb = true;
18996                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18997                    } else {
18998                        mNewNumAServiceProcs++;
18999                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19000                    }
19001                } else {
19002                    app.serviceHighRam = false;
19003                }
19004            }
19005            if (app.serviceb) {
19006                adj = ProcessList.SERVICE_B_ADJ;
19007            }
19008        }
19009
19010        app.curRawAdj = adj;
19011
19012        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19013        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19014        if (adj > app.maxAdj) {
19015            adj = app.maxAdj;
19016            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19017                schedGroup = Process.THREAD_GROUP_DEFAULT;
19018            }
19019        }
19020
19021        // Do final modification to adj.  Everything we do between here and applying
19022        // the final setAdj must be done in this function, because we will also use
19023        // it when computing the final cached adj later.  Note that we don't need to
19024        // worry about this for max adj above, since max adj will always be used to
19025        // keep it out of the cached vaues.
19026        app.curAdj = app.modifyRawOomAdj(adj);
19027        app.curSchedGroup = schedGroup;
19028        app.curProcState = procState;
19029        app.foregroundActivities = foregroundActivities;
19030
19031        return app.curRawAdj;
19032    }
19033
19034    /**
19035     * Record new PSS sample for a process.
19036     */
19037    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
19038        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
19039        proc.lastPssTime = now;
19040        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19041        if (DEBUG_PSS) Slog.d(TAG_PSS,
19042                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19043                + " state=" + ProcessList.makeProcStateString(procState));
19044        if (proc.initialIdlePss == 0) {
19045            proc.initialIdlePss = pss;
19046        }
19047        proc.lastPss = pss;
19048        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19049            proc.lastCachedPss = pss;
19050        }
19051
19052        final SparseArray<Pair<Long, String>> watchUids
19053                = mMemWatchProcesses.getMap().get(proc.processName);
19054        Long check = null;
19055        if (watchUids != null) {
19056            Pair<Long, String> val = watchUids.get(proc.uid);
19057            if (val == null) {
19058                val = watchUids.get(0);
19059            }
19060            if (val != null) {
19061                check = val.first;
19062            }
19063        }
19064        if (check != null) {
19065            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19066                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19067                if (!isDebuggable) {
19068                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19069                        isDebuggable = true;
19070                    }
19071                }
19072                if (isDebuggable) {
19073                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19074                    final ProcessRecord myProc = proc;
19075                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19076                    mMemWatchDumpProcName = proc.processName;
19077                    mMemWatchDumpFile = heapdumpFile.toString();
19078                    mMemWatchDumpPid = proc.pid;
19079                    mMemWatchDumpUid = proc.uid;
19080                    BackgroundThread.getHandler().post(new Runnable() {
19081                        @Override
19082                        public void run() {
19083                            revokeUriPermission(ActivityThread.currentActivityThread()
19084                                            .getApplicationThread(),
19085                                    DumpHeapActivity.JAVA_URI,
19086                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19087                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19088                                    UserHandle.myUserId());
19089                            ParcelFileDescriptor fd = null;
19090                            try {
19091                                heapdumpFile.delete();
19092                                fd = ParcelFileDescriptor.open(heapdumpFile,
19093                                        ParcelFileDescriptor.MODE_CREATE |
19094                                                ParcelFileDescriptor.MODE_TRUNCATE |
19095                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19096                                                ParcelFileDescriptor.MODE_APPEND);
19097                                IApplicationThread thread = myProc.thread;
19098                                if (thread != null) {
19099                                    try {
19100                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19101                                                "Requesting dump heap from "
19102                                                + myProc + " to " + heapdumpFile);
19103                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19104                                    } catch (RemoteException e) {
19105                                    }
19106                                }
19107                            } catch (FileNotFoundException e) {
19108                                e.printStackTrace();
19109                            } finally {
19110                                if (fd != null) {
19111                                    try {
19112                                        fd.close();
19113                                    } catch (IOException e) {
19114                                    }
19115                                }
19116                            }
19117                        }
19118                    });
19119                } else {
19120                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19121                            + ", but debugging not enabled");
19122                }
19123            }
19124        }
19125    }
19126
19127    /**
19128     * Schedule PSS collection of a process.
19129     */
19130    void requestPssLocked(ProcessRecord proc, int procState) {
19131        if (mPendingPssProcesses.contains(proc)) {
19132            return;
19133        }
19134        if (mPendingPssProcesses.size() == 0) {
19135            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19136        }
19137        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19138        proc.pssProcState = procState;
19139        mPendingPssProcesses.add(proc);
19140    }
19141
19142    /**
19143     * Schedule PSS collection of all processes.
19144     */
19145    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19146        if (!always) {
19147            if (now < (mLastFullPssTime +
19148                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19149                return;
19150            }
19151        }
19152        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19153        mLastFullPssTime = now;
19154        mFullPssPending = true;
19155        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19156        mPendingPssProcesses.clear();
19157        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19158            ProcessRecord app = mLruProcesses.get(i);
19159            if (app.thread == null
19160                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19161                continue;
19162            }
19163            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19164                app.pssProcState = app.setProcState;
19165                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19166                        mTestPssMode, isSleeping(), now);
19167                mPendingPssProcesses.add(app);
19168            }
19169        }
19170        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19171    }
19172
19173    public void setTestPssMode(boolean enabled) {
19174        synchronized (this) {
19175            mTestPssMode = enabled;
19176            if (enabled) {
19177                // Whenever we enable the mode, we want to take a snapshot all of current
19178                // process mem use.
19179                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19180            }
19181        }
19182    }
19183
19184    /**
19185     * Ask a given process to GC right now.
19186     */
19187    final void performAppGcLocked(ProcessRecord app) {
19188        try {
19189            app.lastRequestedGc = SystemClock.uptimeMillis();
19190            if (app.thread != null) {
19191                if (app.reportLowMemory) {
19192                    app.reportLowMemory = false;
19193                    app.thread.scheduleLowMemory();
19194                } else {
19195                    app.thread.processInBackground();
19196                }
19197            }
19198        } catch (Exception e) {
19199            // whatever.
19200        }
19201    }
19202
19203    /**
19204     * Returns true if things are idle enough to perform GCs.
19205     */
19206    private final boolean canGcNowLocked() {
19207        boolean processingBroadcasts = false;
19208        for (BroadcastQueue q : mBroadcastQueues) {
19209            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19210                processingBroadcasts = true;
19211            }
19212        }
19213        return !processingBroadcasts
19214                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19215    }
19216
19217    /**
19218     * Perform GCs on all processes that are waiting for it, but only
19219     * if things are idle.
19220     */
19221    final void performAppGcsLocked() {
19222        final int N = mProcessesToGc.size();
19223        if (N <= 0) {
19224            return;
19225        }
19226        if (canGcNowLocked()) {
19227            while (mProcessesToGc.size() > 0) {
19228                ProcessRecord proc = mProcessesToGc.remove(0);
19229                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19230                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19231                            <= SystemClock.uptimeMillis()) {
19232                        // To avoid spamming the system, we will GC processes one
19233                        // at a time, waiting a few seconds between each.
19234                        performAppGcLocked(proc);
19235                        scheduleAppGcsLocked();
19236                        return;
19237                    } else {
19238                        // It hasn't been long enough since we last GCed this
19239                        // process...  put it in the list to wait for its time.
19240                        addProcessToGcListLocked(proc);
19241                        break;
19242                    }
19243                }
19244            }
19245
19246            scheduleAppGcsLocked();
19247        }
19248    }
19249
19250    /**
19251     * If all looks good, perform GCs on all processes waiting for them.
19252     */
19253    final void performAppGcsIfAppropriateLocked() {
19254        if (canGcNowLocked()) {
19255            performAppGcsLocked();
19256            return;
19257        }
19258        // Still not idle, wait some more.
19259        scheduleAppGcsLocked();
19260    }
19261
19262    /**
19263     * Schedule the execution of all pending app GCs.
19264     */
19265    final void scheduleAppGcsLocked() {
19266        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19267
19268        if (mProcessesToGc.size() > 0) {
19269            // Schedule a GC for the time to the next process.
19270            ProcessRecord proc = mProcessesToGc.get(0);
19271            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19272
19273            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19274            long now = SystemClock.uptimeMillis();
19275            if (when < (now+GC_TIMEOUT)) {
19276                when = now + GC_TIMEOUT;
19277            }
19278            mHandler.sendMessageAtTime(msg, when);
19279        }
19280    }
19281
19282    /**
19283     * Add a process to the array of processes waiting to be GCed.  Keeps the
19284     * list in sorted order by the last GC time.  The process can't already be
19285     * on the list.
19286     */
19287    final void addProcessToGcListLocked(ProcessRecord proc) {
19288        boolean added = false;
19289        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19290            if (mProcessesToGc.get(i).lastRequestedGc <
19291                    proc.lastRequestedGc) {
19292                added = true;
19293                mProcessesToGc.add(i+1, proc);
19294                break;
19295            }
19296        }
19297        if (!added) {
19298            mProcessesToGc.add(0, proc);
19299        }
19300    }
19301
19302    /**
19303     * Set up to ask a process to GC itself.  This will either do it
19304     * immediately, or put it on the list of processes to gc the next
19305     * time things are idle.
19306     */
19307    final void scheduleAppGcLocked(ProcessRecord app) {
19308        long now = SystemClock.uptimeMillis();
19309        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19310            return;
19311        }
19312        if (!mProcessesToGc.contains(app)) {
19313            addProcessToGcListLocked(app);
19314            scheduleAppGcsLocked();
19315        }
19316    }
19317
19318    final void checkExcessivePowerUsageLocked(boolean doKills) {
19319        updateCpuStatsNow();
19320
19321        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19322        boolean doWakeKills = doKills;
19323        boolean doCpuKills = doKills;
19324        if (mLastPowerCheckRealtime == 0) {
19325            doWakeKills = false;
19326        }
19327        if (mLastPowerCheckUptime == 0) {
19328            doCpuKills = false;
19329        }
19330        if (stats.isScreenOn()) {
19331            doWakeKills = false;
19332        }
19333        final long curRealtime = SystemClock.elapsedRealtime();
19334        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19335        final long curUptime = SystemClock.uptimeMillis();
19336        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19337        mLastPowerCheckRealtime = curRealtime;
19338        mLastPowerCheckUptime = curUptime;
19339        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19340            doWakeKills = false;
19341        }
19342        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19343            doCpuKills = false;
19344        }
19345        int i = mLruProcesses.size();
19346        while (i > 0) {
19347            i--;
19348            ProcessRecord app = mLruProcesses.get(i);
19349            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19350                long wtime;
19351                synchronized (stats) {
19352                    wtime = stats.getProcessWakeTime(app.info.uid,
19353                            app.pid, curRealtime);
19354                }
19355                long wtimeUsed = wtime - app.lastWakeTime;
19356                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19357                if (DEBUG_POWER) {
19358                    StringBuilder sb = new StringBuilder(128);
19359                    sb.append("Wake for ");
19360                    app.toShortString(sb);
19361                    sb.append(": over ");
19362                    TimeUtils.formatDuration(realtimeSince, sb);
19363                    sb.append(" used ");
19364                    TimeUtils.formatDuration(wtimeUsed, sb);
19365                    sb.append(" (");
19366                    sb.append((wtimeUsed*100)/realtimeSince);
19367                    sb.append("%)");
19368                    Slog.i(TAG_POWER, sb.toString());
19369                    sb.setLength(0);
19370                    sb.append("CPU for ");
19371                    app.toShortString(sb);
19372                    sb.append(": over ");
19373                    TimeUtils.formatDuration(uptimeSince, sb);
19374                    sb.append(" used ");
19375                    TimeUtils.formatDuration(cputimeUsed, sb);
19376                    sb.append(" (");
19377                    sb.append((cputimeUsed*100)/uptimeSince);
19378                    sb.append("%)");
19379                    Slog.i(TAG_POWER, sb.toString());
19380                }
19381                // If a process has held a wake lock for more
19382                // than 50% of the time during this period,
19383                // that sounds bad.  Kill!
19384                if (doWakeKills && realtimeSince > 0
19385                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19386                    synchronized (stats) {
19387                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19388                                realtimeSince, wtimeUsed);
19389                    }
19390                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19391                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19392                } else if (doCpuKills && uptimeSince > 0
19393                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19394                    synchronized (stats) {
19395                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19396                                uptimeSince, cputimeUsed);
19397                    }
19398                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19399                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19400                } else {
19401                    app.lastWakeTime = wtime;
19402                    app.lastCpuTime = app.curCpuTime;
19403                }
19404            }
19405        }
19406    }
19407
19408    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19409            long nowElapsed) {
19410        boolean success = true;
19411
19412        if (app.curRawAdj != app.setRawAdj) {
19413            app.setRawAdj = app.curRawAdj;
19414        }
19415
19416        int changes = 0;
19417
19418        if (app.curAdj != app.setAdj) {
19419            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19420            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19421                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19422                    + app.adjType);
19423            app.setAdj = app.curAdj;
19424        }
19425
19426        if (app.setSchedGroup != app.curSchedGroup) {
19427            app.setSchedGroup = app.curSchedGroup;
19428            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19429                    "Setting process group of " + app.processName
19430                    + " to " + app.curSchedGroup);
19431            if (app.waitingToKill != null && app.curReceiver == null
19432                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19433                app.kill(app.waitingToKill, true);
19434                success = false;
19435            } else {
19436                if (true) {
19437                    long oldId = Binder.clearCallingIdentity();
19438                    try {
19439                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19440                    } catch (Exception e) {
19441                        Slog.w(TAG, "Failed setting process group of " + app.pid
19442                                + " to " + app.curSchedGroup);
19443                        e.printStackTrace();
19444                    } finally {
19445                        Binder.restoreCallingIdentity(oldId);
19446                    }
19447                } else {
19448                    if (app.thread != null) {
19449                        try {
19450                            app.thread.setSchedulingGroup(app.curSchedGroup);
19451                        } catch (RemoteException e) {
19452                        }
19453                    }
19454                }
19455            }
19456        }
19457        if (app.repForegroundActivities != app.foregroundActivities) {
19458            app.repForegroundActivities = app.foregroundActivities;
19459            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19460        }
19461        if (app.repProcState != app.curProcState) {
19462            app.repProcState = app.curProcState;
19463            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19464            if (app.thread != null) {
19465                try {
19466                    if (false) {
19467                        //RuntimeException h = new RuntimeException("here");
19468                        Slog.i(TAG, "Sending new process state " + app.repProcState
19469                                + " to " + app /*, h*/);
19470                    }
19471                    app.thread.setProcessState(app.repProcState);
19472                } catch (RemoteException e) {
19473                }
19474            }
19475        }
19476        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19477                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19478            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19479                // Experimental code to more aggressively collect pss while
19480                // running test...  the problem is that this tends to collect
19481                // the data right when a process is transitioning between process
19482                // states, which well tend to give noisy data.
19483                long start = SystemClock.uptimeMillis();
19484                long pss = Debug.getPss(app.pid, mTmpLong, null);
19485                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19486                mPendingPssProcesses.remove(app);
19487                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19488                        + " to " + app.curProcState + ": "
19489                        + (SystemClock.uptimeMillis()-start) + "ms");
19490            }
19491            app.lastStateTime = now;
19492            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19493                    mTestPssMode, isSleeping(), now);
19494            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19495                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19496                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19497                    + (app.nextPssTime-now) + ": " + app);
19498        } else {
19499            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19500                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19501                    mTestPssMode)))) {
19502                requestPssLocked(app, app.setProcState);
19503                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19504                        mTestPssMode, isSleeping(), now);
19505            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19506                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19507        }
19508        if (app.setProcState != app.curProcState) {
19509            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19510                    "Proc state change of " + app.processName
19511                            + " to " + app.curProcState);
19512            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19513            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19514            if (setImportant && !curImportant) {
19515                // This app is no longer something we consider important enough to allow to
19516                // use arbitrary amounts of battery power.  Note
19517                // its current wake lock time to later know to kill it if
19518                // it is not behaving well.
19519                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19520                synchronized (stats) {
19521                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19522                            app.pid, nowElapsed);
19523                }
19524                app.lastCpuTime = app.curCpuTime;
19525
19526            }
19527            // Inform UsageStats of important process state change
19528            // Must be called before updating setProcState
19529            maybeUpdateUsageStatsLocked(app, nowElapsed);
19530
19531            app.setProcState = app.curProcState;
19532            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19533                app.notCachedSinceIdle = false;
19534            }
19535            if (!doingAll) {
19536                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19537            } else {
19538                app.procStateChanged = true;
19539            }
19540        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19541                > USAGE_STATS_INTERACTION_INTERVAL) {
19542            // For apps that sit around for a long time in the interactive state, we need
19543            // to report this at least once a day so they don't go idle.
19544            maybeUpdateUsageStatsLocked(app, nowElapsed);
19545        }
19546
19547        if (changes != 0) {
19548            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19549                    "Changes in " + app + ": " + changes);
19550            int i = mPendingProcessChanges.size()-1;
19551            ProcessChangeItem item = null;
19552            while (i >= 0) {
19553                item = mPendingProcessChanges.get(i);
19554                if (item.pid == app.pid) {
19555                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19556                            "Re-using existing item: " + item);
19557                    break;
19558                }
19559                i--;
19560            }
19561            if (i < 0) {
19562                // No existing item in pending changes; need a new one.
19563                final int NA = mAvailProcessChanges.size();
19564                if (NA > 0) {
19565                    item = mAvailProcessChanges.remove(NA-1);
19566                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19567                            "Retrieving available item: " + item);
19568                } else {
19569                    item = new ProcessChangeItem();
19570                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19571                            "Allocating new item: " + item);
19572                }
19573                item.changes = 0;
19574                item.pid = app.pid;
19575                item.uid = app.info.uid;
19576                if (mPendingProcessChanges.size() == 0) {
19577                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19578                            "*** Enqueueing dispatch processes changed!");
19579                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19580                }
19581                mPendingProcessChanges.add(item);
19582            }
19583            item.changes |= changes;
19584            item.processState = app.repProcState;
19585            item.foregroundActivities = app.repForegroundActivities;
19586            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19587                    "Item " + Integer.toHexString(System.identityHashCode(item))
19588                    + " " + app.toShortString() + ": changes=" + item.changes
19589                    + " procState=" + item.processState
19590                    + " foreground=" + item.foregroundActivities
19591                    + " type=" + app.adjType + " source=" + app.adjSource
19592                    + " target=" + app.adjTarget);
19593        }
19594
19595        return success;
19596    }
19597
19598    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19599        final UidRecord.ChangeItem pendingChange;
19600        if (uidRec == null || uidRec.pendingChange == null) {
19601            if (mPendingUidChanges.size() == 0) {
19602                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19603                        "*** Enqueueing dispatch uid changed!");
19604                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19605            }
19606            final int NA = mAvailUidChanges.size();
19607            if (NA > 0) {
19608                pendingChange = mAvailUidChanges.remove(NA-1);
19609                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19610                        "Retrieving available item: " + pendingChange);
19611            } else {
19612                pendingChange = new UidRecord.ChangeItem();
19613                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19614                        "Allocating new item: " + pendingChange);
19615            }
19616            if (uidRec != null) {
19617                uidRec.pendingChange = pendingChange;
19618                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19619                    // If this uid is going away, and we haven't yet reported it is gone,
19620                    // then do so now.
19621                    change = UidRecord.CHANGE_GONE_IDLE;
19622                }
19623            } else if (uid < 0) {
19624                throw new IllegalArgumentException("No UidRecord or uid");
19625            }
19626            pendingChange.uidRecord = uidRec;
19627            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19628            mPendingUidChanges.add(pendingChange);
19629        } else {
19630            pendingChange = uidRec.pendingChange;
19631            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19632                change = UidRecord.CHANGE_GONE_IDLE;
19633            }
19634        }
19635        pendingChange.change = change;
19636        pendingChange.processState = uidRec != null
19637                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19638    }
19639
19640    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19641            String authority) {
19642        if (app == null) return;
19643        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19644            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19645            if (userState == null) return;
19646            final long now = SystemClock.elapsedRealtime();
19647            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19648            if (lastReported == null || lastReported < now - 60 * 1000L) {
19649                mUsageStatsService.reportContentProviderUsage(
19650                        authority, providerPkgName, app.userId);
19651                userState.mProviderLastReportedFg.put(authority, now);
19652            }
19653        }
19654    }
19655
19656    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19657        if (DEBUG_USAGE_STATS) {
19658            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19659                    + "] state changes: old = " + app.setProcState + ", new = "
19660                    + app.curProcState);
19661        }
19662        if (mUsageStatsService == null) {
19663            return;
19664        }
19665        boolean isInteraction;
19666        // To avoid some abuse patterns, we are going to be careful about what we consider
19667        // to be an app interaction.  Being the top activity doesn't count while the display
19668        // is sleeping, nor do short foreground services.
19669        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19670            isInteraction = true;
19671            app.fgInteractionTime = 0;
19672        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19673            if (app.fgInteractionTime == 0) {
19674                app.fgInteractionTime = nowElapsed;
19675                isInteraction = false;
19676            } else {
19677                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19678            }
19679        } else {
19680            isInteraction = app.curProcState
19681                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19682            app.fgInteractionTime = 0;
19683        }
19684        if (isInteraction && (!app.reportedInteraction
19685                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19686            app.interactionEventTime = nowElapsed;
19687            String[] packages = app.getPackageList();
19688            if (packages != null) {
19689                for (int i = 0; i < packages.length; i++) {
19690                    mUsageStatsService.reportEvent(packages[i], app.userId,
19691                            UsageEvents.Event.SYSTEM_INTERACTION);
19692                }
19693            }
19694        }
19695        app.reportedInteraction = isInteraction;
19696        if (!isInteraction) {
19697            app.interactionEventTime = 0;
19698        }
19699    }
19700
19701    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19702        if (proc.thread != null) {
19703            if (proc.baseProcessTracker != null) {
19704                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19705            }
19706        }
19707    }
19708
19709    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19710            ProcessRecord TOP_APP, boolean doingAll, long now) {
19711        if (app.thread == null) {
19712            return false;
19713        }
19714
19715        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19716
19717        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19718    }
19719
19720    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19721            boolean oomAdj) {
19722        if (isForeground != proc.foregroundServices) {
19723            proc.foregroundServices = isForeground;
19724            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19725                    proc.info.uid);
19726            if (isForeground) {
19727                if (curProcs == null) {
19728                    curProcs = new ArrayList<ProcessRecord>();
19729                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19730                }
19731                if (!curProcs.contains(proc)) {
19732                    curProcs.add(proc);
19733                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19734                            proc.info.packageName, proc.info.uid);
19735                }
19736            } else {
19737                if (curProcs != null) {
19738                    if (curProcs.remove(proc)) {
19739                        mBatteryStatsService.noteEvent(
19740                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19741                                proc.info.packageName, proc.info.uid);
19742                        if (curProcs.size() <= 0) {
19743                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19744                        }
19745                    }
19746                }
19747            }
19748            if (oomAdj) {
19749                updateOomAdjLocked();
19750            }
19751        }
19752    }
19753
19754    private final ActivityRecord resumedAppLocked() {
19755        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19756        String pkg;
19757        int uid;
19758        if (act != null) {
19759            pkg = act.packageName;
19760            uid = act.info.applicationInfo.uid;
19761        } else {
19762            pkg = null;
19763            uid = -1;
19764        }
19765        // Has the UID or resumed package name changed?
19766        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19767                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19768            if (mCurResumedPackage != null) {
19769                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19770                        mCurResumedPackage, mCurResumedUid);
19771            }
19772            mCurResumedPackage = pkg;
19773            mCurResumedUid = uid;
19774            if (mCurResumedPackage != null) {
19775                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19776                        mCurResumedPackage, mCurResumedUid);
19777            }
19778        }
19779        return act;
19780    }
19781
19782    final boolean updateOomAdjLocked(ProcessRecord app) {
19783        final ActivityRecord TOP_ACT = resumedAppLocked();
19784        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19785        final boolean wasCached = app.cached;
19786
19787        mAdjSeq++;
19788
19789        // This is the desired cached adjusment we want to tell it to use.
19790        // If our app is currently cached, we know it, and that is it.  Otherwise,
19791        // we don't know it yet, and it needs to now be cached we will then
19792        // need to do a complete oom adj.
19793        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19794                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19795        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19796                SystemClock.uptimeMillis());
19797        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19798            // Changed to/from cached state, so apps after it in the LRU
19799            // list may also be changed.
19800            updateOomAdjLocked();
19801        }
19802        return success;
19803    }
19804
19805    final void updateOomAdjLocked() {
19806        final ActivityRecord TOP_ACT = resumedAppLocked();
19807        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19808        final long now = SystemClock.uptimeMillis();
19809        final long nowElapsed = SystemClock.elapsedRealtime();
19810        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19811        final int N = mLruProcesses.size();
19812
19813        if (false) {
19814            RuntimeException e = new RuntimeException();
19815            e.fillInStackTrace();
19816            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19817        }
19818
19819        // Reset state in all uid records.
19820        for (int i=mActiveUids.size()-1; i>=0; i--) {
19821            final UidRecord uidRec = mActiveUids.valueAt(i);
19822            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19823                    "Starting update of " + uidRec);
19824            uidRec.reset();
19825        }
19826
19827        mStackSupervisor.rankTaskLayersIfNeeded();
19828
19829        mAdjSeq++;
19830        mNewNumServiceProcs = 0;
19831        mNewNumAServiceProcs = 0;
19832
19833        final int emptyProcessLimit;
19834        final int cachedProcessLimit;
19835        if (mProcessLimit <= 0) {
19836            emptyProcessLimit = cachedProcessLimit = 0;
19837        } else if (mProcessLimit == 1) {
19838            emptyProcessLimit = 1;
19839            cachedProcessLimit = 0;
19840        } else {
19841            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19842            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19843        }
19844
19845        // Let's determine how many processes we have running vs.
19846        // how many slots we have for background processes; we may want
19847        // to put multiple processes in a slot of there are enough of
19848        // them.
19849        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19850                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19851        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19852        if (numEmptyProcs > cachedProcessLimit) {
19853            // If there are more empty processes than our limit on cached
19854            // processes, then use the cached process limit for the factor.
19855            // This ensures that the really old empty processes get pushed
19856            // down to the bottom, so if we are running low on memory we will
19857            // have a better chance at keeping around more cached processes
19858            // instead of a gazillion empty processes.
19859            numEmptyProcs = cachedProcessLimit;
19860        }
19861        int emptyFactor = numEmptyProcs/numSlots;
19862        if (emptyFactor < 1) emptyFactor = 1;
19863        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19864        if (cachedFactor < 1) cachedFactor = 1;
19865        int stepCached = 0;
19866        int stepEmpty = 0;
19867        int numCached = 0;
19868        int numEmpty = 0;
19869        int numTrimming = 0;
19870
19871        mNumNonCachedProcs = 0;
19872        mNumCachedHiddenProcs = 0;
19873
19874        // First update the OOM adjustment for each of the
19875        // application processes based on their current state.
19876        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19877        int nextCachedAdj = curCachedAdj+1;
19878        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19879        int nextEmptyAdj = curEmptyAdj+2;
19880        for (int i=N-1; i>=0; i--) {
19881            ProcessRecord app = mLruProcesses.get(i);
19882            if (!app.killedByAm && app.thread != null) {
19883                app.procStateChanged = false;
19884                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19885
19886                // If we haven't yet assigned the final cached adj
19887                // to the process, do that now.
19888                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19889                    switch (app.curProcState) {
19890                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19891                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19892                            // This process is a cached process holding activities...
19893                            // assign it the next cached value for that type, and then
19894                            // step that cached level.
19895                            app.curRawAdj = curCachedAdj;
19896                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19897                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19898                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19899                                    + ")");
19900                            if (curCachedAdj != nextCachedAdj) {
19901                                stepCached++;
19902                                if (stepCached >= cachedFactor) {
19903                                    stepCached = 0;
19904                                    curCachedAdj = nextCachedAdj;
19905                                    nextCachedAdj += 2;
19906                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19907                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19908                                    }
19909                                }
19910                            }
19911                            break;
19912                        default:
19913                            // For everything else, assign next empty cached process
19914                            // level and bump that up.  Note that this means that
19915                            // long-running services that have dropped down to the
19916                            // cached level will be treated as empty (since their process
19917                            // state is still as a service), which is what we want.
19918                            app.curRawAdj = curEmptyAdj;
19919                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19920                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19921                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19922                                    + ")");
19923                            if (curEmptyAdj != nextEmptyAdj) {
19924                                stepEmpty++;
19925                                if (stepEmpty >= emptyFactor) {
19926                                    stepEmpty = 0;
19927                                    curEmptyAdj = nextEmptyAdj;
19928                                    nextEmptyAdj += 2;
19929                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19930                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19931                                    }
19932                                }
19933                            }
19934                            break;
19935                    }
19936                }
19937
19938                applyOomAdjLocked(app, true, now, nowElapsed);
19939
19940                // Count the number of process types.
19941                switch (app.curProcState) {
19942                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19943                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19944                        mNumCachedHiddenProcs++;
19945                        numCached++;
19946                        if (numCached > cachedProcessLimit) {
19947                            app.kill("cached #" + numCached, true);
19948                        }
19949                        break;
19950                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19951                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19952                                && app.lastActivityTime < oldTime) {
19953                            app.kill("empty for "
19954                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19955                                    / 1000) + "s", true);
19956                        } else {
19957                            numEmpty++;
19958                            if (numEmpty > emptyProcessLimit) {
19959                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19960                            }
19961                        }
19962                        break;
19963                    default:
19964                        mNumNonCachedProcs++;
19965                        break;
19966                }
19967
19968                if (app.isolated && app.services.size() <= 0) {
19969                    // If this is an isolated process, and there are no
19970                    // services running in it, then the process is no longer
19971                    // needed.  We agressively kill these because we can by
19972                    // definition not re-use the same process again, and it is
19973                    // good to avoid having whatever code was running in them
19974                    // left sitting around after no longer needed.
19975                    app.kill("isolated not needed", true);
19976                } else {
19977                    // Keeping this process, update its uid.
19978                    final UidRecord uidRec = app.uidRecord;
19979                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19980                        uidRec.curProcState = app.curProcState;
19981                    }
19982                }
19983
19984                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19985                        && !app.killedByAm) {
19986                    numTrimming++;
19987                }
19988            }
19989        }
19990
19991        mNumServiceProcs = mNewNumServiceProcs;
19992
19993        // Now determine the memory trimming level of background processes.
19994        // Unfortunately we need to start at the back of the list to do this
19995        // properly.  We only do this if the number of background apps we
19996        // are managing to keep around is less than half the maximum we desire;
19997        // if we are keeping a good number around, we'll let them use whatever
19998        // memory they want.
19999        final int numCachedAndEmpty = numCached + numEmpty;
20000        int memFactor;
20001        if (numCached <= ProcessList.TRIM_CACHED_APPS
20002                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20003            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20004                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20005            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20006                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20007            } else {
20008                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20009            }
20010        } else {
20011            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20012        }
20013        // We always allow the memory level to go up (better).  We only allow it to go
20014        // down if we are in a state where that is allowed, *and* the total number of processes
20015        // has gone down since last time.
20016        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20017                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20018                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20019        if (memFactor > mLastMemoryLevel) {
20020            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20021                memFactor = mLastMemoryLevel;
20022                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20023            }
20024        }
20025        mLastMemoryLevel = memFactor;
20026        mLastNumProcesses = mLruProcesses.size();
20027        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20028        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20029        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20030            if (mLowRamStartTime == 0) {
20031                mLowRamStartTime = now;
20032            }
20033            int step = 0;
20034            int fgTrimLevel;
20035            switch (memFactor) {
20036                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20037                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20038                    break;
20039                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20040                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20041                    break;
20042                default:
20043                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20044                    break;
20045            }
20046            int factor = numTrimming/3;
20047            int minFactor = 2;
20048            if (mHomeProcess != null) minFactor++;
20049            if (mPreviousProcess != null) minFactor++;
20050            if (factor < minFactor) factor = minFactor;
20051            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20052            for (int i=N-1; i>=0; i--) {
20053                ProcessRecord app = mLruProcesses.get(i);
20054                if (allChanged || app.procStateChanged) {
20055                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20056                    app.procStateChanged = false;
20057                }
20058                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20059                        && !app.killedByAm) {
20060                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20061                        try {
20062                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20063                                    "Trimming memory of " + app.processName + " to " + curLevel);
20064                            app.thread.scheduleTrimMemory(curLevel);
20065                        } catch (RemoteException e) {
20066                        }
20067                        if (false) {
20068                            // For now we won't do this; our memory trimming seems
20069                            // to be good enough at this point that destroying
20070                            // activities causes more harm than good.
20071                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20072                                    && app != mHomeProcess && app != mPreviousProcess) {
20073                                // Need to do this on its own message because the stack may not
20074                                // be in a consistent state at this point.
20075                                // For these apps we will also finish their activities
20076                                // to help them free memory.
20077                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20078                            }
20079                        }
20080                    }
20081                    app.trimMemoryLevel = curLevel;
20082                    step++;
20083                    if (step >= factor) {
20084                        step = 0;
20085                        switch (curLevel) {
20086                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20087                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20088                                break;
20089                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20090                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20091                                break;
20092                        }
20093                    }
20094                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20095                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20096                            && app.thread != null) {
20097                        try {
20098                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20099                                    "Trimming memory of heavy-weight " + app.processName
20100                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20101                            app.thread.scheduleTrimMemory(
20102                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20103                        } catch (RemoteException e) {
20104                        }
20105                    }
20106                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20107                } else {
20108                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20109                            || app.systemNoUi) && app.pendingUiClean) {
20110                        // If this application is now in the background and it
20111                        // had done UI, then give it the special trim level to
20112                        // have it free UI resources.
20113                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20114                        if (app.trimMemoryLevel < level && app.thread != null) {
20115                            try {
20116                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20117                                        "Trimming memory of bg-ui " + app.processName
20118                                        + " to " + level);
20119                                app.thread.scheduleTrimMemory(level);
20120                            } catch (RemoteException e) {
20121                            }
20122                        }
20123                        app.pendingUiClean = false;
20124                    }
20125                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20126                        try {
20127                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20128                                    "Trimming memory of fg " + app.processName
20129                                    + " to " + fgTrimLevel);
20130                            app.thread.scheduleTrimMemory(fgTrimLevel);
20131                        } catch (RemoteException e) {
20132                        }
20133                    }
20134                    app.trimMemoryLevel = fgTrimLevel;
20135                }
20136            }
20137        } else {
20138            if (mLowRamStartTime != 0) {
20139                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20140                mLowRamStartTime = 0;
20141            }
20142            for (int i=N-1; i>=0; i--) {
20143                ProcessRecord app = mLruProcesses.get(i);
20144                if (allChanged || app.procStateChanged) {
20145                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20146                    app.procStateChanged = false;
20147                }
20148                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20149                        || app.systemNoUi) && app.pendingUiClean) {
20150                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20151                            && app.thread != null) {
20152                        try {
20153                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20154                                    "Trimming memory of ui hidden " + app.processName
20155                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20156                            app.thread.scheduleTrimMemory(
20157                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20158                        } catch (RemoteException e) {
20159                        }
20160                    }
20161                    app.pendingUiClean = false;
20162                }
20163                app.trimMemoryLevel = 0;
20164            }
20165        }
20166
20167        if (mAlwaysFinishActivities) {
20168            // Need to do this on its own message because the stack may not
20169            // be in a consistent state at this point.
20170            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20171        }
20172
20173        if (allChanged) {
20174            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20175        }
20176
20177        // Update from any uid changes.
20178        for (int i=mActiveUids.size()-1; i>=0; i--) {
20179            final UidRecord uidRec = mActiveUids.valueAt(i);
20180            int uidChange = UidRecord.CHANGE_PROCSTATE;
20181            if (uidRec.setProcState != uidRec.curProcState) {
20182                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20183                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20184                        + " to " + uidRec.curProcState);
20185                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20186                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20187                        uidRec.lastBackgroundTime = nowElapsed;
20188                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20189                            // Note: the background settle time is in elapsed realtime, while
20190                            // the handler time base is uptime.  All this means is that we may
20191                            // stop background uids later than we had intended, but that only
20192                            // happens because the device was sleeping so we are okay anyway.
20193                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20194                        }
20195                    }
20196                } else {
20197                    if (uidRec.idle) {
20198                        uidChange = UidRecord.CHANGE_ACTIVE;
20199                        uidRec.idle = false;
20200                    }
20201                    uidRec.lastBackgroundTime = 0;
20202                }
20203                uidRec.setProcState = uidRec.curProcState;
20204                enqueueUidChangeLocked(uidRec, -1, uidChange);
20205                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20206            }
20207        }
20208
20209        if (mProcessStats.shouldWriteNowLocked(now)) {
20210            mHandler.post(new Runnable() {
20211                @Override public void run() {
20212                    synchronized (ActivityManagerService.this) {
20213                        mProcessStats.writeStateAsyncLocked();
20214                    }
20215                }
20216            });
20217        }
20218
20219        if (DEBUG_OOM_ADJ) {
20220            final long duration = SystemClock.uptimeMillis() - now;
20221            if (false) {
20222                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20223                        new RuntimeException("here").fillInStackTrace());
20224            } else {
20225                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20226            }
20227        }
20228    }
20229
20230    final void idleUids() {
20231        synchronized (this) {
20232            final long nowElapsed = SystemClock.elapsedRealtime();
20233            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20234            long nextTime = 0;
20235            for (int i=mActiveUids.size()-1; i>=0; i--) {
20236                final UidRecord uidRec = mActiveUids.valueAt(i);
20237                final long bgTime = uidRec.lastBackgroundTime;
20238                if (bgTime > 0 && !uidRec.idle) {
20239                    if (bgTime <= maxBgTime) {
20240                        uidRec.idle = true;
20241                        doStopUidLocked(uidRec.uid, uidRec);
20242                    } else {
20243                        if (nextTime == 0 || nextTime > bgTime) {
20244                            nextTime = bgTime;
20245                        }
20246                    }
20247                }
20248            }
20249            if (nextTime > 0) {
20250                mHandler.removeMessages(IDLE_UIDS_MSG);
20251                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20252                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20253            }
20254        }
20255    }
20256
20257    final void runInBackgroundDisabled(int uid) {
20258        synchronized (this) {
20259            UidRecord uidRec = mActiveUids.get(uid);
20260            if (uidRec != null) {
20261                // This uid is actually running...  should it be considered background now?
20262                if (uidRec.idle) {
20263                    doStopUidLocked(uidRec.uid, uidRec);
20264                }
20265            } else {
20266                // This uid isn't actually running...  still send a report about it being "stopped".
20267                doStopUidLocked(uid, null);
20268            }
20269        }
20270    }
20271
20272    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20273        mServices.stopInBackgroundLocked(uid);
20274        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20275    }
20276
20277    final void trimApplications() {
20278        synchronized (this) {
20279            int i;
20280
20281            // First remove any unused application processes whose package
20282            // has been removed.
20283            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20284                final ProcessRecord app = mRemovedProcesses.get(i);
20285                if (app.activities.size() == 0
20286                        && app.curReceiver == null && app.services.size() == 0) {
20287                    Slog.i(
20288                        TAG, "Exiting empty application process "
20289                        + app.processName + " ("
20290                        + (app.thread != null ? app.thread.asBinder() : null)
20291                        + ")\n");
20292                    if (app.pid > 0 && app.pid != MY_PID) {
20293                        app.kill("empty", false);
20294                    } else {
20295                        try {
20296                            app.thread.scheduleExit();
20297                        } catch (Exception e) {
20298                            // Ignore exceptions.
20299                        }
20300                    }
20301                    cleanUpApplicationRecordLocked(app, false, true, -1);
20302                    mRemovedProcesses.remove(i);
20303
20304                    if (app.persistent) {
20305                        addAppLocked(app.info, false, null /* ABI override */);
20306                    }
20307                }
20308            }
20309
20310            // Now update the oom adj for all processes.
20311            updateOomAdjLocked();
20312        }
20313    }
20314
20315    /** This method sends the specified signal to each of the persistent apps */
20316    public void signalPersistentProcesses(int sig) throws RemoteException {
20317        if (sig != Process.SIGNAL_USR1) {
20318            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20319        }
20320
20321        synchronized (this) {
20322            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20323                    != PackageManager.PERMISSION_GRANTED) {
20324                throw new SecurityException("Requires permission "
20325                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20326            }
20327
20328            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20329                ProcessRecord r = mLruProcesses.get(i);
20330                if (r.thread != null && r.persistent) {
20331                    Process.sendSignal(r.pid, sig);
20332                }
20333            }
20334        }
20335    }
20336
20337    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20338        if (proc == null || proc == mProfileProc) {
20339            proc = mProfileProc;
20340            profileType = mProfileType;
20341            clearProfilerLocked();
20342        }
20343        if (proc == null) {
20344            return;
20345        }
20346        try {
20347            proc.thread.profilerControl(false, null, profileType);
20348        } catch (RemoteException e) {
20349            throw new IllegalStateException("Process disappeared");
20350        }
20351    }
20352
20353    private void clearProfilerLocked() {
20354        if (mProfileFd != null) {
20355            try {
20356                mProfileFd.close();
20357            } catch (IOException e) {
20358            }
20359        }
20360        mProfileApp = null;
20361        mProfileProc = null;
20362        mProfileFile = null;
20363        mProfileType = 0;
20364        mAutoStopProfiler = false;
20365        mSamplingInterval = 0;
20366    }
20367
20368    public boolean profileControl(String process, int userId, boolean start,
20369            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20370
20371        try {
20372            synchronized (this) {
20373                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20374                // its own permission.
20375                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20376                        != PackageManager.PERMISSION_GRANTED) {
20377                    throw new SecurityException("Requires permission "
20378                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20379                }
20380
20381                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20382                    throw new IllegalArgumentException("null profile info or fd");
20383                }
20384
20385                ProcessRecord proc = null;
20386                if (process != null) {
20387                    proc = findProcessLocked(process, userId, "profileControl");
20388                }
20389
20390                if (start && (proc == null || proc.thread == null)) {
20391                    throw new IllegalArgumentException("Unknown process: " + process);
20392                }
20393
20394                if (start) {
20395                    stopProfilerLocked(null, 0);
20396                    setProfileApp(proc.info, proc.processName, profilerInfo);
20397                    mProfileProc = proc;
20398                    mProfileType = profileType;
20399                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20400                    try {
20401                        fd = fd.dup();
20402                    } catch (IOException e) {
20403                        fd = null;
20404                    }
20405                    profilerInfo.profileFd = fd;
20406                    proc.thread.profilerControl(start, profilerInfo, profileType);
20407                    fd = null;
20408                    mProfileFd = null;
20409                } else {
20410                    stopProfilerLocked(proc, profileType);
20411                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20412                        try {
20413                            profilerInfo.profileFd.close();
20414                        } catch (IOException e) {
20415                        }
20416                    }
20417                }
20418
20419                return true;
20420            }
20421        } catch (RemoteException e) {
20422            throw new IllegalStateException("Process disappeared");
20423        } finally {
20424            if (profilerInfo != null && profilerInfo.profileFd != null) {
20425                try {
20426                    profilerInfo.profileFd.close();
20427                } catch (IOException e) {
20428                }
20429            }
20430        }
20431    }
20432
20433    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20434        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20435                userId, true, ALLOW_FULL_ONLY, callName, null);
20436        ProcessRecord proc = null;
20437        try {
20438            int pid = Integer.parseInt(process);
20439            synchronized (mPidsSelfLocked) {
20440                proc = mPidsSelfLocked.get(pid);
20441            }
20442        } catch (NumberFormatException e) {
20443        }
20444
20445        if (proc == null) {
20446            ArrayMap<String, SparseArray<ProcessRecord>> all
20447                    = mProcessNames.getMap();
20448            SparseArray<ProcessRecord> procs = all.get(process);
20449            if (procs != null && procs.size() > 0) {
20450                proc = procs.valueAt(0);
20451                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20452                    for (int i=1; i<procs.size(); i++) {
20453                        ProcessRecord thisProc = procs.valueAt(i);
20454                        if (thisProc.userId == userId) {
20455                            proc = thisProc;
20456                            break;
20457                        }
20458                    }
20459                }
20460            }
20461        }
20462
20463        return proc;
20464    }
20465
20466    public boolean dumpHeap(String process, int userId, boolean managed,
20467            String path, ParcelFileDescriptor fd) throws RemoteException {
20468
20469        try {
20470            synchronized (this) {
20471                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20472                // its own permission (same as profileControl).
20473                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20474                        != PackageManager.PERMISSION_GRANTED) {
20475                    throw new SecurityException("Requires permission "
20476                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20477                }
20478
20479                if (fd == null) {
20480                    throw new IllegalArgumentException("null fd");
20481                }
20482
20483                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20484                if (proc == null || proc.thread == null) {
20485                    throw new IllegalArgumentException("Unknown process: " + process);
20486                }
20487
20488                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20489                if (!isDebuggable) {
20490                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20491                        throw new SecurityException("Process not debuggable: " + proc);
20492                    }
20493                }
20494
20495                proc.thread.dumpHeap(managed, path, fd);
20496                fd = null;
20497                return true;
20498            }
20499        } catch (RemoteException e) {
20500            throw new IllegalStateException("Process disappeared");
20501        } finally {
20502            if (fd != null) {
20503                try {
20504                    fd.close();
20505                } catch (IOException e) {
20506                }
20507            }
20508        }
20509    }
20510
20511    @Override
20512    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20513            String reportPackage) {
20514        if (processName != null) {
20515            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20516                    "setDumpHeapDebugLimit()");
20517        } else {
20518            synchronized (mPidsSelfLocked) {
20519                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20520                if (proc == null) {
20521                    throw new SecurityException("No process found for calling pid "
20522                            + Binder.getCallingPid());
20523                }
20524                if (!Build.IS_DEBUGGABLE
20525                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20526                    throw new SecurityException("Not running a debuggable build");
20527                }
20528                processName = proc.processName;
20529                uid = proc.uid;
20530                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20531                    throw new SecurityException("Package " + reportPackage + " is not running in "
20532                            + proc);
20533                }
20534            }
20535        }
20536        synchronized (this) {
20537            if (maxMemSize > 0) {
20538                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20539            } else {
20540                if (uid != 0) {
20541                    mMemWatchProcesses.remove(processName, uid);
20542                } else {
20543                    mMemWatchProcesses.getMap().remove(processName);
20544                }
20545            }
20546        }
20547    }
20548
20549    @Override
20550    public void dumpHeapFinished(String path) {
20551        synchronized (this) {
20552            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20553                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20554                        + " does not match last pid " + mMemWatchDumpPid);
20555                return;
20556            }
20557            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20558                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20559                        + " does not match last path " + mMemWatchDumpFile);
20560                return;
20561            }
20562            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20563            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20564        }
20565    }
20566
20567    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20568    public void monitor() {
20569        synchronized (this) { }
20570    }
20571
20572    void onCoreSettingsChange(Bundle settings) {
20573        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20574            ProcessRecord processRecord = mLruProcesses.get(i);
20575            try {
20576                if (processRecord.thread != null) {
20577                    processRecord.thread.setCoreSettings(settings);
20578                }
20579            } catch (RemoteException re) {
20580                /* ignore */
20581            }
20582        }
20583    }
20584
20585    // Multi-user methods
20586
20587    /**
20588     * Start user, if its not already running, but don't bring it to foreground.
20589     */
20590    @Override
20591    public boolean startUserInBackground(final int userId) {
20592        return mUserController.startUser(userId, /* foreground */ false);
20593    }
20594
20595    @Override
20596    public boolean unlockUser(int userId, byte[] token) {
20597        return mUserController.unlockUser(userId, token);
20598    }
20599
20600    @Override
20601    public boolean switchUser(final int targetUserId) {
20602        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20603        UserInfo currentUserInfo;
20604        UserInfo targetUserInfo;
20605        synchronized (this) {
20606            int currentUserId = mUserController.getCurrentUserIdLocked();
20607            currentUserInfo = mUserController.getUserInfo(currentUserId);
20608            targetUserInfo = mUserController.getUserInfo(targetUserId);
20609            if (targetUserInfo == null) {
20610                Slog.w(TAG, "No user info for user #" + targetUserId);
20611                return false;
20612            }
20613            if (targetUserInfo.isManagedProfile()) {
20614                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20615                return false;
20616            }
20617            mUserController.setTargetUserIdLocked(targetUserId);
20618        }
20619        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20620        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20621        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20622        return true;
20623    }
20624
20625    void scheduleStartProfilesLocked() {
20626        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20627            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20628                    DateUtils.SECOND_IN_MILLIS);
20629        }
20630    }
20631
20632    @Override
20633    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20634        return mUserController.stopUser(userId, force, callback);
20635    }
20636
20637    void onUserRemovedLocked(int userId) {
20638        mRecentTasks.removeTasksForUserLocked(userId);
20639    }
20640
20641    @Override
20642    public UserInfo getCurrentUser() {
20643        return mUserController.getCurrentUser();
20644    }
20645
20646    @Override
20647    public boolean isUserRunning(int userId, int flags) {
20648        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20649                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20650            String msg = "Permission Denial: isUserRunning() from pid="
20651                    + Binder.getCallingPid()
20652                    + ", uid=" + Binder.getCallingUid()
20653                    + " requires " + INTERACT_ACROSS_USERS;
20654            Slog.w(TAG, msg);
20655            throw new SecurityException(msg);
20656        }
20657        synchronized (this) {
20658            return mUserController.isUserRunningLocked(userId, flags);
20659        }
20660    }
20661
20662    @Override
20663    public int[] getRunningUserIds() {
20664        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20665                != PackageManager.PERMISSION_GRANTED) {
20666            String msg = "Permission Denial: isUserRunning() from pid="
20667                    + Binder.getCallingPid()
20668                    + ", uid=" + Binder.getCallingUid()
20669                    + " requires " + INTERACT_ACROSS_USERS;
20670            Slog.w(TAG, msg);
20671            throw new SecurityException(msg);
20672        }
20673        synchronized (this) {
20674            return mUserController.getStartedUserArrayLocked();
20675        }
20676    }
20677
20678    @Override
20679    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20680        mUserController.registerUserSwitchObserver(observer);
20681    }
20682
20683    @Override
20684    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20685        mUserController.unregisterUserSwitchObserver(observer);
20686    }
20687
20688    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20689        if (info == null) return null;
20690        ApplicationInfo newInfo = new ApplicationInfo(info);
20691        newInfo.initForUser(userId);
20692        return newInfo;
20693    }
20694
20695    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20696        if (aInfo == null
20697                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20698            return aInfo;
20699        }
20700
20701        ActivityInfo info = new ActivityInfo(aInfo);
20702        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20703        return info;
20704    }
20705
20706    private boolean processSanityChecksLocked(ProcessRecord process) {
20707        if (process == null || process.thread == null) {
20708            return false;
20709        }
20710
20711        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20712        if (!isDebuggable) {
20713            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20714                return false;
20715            }
20716        }
20717
20718        return true;
20719    }
20720
20721    public boolean startBinderTracking() throws RemoteException {
20722        synchronized (this) {
20723            mBinderTransactionTrackingEnabled = true;
20724            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20725            // permission (same as profileControl).
20726            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20727                    != PackageManager.PERMISSION_GRANTED) {
20728                throw new SecurityException("Requires permission "
20729                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20730            }
20731
20732            for (int i = 0; i < mLruProcesses.size(); i++) {
20733                ProcessRecord process = mLruProcesses.get(i);
20734                if (!processSanityChecksLocked(process)) {
20735                    continue;
20736                }
20737                try {
20738                    process.thread.startBinderTracking();
20739                } catch (RemoteException e) {
20740                    Log.v(TAG, "Process disappared");
20741                }
20742            }
20743            return true;
20744        }
20745    }
20746
20747    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20748        try {
20749            synchronized (this) {
20750                mBinderTransactionTrackingEnabled = false;
20751                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20752                // permission (same as profileControl).
20753                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20754                        != PackageManager.PERMISSION_GRANTED) {
20755                    throw new SecurityException("Requires permission "
20756                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20757                }
20758
20759                if (fd == null) {
20760                    throw new IllegalArgumentException("null fd");
20761                }
20762
20763                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20764                pw.println("Binder transaction traces for all processes.\n");
20765                for (ProcessRecord process : mLruProcesses) {
20766                    if (!processSanityChecksLocked(process)) {
20767                        continue;
20768                    }
20769
20770                    pw.println("Traces for process: " + process.processName);
20771                    pw.flush();
20772                    try {
20773                        TransferPipe tp = new TransferPipe();
20774                        try {
20775                            process.thread.stopBinderTrackingAndDump(
20776                                    tp.getWriteFd().getFileDescriptor());
20777                            tp.go(fd.getFileDescriptor());
20778                        } finally {
20779                            tp.kill();
20780                        }
20781                    } catch (IOException e) {
20782                        pw.println("Failure while dumping IPC traces from " + process +
20783                                ".  Exception: " + e);
20784                        pw.flush();
20785                    } catch (RemoteException e) {
20786                        pw.println("Got a RemoteException while dumping IPC traces from " +
20787                                process + ".  Exception: " + e);
20788                        pw.flush();
20789                    }
20790                }
20791                fd = null;
20792                return true;
20793            }
20794        } finally {
20795            if (fd != null) {
20796                try {
20797                    fd.close();
20798                } catch (IOException e) {
20799                }
20800            }
20801        }
20802    }
20803
20804    void stopReportingCrashesLocked(ProcessRecord proc) {
20805        if (mAppsNotReportingCrashes == null) {
20806            mAppsNotReportingCrashes = new ArraySet<>();
20807        }
20808        mAppsNotReportingCrashes.add(proc.info.packageName);
20809    }
20810
20811    private final class LocalService extends ActivityManagerInternal {
20812        @Override
20813        public void onWakefulnessChanged(int wakefulness) {
20814            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20815        }
20816
20817        @Override
20818        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20819                String processName, String abiOverride, int uid, Runnable crashHandler) {
20820            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20821                    processName, abiOverride, uid, crashHandler);
20822        }
20823
20824        @Override
20825        public SleepToken acquireSleepToken(String tag) {
20826            Preconditions.checkNotNull(tag);
20827
20828            synchronized (ActivityManagerService.this) {
20829                SleepTokenImpl token = new SleepTokenImpl(tag);
20830                mSleepTokens.add(token);
20831                updateSleepIfNeededLocked();
20832                return token;
20833            }
20834        }
20835
20836        @Override
20837        public ComponentName getHomeActivityForUser(int userId) {
20838            synchronized (ActivityManagerService.this) {
20839                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20840                return homeActivity == null ? null : homeActivity.realActivity;
20841            }
20842        }
20843
20844        @Override
20845        public void onUserRemoved(int userId) {
20846            synchronized (ActivityManagerService.this) {
20847                ActivityManagerService.this.onUserRemovedLocked(userId);
20848            }
20849        }
20850    }
20851
20852    private final class SleepTokenImpl extends SleepToken {
20853        private final String mTag;
20854        private final long mAcquireTime;
20855
20856        public SleepTokenImpl(String tag) {
20857            mTag = tag;
20858            mAcquireTime = SystemClock.uptimeMillis();
20859        }
20860
20861        @Override
20862        public void release() {
20863            synchronized (ActivityManagerService.this) {
20864                if (mSleepTokens.remove(this)) {
20865                    updateSleepIfNeededLocked();
20866                }
20867            }
20868        }
20869
20870        @Override
20871        public String toString() {
20872            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20873        }
20874    }
20875
20876    /**
20877     * An implementation of IAppTask, that allows an app to manage its own tasks via
20878     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20879     * only the process that calls getAppTasks() can call the AppTask methods.
20880     */
20881    class AppTaskImpl extends IAppTask.Stub {
20882        private int mTaskId;
20883        private int mCallingUid;
20884
20885        public AppTaskImpl(int taskId, int callingUid) {
20886            mTaskId = taskId;
20887            mCallingUid = callingUid;
20888        }
20889
20890        private void checkCaller() {
20891            if (mCallingUid != Binder.getCallingUid()) {
20892                throw new SecurityException("Caller " + mCallingUid
20893                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20894            }
20895        }
20896
20897        @Override
20898        public void finishAndRemoveTask() {
20899            checkCaller();
20900
20901            synchronized (ActivityManagerService.this) {
20902                long origId = Binder.clearCallingIdentity();
20903                try {
20904                    // We remove the task from recents to preserve backwards
20905                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20906                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20907                    }
20908                } finally {
20909                    Binder.restoreCallingIdentity(origId);
20910                }
20911            }
20912        }
20913
20914        @Override
20915        public ActivityManager.RecentTaskInfo getTaskInfo() {
20916            checkCaller();
20917
20918            synchronized (ActivityManagerService.this) {
20919                long origId = Binder.clearCallingIdentity();
20920                try {
20921                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20922                    if (tr == null) {
20923                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20924                    }
20925                    return createRecentTaskInfoFromTaskRecord(tr);
20926                } finally {
20927                    Binder.restoreCallingIdentity(origId);
20928                }
20929            }
20930        }
20931
20932        @Override
20933        public void moveToFront() {
20934            checkCaller();
20935            // Will bring task to front if it already has a root activity.
20936            startActivityFromRecentsInner(mTaskId, null);
20937        }
20938
20939        @Override
20940        public int startActivity(IBinder whoThread, String callingPackage,
20941                Intent intent, String resolvedType, Bundle bOptions) {
20942            checkCaller();
20943
20944            int callingUser = UserHandle.getCallingUserId();
20945            TaskRecord tr;
20946            IApplicationThread appThread;
20947            synchronized (ActivityManagerService.this) {
20948                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20949                if (tr == null) {
20950                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20951                }
20952                appThread = ApplicationThreadNative.asInterface(whoThread);
20953                if (appThread == null) {
20954                    throw new IllegalArgumentException("Bad app thread " + appThread);
20955                }
20956            }
20957            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20958                    resolvedType, null, null, null, null, 0, 0, null, null,
20959                    null, bOptions, false, callingUser, null, tr);
20960        }
20961
20962        @Override
20963        public void setExcludeFromRecents(boolean exclude) {
20964            checkCaller();
20965
20966            synchronized (ActivityManagerService.this) {
20967                long origId = Binder.clearCallingIdentity();
20968                try {
20969                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20970                    if (tr == null) {
20971                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20972                    }
20973                    Intent intent = tr.getBaseIntent();
20974                    if (exclude) {
20975                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20976                    } else {
20977                        intent.setFlags(intent.getFlags()
20978                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20979                    }
20980                } finally {
20981                    Binder.restoreCallingIdentity(origId);
20982                }
20983            }
20984        }
20985    }
20986
20987    /**
20988     * Kill processes for the user with id userId and that depend on the package named packageName
20989     */
20990    @Override
20991    public void killPackageDependents(String packageName, int userId) {
20992        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20993        if (packageName == null) {
20994            throw new NullPointerException("Cannot kill the dependents of a package without its name.");
20995        }
20996
20997        long callingId = Binder.clearCallingIdentity();
20998        IPackageManager pm = AppGlobals.getPackageManager();
20999        int pkgUid = -1;
21000        try {
21001            pkgUid = pm.getPackageUid(packageName, userId);
21002        } catch (RemoteException e) {
21003        }
21004        if (pkgUid == -1) {
21005            throw new IllegalArgumentException("Cannot kill dependents of non-existing package " + packageName);
21006        }
21007        try {
21008            synchronized(this) {
21009                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21010                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, false,
21011                        "dep: " + packageName);
21012            }
21013        } finally {
21014            Binder.restoreCallingIdentity(callingId);
21015        }
21016    }
21017}
21018