ActivityManagerService.java revision 4752ab714dc721c2f17a8104cc327e1c711a2640
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.vr.VrManagerInternal;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
63
64import android.Manifest;
65import android.app.Activity;
66import android.app.ActivityManager;
67import android.app.ActivityManager.RunningTaskInfo;
68import android.app.ActivityManager.StackId;
69import android.app.ActivityManager.StackInfo;
70import android.app.ActivityManager.TaskThumbnailInfo;
71import android.app.ActivityManagerInternal;
72import android.app.ActivityManagerInternal.SleepToken;
73import android.app.ActivityManagerNative;
74import android.app.ActivityOptions;
75import android.app.ActivityThread;
76import android.app.AlertDialog;
77import android.app.AppGlobals;
78import android.app.AppOpsManager;
79import android.app.ApplicationErrorReport;
80import android.app.ApplicationThreadNative;
81import android.app.BroadcastOptions;
82import android.app.Dialog;
83import android.app.IActivityContainer;
84import android.app.IActivityContainerCallback;
85import android.app.IActivityController;
86import android.app.IAppTask;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.ITaskStackListener;
94import android.app.IUiAutomationConnection;
95import android.app.IUidObserver;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.ProfilerInfo;
102import android.app.admin.DevicePolicyManager;
103import android.app.assist.AssistContent;
104import android.app.assist.AssistStructure;
105import android.app.backup.IBackupManager;
106import android.app.usage.UsageEvents;
107import android.app.usage.UsageStatsManagerInternal;
108import android.appwidget.AppWidgetManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PackageManagerInternal;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.PathPermission;
136import android.content.pm.PermissionInfo;
137import android.content.pm.ProviderInfo;
138import android.content.pm.ResolveInfo;
139import android.content.pm.ServiceInfo;
140import android.content.pm.UserInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.content.res.Resources;
144import android.graphics.Bitmap;
145import android.graphics.Point;
146import android.graphics.Rect;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.BatteryStats;
151import android.os.Binder;
152import android.os.Build;
153import android.os.Bundle;
154import android.os.Debug;
155import android.os.DropBoxManager;
156import android.os.Environment;
157import android.os.FactoryTest;
158import android.os.FileObserver;
159import android.os.FileUtils;
160import android.os.Handler;
161import android.os.IBinder;
162import android.os.IPermissionController;
163import android.os.IProcessInfoService;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.PersistableBundle;
169import android.os.PowerManager;
170import android.os.PowerManagerInternal;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.ResultReceiver;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.Trace;
180import android.os.TransactionTooLargeException;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.os.WorkSource;
185import android.os.storage.IMountService;
186import android.os.storage.MountServiceInternal;
187import android.os.storage.StorageManager;
188import android.provider.Settings;
189import android.service.voice.IVoiceInteractionSession;
190import android.service.voice.VoiceInteractionSession;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.ArrayMap;
194import android.util.ArraySet;
195import android.util.AtomicFile;
196import android.util.DebugUtils;
197import android.util.EventLog;
198import android.util.LocaleList;
199import android.util.Log;
200import android.util.Pair;
201import android.util.PrintWriterPrinter;
202import android.util.Slog;
203import android.util.SparseArray;
204import android.util.SparseBooleanArray;
205import android.util.TimeUtils;
206import android.util.Xml;
207import android.view.Display;
208import android.view.Gravity;
209import android.view.LayoutInflater;
210import android.view.View;
211import android.view.WindowManager;
212
213import java.io.BufferedInputStream;
214import java.io.BufferedOutputStream;
215import java.io.DataInputStream;
216import java.io.DataOutputStream;
217import java.io.File;
218import java.io.FileDescriptor;
219import java.io.FileInputStream;
220import java.io.FileNotFoundException;
221import java.io.FileOutputStream;
222import java.io.IOException;
223import java.io.InputStreamReader;
224import java.io.PrintWriter;
225import java.io.StringWriter;
226import java.lang.ref.WeakReference;
227import java.nio.charset.StandardCharsets;
228import java.util.ArrayList;
229import java.util.Arrays;
230import java.util.Collections;
231import java.util.Comparator;
232import java.util.HashMap;
233import java.util.HashSet;
234import java.util.Iterator;
235import java.util.List;
236import java.util.Locale;
237import java.util.Map;
238import java.util.Set;
239import java.util.concurrent.atomic.AtomicBoolean;
240import java.util.concurrent.atomic.AtomicLong;
241
242import dalvik.system.VMRuntime;
243
244import libcore.io.IoUtils;
245import libcore.util.EmptyArray;
246
247import static android.Manifest.permission.INTERACT_ACROSS_USERS;
248import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
249import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
250import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
251import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
252import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
253import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
254import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
255import static android.app.ActivityManager.StackId.HOME_STACK_ID;
256import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
257import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
258import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
259import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
260import static android.content.pm.PackageManager.GET_PROVIDERS;
261import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
262import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
263import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
264import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
265import static android.content.pm.PackageManager.PERMISSION_GRANTED;
266import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
267import static android.provider.Settings.Global.DEBUG_APP;
268import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
269import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
270import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
271import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
272import static com.android.internal.util.XmlUtils.readBooleanAttribute;
273import static com.android.internal.util.XmlUtils.readIntAttribute;
274import static com.android.internal.util.XmlUtils.readLongAttribute;
275import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
276import static com.android.internal.util.XmlUtils.writeIntAttribute;
277import static com.android.internal.util.XmlUtils.writeLongAttribute;
278import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
334import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
335import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
336import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
337import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
338import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
339import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
340import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
341import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
342import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
343import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
344import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
345import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
346import static org.xmlpull.v1.XmlPullParser.START_TAG;
347
348public final class ActivityManagerService extends ActivityManagerNative
349        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
350
351    // File that stores last updated system version and called preboot receivers
352    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
353
354    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
355    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
356    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
357    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
358    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
359    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
360    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
361    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
362    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
363    private static final String TAG_LRU = TAG + POSTFIX_LRU;
364    private static final String TAG_MU = TAG + POSTFIX_MU;
365    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
366    private static final String TAG_POWER = TAG + POSTFIX_POWER;
367    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
368    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
369    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
370    private static final String TAG_PSS = TAG + POSTFIX_PSS;
371    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
372    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
373    private static final String TAG_STACK = TAG + POSTFIX_STACK;
374    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
375    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
376    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
377    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
378    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
379
380    /** Control over CPU and battery monitoring */
381    // write battery stats every 30 minutes.
382    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
383    static final boolean MONITOR_CPU_USAGE = true;
384    // don't sample cpu less than every 5 seconds.
385    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
386    // wait possibly forever for next cpu sample.
387    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
388    static final boolean MONITOR_THREAD_CPU_USAGE = false;
389
390    // The flags that are set for all calls we make to the package manager.
391    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
392
393    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
394
395    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
396
397    // Amount of time after a call to stopAppSwitches() during which we will
398    // prevent further untrusted switches from happening.
399    static final long APP_SWITCH_DELAY_TIME = 5*1000;
400
401    // How long we wait for a launched process to attach to the activity manager
402    // before we decide it's never going to come up for real.
403    static final int PROC_START_TIMEOUT = 10*1000;
404    // How long we wait for an attached process to publish its content providers
405    // before we decide it must be hung.
406    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
407
408    // How long we will retain processes hosting content providers in the "last activity"
409    // state before allowing them to drop down to the regular cached LRU list.  This is
410    // to avoid thrashing of provider processes under low memory situations.
411    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
412
413    // How long we wait for a launched process to attach to the activity manager
414    // before we decide it's never going to come up for real, when the process was
415    // started with a wrapper for instrumentation (such as Valgrind) because it
416    // could take much longer than usual.
417    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
418
419    // How long to wait after going idle before forcing apps to GC.
420    static final int GC_TIMEOUT = 5*1000;
421
422    // The minimum amount of time between successive GC requests for a process.
423    static final int GC_MIN_INTERVAL = 60*1000;
424
425    // The minimum amount of time between successive PSS requests for a process.
426    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
427
428    // The minimum amount of time between successive PSS requests for a process
429    // when the request is due to the memory state being lowered.
430    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
431
432    // The rate at which we check for apps using excessive power -- 15 mins.
433    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
434
435    // The minimum sample duration we will allow before deciding we have
436    // enough data on wake locks to start killing things.
437    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
438
439    // The minimum sample duration we will allow before deciding we have
440    // enough data on CPU usage to start killing things.
441    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
442
443    // How long we allow a receiver to run before giving up on it.
444    static final int BROADCAST_FG_TIMEOUT = 10*1000;
445    static final int BROADCAST_BG_TIMEOUT = 60*1000;
446
447    // How long we wait until we timeout on key dispatching.
448    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
449
450    // How long we wait until we timeout on key dispatching during instrumentation.
451    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
452
453    // This is the amount of time an app needs to be running a foreground service before
454    // we will consider it to be doing interaction for usage stats.
455    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
456
457    // Maximum amount of time we will allow to elapse before re-reporting usage stats
458    // interaction with foreground processes.
459    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
460
461    // This is the amount of time we allow an app to settle after it goes into the background,
462    // before we start restricting what it can do.
463    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
464
465    // How long to wait in getAssistContextExtras for the activity and foreground services
466    // to respond with the result.
467    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
468
469    // How long top wait when going through the modern assist (which doesn't need to block
470    // on getting this result before starting to launch its UI).
471    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
472
473    // Maximum number of persisted Uri grants a package is allowed
474    static final int MAX_PERSISTED_URI_GRANTS = 128;
475
476    static final int MY_PID = Process.myPid();
477
478    static final String[] EMPTY_STRING_ARRAY = new String[0];
479
480    // How many bytes to write into the dropbox log before truncating
481    static final int DROPBOX_MAX_SIZE = 256 * 1024;
482
483    // Access modes for handleIncomingUser.
484    static final int ALLOW_NON_FULL = 0;
485    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
486    static final int ALLOW_FULL_ONLY = 2;
487
488    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
489
490    // Delay in notifying task stack change listeners (in millis)
491    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
492
493    // Necessary ApplicationInfo flags to mark an app as persistent
494    private static final int PERSISTENT_MASK =
495            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
496
497
498    // Delay to disable app launch boost
499    static final int APP_BOOST_MESSAGE_DELAY = 3000;
500    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
501    static final int APP_BOOST_TIMEOUT = 2500;
502
503    // Used to indicate that a task is removed it should also be removed from recents.
504    private static final boolean REMOVE_FROM_RECENTS = true;
505    // Used to indicate that an app transition should be animated.
506    static final boolean ANIMATE = true;
507
508    // Determines whether to take full screen screenshots
509    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
510
511    private static native int nativeMigrateToBoost();
512    private static native int nativeMigrateFromBoost();
513    private boolean mIsBoosted = false;
514    private long mBoostStartTime = 0;
515
516    /** All system services */
517    SystemServiceManager mSystemServiceManager;
518
519    private Installer mInstaller;
520
521    /** Run all ActivityStacks through this */
522    final ActivityStackSupervisor mStackSupervisor;
523
524    final ActivityStarter mActivityStarter;
525
526    /** Task stack change listeners. */
527    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
528            new RemoteCallbackList<ITaskStackListener>();
529
530    public IntentFirewall mIntentFirewall;
531
532    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
533    // default actuion automatically.  Important for devices without direct input
534    // devices.
535    private boolean mShowDialogs = true;
536
537    BroadcastQueue mFgBroadcastQueue;
538    BroadcastQueue mBgBroadcastQueue;
539    // Convenient for easy iteration over the queues. Foreground is first
540    // so that dispatch of foreground broadcasts gets precedence.
541    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
542
543    BroadcastQueue broadcastQueueForIntent(Intent intent) {
544        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
545        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
546                "Broadcast intent " + intent + " on "
547                + (isFg ? "foreground" : "background") + " queue");
548        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
549    }
550
551    /**
552     * Activity we have told the window manager to have key focus.
553     */
554    ActivityRecord mFocusedActivity = null;
555
556    /**
557     * User id of the last activity mFocusedActivity was set to.
558     */
559    private int mLastFocusedUserId;
560
561    /**
562     * If non-null, we are tracking the time the user spends in the currently focused app.
563     */
564    private AppTimeTracker mCurAppTimeTracker;
565
566    /**
567     * List of intents that were used to start the most recent tasks.
568     */
569    final RecentTasks mRecentTasks;
570
571    /**
572     * For addAppTask: cached of the last activity component that was added.
573     */
574    ComponentName mLastAddedTaskComponent;
575
576    /**
577     * For addAppTask: cached of the last activity uid that was added.
578     */
579    int mLastAddedTaskUid;
580
581    /**
582     * For addAppTask: cached of the last ActivityInfo that was added.
583     */
584    ActivityInfo mLastAddedTaskActivity;
585
586    /**
587     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
588     */
589    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
590
591    /**
592     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
593     */
594    String mDeviceOwnerName;
595
596    final UserController mUserController;
597
598    public class PendingAssistExtras extends Binder implements Runnable {
599        public final ActivityRecord activity;
600        public final Bundle extras;
601        public final Intent intent;
602        public final String hint;
603        public final IResultReceiver receiver;
604        public final int userHandle;
605        public boolean haveResult = false;
606        public Bundle result = null;
607        public AssistStructure structure = null;
608        public AssistContent content = null;
609        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
610                String _hint, IResultReceiver _receiver, int _userHandle) {
611            activity = _activity;
612            extras = _extras;
613            intent = _intent;
614            hint = _hint;
615            receiver = _receiver;
616            userHandle = _userHandle;
617        }
618        @Override
619        public void run() {
620            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
621            synchronized (this) {
622                haveResult = true;
623                notifyAll();
624            }
625            pendingAssistExtrasTimedOut(this);
626        }
627    }
628
629    final ArrayList<PendingAssistExtras> mPendingAssistExtras
630            = new ArrayList<PendingAssistExtras>();
631
632    /**
633     * Process management.
634     */
635    final ProcessList mProcessList = new ProcessList();
636
637    /**
638     * All of the applications we currently have running organized by name.
639     * The keys are strings of the application package name (as
640     * returned by the package manager), and the keys are ApplicationRecord
641     * objects.
642     */
643    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
644
645    /**
646     * Tracking long-term execution of processes to look for abuse and other
647     * bad app behavior.
648     */
649    final ProcessStatsService mProcessStats;
650
651    /**
652     * The currently running isolated processes.
653     */
654    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
655
656    /**
657     * Counter for assigning isolated process uids, to avoid frequently reusing the
658     * same ones.
659     */
660    int mNextIsolatedProcessUid = 0;
661
662    /**
663     * The currently running heavy-weight process, if any.
664     */
665    ProcessRecord mHeavyWeightProcess = null;
666
667    /**
668     * The last time that various processes have crashed.
669     */
670    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
671
672    /**
673     * Information about a process that is currently marked as bad.
674     */
675    static final class BadProcessInfo {
676        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
677            this.time = time;
678            this.shortMsg = shortMsg;
679            this.longMsg = longMsg;
680            this.stack = stack;
681        }
682
683        final long time;
684        final String shortMsg;
685        final String longMsg;
686        final String stack;
687    }
688
689    /**
690     * Set of applications that we consider to be bad, and will reject
691     * incoming broadcasts from (which the user has no control over).
692     * Processes are added to this set when they have crashed twice within
693     * a minimum amount of time; they are removed from it when they are
694     * later restarted (hopefully due to some user action).  The value is the
695     * time it was added to the list.
696     */
697    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
698
699    /**
700     * All of the processes we currently have running organized by pid.
701     * The keys are the pid running the application.
702     *
703     * <p>NOTE: This object is protected by its own lock, NOT the global
704     * activity manager lock!
705     */
706    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
707
708    /**
709     * All of the processes that have been forced to be foreground.  The key
710     * is the pid of the caller who requested it (we hold a death
711     * link on it).
712     */
713    abstract class ForegroundToken implements IBinder.DeathRecipient {
714        int pid;
715        IBinder token;
716    }
717    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
718
719    /**
720     * List of records for processes that someone had tried to start before the
721     * system was ready.  We don't start them at that point, but ensure they
722     * are started by the time booting is complete.
723     */
724    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
725
726    /**
727     * List of persistent applications that are in the process
728     * of being started.
729     */
730    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
731
732    /**
733     * Processes that are being forcibly torn down.
734     */
735    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
736
737    /**
738     * List of running applications, sorted by recent usage.
739     * The first entry in the list is the least recently used.
740     */
741    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
742
743    /**
744     * Where in mLruProcesses that the processes hosting activities start.
745     */
746    int mLruProcessActivityStart = 0;
747
748    /**
749     * Where in mLruProcesses that the processes hosting services start.
750     * This is after (lower index) than mLruProcessesActivityStart.
751     */
752    int mLruProcessServiceStart = 0;
753
754    /**
755     * List of processes that should gc as soon as things are idle.
756     */
757    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
758
759    /**
760     * Processes we want to collect PSS data from.
761     */
762    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
763
764    private boolean mBinderTransactionTrackingEnabled = false;
765
766    /**
767     * Last time we requested PSS data of all processes.
768     */
769    long mLastFullPssTime = SystemClock.uptimeMillis();
770
771    /**
772     * If set, the next time we collect PSS data we should do a full collection
773     * with data from native processes and the kernel.
774     */
775    boolean mFullPssPending = false;
776
777    /**
778     * This is the process holding what we currently consider to be
779     * the "home" activity.
780     */
781    ProcessRecord mHomeProcess;
782
783    /**
784     * This is the process holding the activity the user last visited that
785     * is in a different process from the one they are currently in.
786     */
787    ProcessRecord mPreviousProcess;
788
789    /**
790     * The time at which the previous process was last visible.
791     */
792    long mPreviousProcessVisibleTime;
793
794    /**
795     * Track all uids that have actively running processes.
796     */
797    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
798
799    /**
800     * This is for verifying the UID report flow.
801     */
802    static final boolean VALIDATE_UID_STATES = true;
803    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
804
805    /**
806     * Packages that the user has asked to have run in screen size
807     * compatibility mode instead of filling the screen.
808     */
809    final CompatModePackages mCompatModePackages;
810
811    /**
812     * Set of IntentSenderRecord objects that are currently active.
813     */
814    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
815            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
816
817    /**
818     * Fingerprints (hashCode()) of stack traces that we've
819     * already logged DropBox entries for.  Guarded by itself.  If
820     * something (rogue user app) forces this over
821     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
822     */
823    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
824    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
825
826    /**
827     * Strict Mode background batched logging state.
828     *
829     * The string buffer is guarded by itself, and its lock is also
830     * used to determine if another batched write is already
831     * in-flight.
832     */
833    private final StringBuilder mStrictModeBuffer = new StringBuilder();
834
835    /**
836     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
837     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
838     */
839    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
840
841    /**
842     * Resolver for broadcast intents to registered receivers.
843     * Holds BroadcastFilter (subclass of IntentFilter).
844     */
845    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
846            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
847        @Override
848        protected boolean allowFilterResult(
849                BroadcastFilter filter, List<BroadcastFilter> dest) {
850            IBinder target = filter.receiverList.receiver.asBinder();
851            for (int i = dest.size() - 1; i >= 0; i--) {
852                if (dest.get(i).receiverList.receiver.asBinder() == target) {
853                    return false;
854                }
855            }
856            return true;
857        }
858
859        @Override
860        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
861            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
862                    || userId == filter.owningUserId) {
863                return super.newResult(filter, match, userId);
864            }
865            return null;
866        }
867
868        @Override
869        protected BroadcastFilter[] newArray(int size) {
870            return new BroadcastFilter[size];
871        }
872
873        @Override
874        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
875            return packageName.equals(filter.packageName);
876        }
877    };
878
879    /**
880     * State of all active sticky broadcasts per user.  Keys are the action of the
881     * sticky Intent, values are an ArrayList of all broadcasted intents with
882     * that action (which should usually be one).  The SparseArray is keyed
883     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
884     * for stickies that are sent to all users.
885     */
886    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
887            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
888
889    final ActiveServices mServices;
890
891    final static class Association {
892        final int mSourceUid;
893        final String mSourceProcess;
894        final int mTargetUid;
895        final ComponentName mTargetComponent;
896        final String mTargetProcess;
897
898        int mCount;
899        long mTime;
900
901        int mNesting;
902        long mStartTime;
903
904        Association(int sourceUid, String sourceProcess, int targetUid,
905                ComponentName targetComponent, String targetProcess) {
906            mSourceUid = sourceUid;
907            mSourceProcess = sourceProcess;
908            mTargetUid = targetUid;
909            mTargetComponent = targetComponent;
910            mTargetProcess = targetProcess;
911        }
912    }
913
914    /**
915     * When service association tracking is enabled, this is all of the associations we
916     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
917     * -> association data.
918     */
919    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
920            mAssociations = new SparseArray<>();
921    boolean mTrackingAssociations;
922
923    /**
924     * Backup/restore process management
925     */
926    String mBackupAppName = null;
927    BackupRecord mBackupTarget = null;
928
929    final ProviderMap mProviderMap;
930
931    /**
932     * List of content providers who have clients waiting for them.  The
933     * application is currently being launched and the provider will be
934     * removed from this list once it is published.
935     */
936    final ArrayList<ContentProviderRecord> mLaunchingProviders
937            = new ArrayList<ContentProviderRecord>();
938
939    /**
940     * File storing persisted {@link #mGrantedUriPermissions}.
941     */
942    private final AtomicFile mGrantFile;
943
944    /** XML constants used in {@link #mGrantFile} */
945    private static final String TAG_URI_GRANTS = "uri-grants";
946    private static final String TAG_URI_GRANT = "uri-grant";
947    private static final String ATTR_USER_HANDLE = "userHandle";
948    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
949    private static final String ATTR_TARGET_USER_ID = "targetUserId";
950    private static final String ATTR_SOURCE_PKG = "sourcePkg";
951    private static final String ATTR_TARGET_PKG = "targetPkg";
952    private static final String ATTR_URI = "uri";
953    private static final String ATTR_MODE_FLAGS = "modeFlags";
954    private static final String ATTR_CREATED_TIME = "createdTime";
955    private static final String ATTR_PREFIX = "prefix";
956
957    /**
958     * Global set of specific {@link Uri} permissions that have been granted.
959     * This optimized lookup structure maps from {@link UriPermission#targetUid}
960     * to {@link UriPermission#uri} to {@link UriPermission}.
961     */
962    @GuardedBy("this")
963    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
964            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
965
966    public static class GrantUri {
967        public final int sourceUserId;
968        public final Uri uri;
969        public boolean prefix;
970
971        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
972            this.sourceUserId = sourceUserId;
973            this.uri = uri;
974            this.prefix = prefix;
975        }
976
977        @Override
978        public int hashCode() {
979            int hashCode = 1;
980            hashCode = 31 * hashCode + sourceUserId;
981            hashCode = 31 * hashCode + uri.hashCode();
982            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
983            return hashCode;
984        }
985
986        @Override
987        public boolean equals(Object o) {
988            if (o instanceof GrantUri) {
989                GrantUri other = (GrantUri) o;
990                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
991                        && prefix == other.prefix;
992            }
993            return false;
994        }
995
996        @Override
997        public String toString() {
998            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
999            if (prefix) result += " [prefix]";
1000            return result;
1001        }
1002
1003        public String toSafeString() {
1004            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1005            if (prefix) result += " [prefix]";
1006            return result;
1007        }
1008
1009        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1010            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1011                    ContentProvider.getUriWithoutUserId(uri), false);
1012        }
1013    }
1014
1015    CoreSettingsObserver mCoreSettingsObserver;
1016
1017    /**
1018     * Thread-local storage used to carry caller permissions over through
1019     * indirect content-provider access.
1020     */
1021    private class Identity {
1022        public final IBinder token;
1023        public final int pid;
1024        public final int uid;
1025
1026        Identity(IBinder _token, int _pid, int _uid) {
1027            token = _token;
1028            pid = _pid;
1029            uid = _uid;
1030        }
1031    }
1032
1033    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1034
1035    /**
1036     * All information we have collected about the runtime performance of
1037     * any user id that can impact battery performance.
1038     */
1039    final BatteryStatsService mBatteryStatsService;
1040
1041    /**
1042     * Information about component usage
1043     */
1044    UsageStatsManagerInternal mUsageStatsService;
1045
1046    /**
1047     * Access to DeviceIdleController service.
1048     */
1049    DeviceIdleController.LocalService mLocalDeviceIdleController;
1050
1051    /**
1052     * Information about and control over application operations
1053     */
1054    final AppOpsService mAppOpsService;
1055
1056    /**
1057     * Current configuration information.  HistoryRecord objects are given
1058     * a reference to this object to indicate which configuration they are
1059     * currently running in, so this object must be kept immutable.
1060     */
1061    Configuration mConfiguration = new Configuration();
1062
1063    /**
1064     * Current sequencing integer of the configuration, for skipping old
1065     * configurations.
1066     */
1067    int mConfigurationSeq = 0;
1068
1069    boolean mSuppressResizeConfigChanges = false;
1070
1071    /**
1072     * Hardware-reported OpenGLES version.
1073     */
1074    final int GL_ES_VERSION;
1075
1076    /**
1077     * List of initialization arguments to pass to all processes when binding applications to them.
1078     * For example, references to the commonly used services.
1079     */
1080    HashMap<String, IBinder> mAppBindArgs;
1081
1082    /**
1083     * Temporary to avoid allocations.  Protected by main lock.
1084     */
1085    final StringBuilder mStringBuilder = new StringBuilder(256);
1086
1087    /**
1088     * Used to control how we initialize the service.
1089     */
1090    ComponentName mTopComponent;
1091    String mTopAction = Intent.ACTION_MAIN;
1092    String mTopData;
1093    boolean mProcessesReady = false;
1094    boolean mSystemReady = false;
1095    boolean mBooting = false;
1096    boolean mCallFinishBooting = false;
1097    boolean mBootAnimationComplete = false;
1098    boolean mWaitingUpdate = false;
1099    boolean mDidUpdate = false;
1100    boolean mOnBattery = false;
1101    boolean mLaunchWarningShown = false;
1102
1103    Context mContext;
1104
1105    int mFactoryTest;
1106
1107    boolean mCheckedForSetup;
1108
1109    /**
1110     * The time at which we will allow normal application switches again,
1111     * after a call to {@link #stopAppSwitches()}.
1112     */
1113    long mAppSwitchesAllowedTime;
1114
1115    /**
1116     * This is set to true after the first switch after mAppSwitchesAllowedTime
1117     * is set; any switches after that will clear the time.
1118     */
1119    boolean mDidAppSwitch;
1120
1121    /**
1122     * Last time (in realtime) at which we checked for power usage.
1123     */
1124    long mLastPowerCheckRealtime;
1125
1126    /**
1127     * Last time (in uptime) at which we checked for power usage.
1128     */
1129    long mLastPowerCheckUptime;
1130
1131    /**
1132     * Set while we are wanting to sleep, to prevent any
1133     * activities from being started/resumed.
1134     */
1135    private boolean mSleeping = false;
1136
1137    /**
1138     * The process state used for processes that are running the top activities.
1139     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1140     */
1141    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1142
1143    /**
1144     * Set while we are running a voice interaction.  This overrides
1145     * sleeping while it is active.
1146     */
1147    private IVoiceInteractionSession mRunningVoice;
1148
1149    /**
1150     * For some direct access we need to power manager.
1151     */
1152    PowerManagerInternal mLocalPowerManager;
1153
1154    /**
1155     * We want to hold a wake lock while running a voice interaction session, since
1156     * this may happen with the screen off and we need to keep the CPU running to
1157     * be able to continue to interact with the user.
1158     */
1159    PowerManager.WakeLock mVoiceWakeLock;
1160
1161    /**
1162     * State of external calls telling us if the device is awake or asleep.
1163     */
1164    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1165
1166    /**
1167     * A list of tokens that cause the top activity to be put to sleep.
1168     * They are used by components that may hide and block interaction with underlying
1169     * activities.
1170     */
1171    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1172
1173    static final int LOCK_SCREEN_HIDDEN = 0;
1174    static final int LOCK_SCREEN_LEAVING = 1;
1175    static final int LOCK_SCREEN_SHOWN = 2;
1176    /**
1177     * State of external call telling us if the lock screen is shown.
1178     */
1179    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1180
1181    /**
1182     * Set if we are shutting down the system, similar to sleeping.
1183     */
1184    boolean mShuttingDown = false;
1185
1186    /**
1187     * Current sequence id for oom_adj computation traversal.
1188     */
1189    int mAdjSeq = 0;
1190
1191    /**
1192     * Current sequence id for process LRU updating.
1193     */
1194    int mLruSeq = 0;
1195
1196    /**
1197     * Keep track of the non-cached/empty process we last found, to help
1198     * determine how to distribute cached/empty processes next time.
1199     */
1200    int mNumNonCachedProcs = 0;
1201
1202    /**
1203     * Keep track of the number of cached hidden procs, to balance oom adj
1204     * distribution between those and empty procs.
1205     */
1206    int mNumCachedHiddenProcs = 0;
1207
1208    /**
1209     * Keep track of the number of service processes we last found, to
1210     * determine on the next iteration which should be B services.
1211     */
1212    int mNumServiceProcs = 0;
1213    int mNewNumAServiceProcs = 0;
1214    int mNewNumServiceProcs = 0;
1215
1216    /**
1217     * Allow the current computed overall memory level of the system to go down?
1218     * This is set to false when we are killing processes for reasons other than
1219     * memory management, so that the now smaller process list will not be taken as
1220     * an indication that memory is tighter.
1221     */
1222    boolean mAllowLowerMemLevel = false;
1223
1224    /**
1225     * The last computed memory level, for holding when we are in a state that
1226     * processes are going away for other reasons.
1227     */
1228    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1229
1230    /**
1231     * The last total number of process we have, to determine if changes actually look
1232     * like a shrinking number of process due to lower RAM.
1233     */
1234    int mLastNumProcesses;
1235
1236    /**
1237     * The uptime of the last time we performed idle maintenance.
1238     */
1239    long mLastIdleTime = SystemClock.uptimeMillis();
1240
1241    /**
1242     * Total time spent with RAM that has been added in the past since the last idle time.
1243     */
1244    long mLowRamTimeSinceLastIdle = 0;
1245
1246    /**
1247     * If RAM is currently low, when that horrible situation started.
1248     */
1249    long mLowRamStartTime = 0;
1250
1251    /**
1252     * For reporting to battery stats the current top application.
1253     */
1254    private String mCurResumedPackage = null;
1255    private int mCurResumedUid = -1;
1256
1257    /**
1258     * For reporting to battery stats the apps currently running foreground
1259     * service.  The ProcessMap is package/uid tuples; each of these contain
1260     * an array of the currently foreground processes.
1261     */
1262    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1263            = new ProcessMap<ArrayList<ProcessRecord>>();
1264
1265    /**
1266     * This is set if we had to do a delayed dexopt of an app before launching
1267     * it, to increase the ANR timeouts in that case.
1268     */
1269    boolean mDidDexOpt;
1270
1271    /**
1272     * Set if the systemServer made a call to enterSafeMode.
1273     */
1274    boolean mSafeMode;
1275
1276    /**
1277     * If true, we are running under a test environment so will sample PSS from processes
1278     * much more rapidly to try to collect better data when the tests are rapidly
1279     * running through apps.
1280     */
1281    boolean mTestPssMode = false;
1282
1283    String mDebugApp = null;
1284    boolean mWaitForDebugger = false;
1285    boolean mDebugTransient = false;
1286    String mOrigDebugApp = null;
1287    boolean mOrigWaitForDebugger = false;
1288    boolean mAlwaysFinishActivities = false;
1289    boolean mForceResizableActivities;
1290    boolean mSupportsFreeformWindowManagement;
1291    boolean mSupportsPictureInPicture;
1292    Rect mDefaultPinnedStackBounds;
1293    IActivityController mController = null;
1294    String mProfileApp = null;
1295    ProcessRecord mProfileProc = null;
1296    String mProfileFile;
1297    ParcelFileDescriptor mProfileFd;
1298    int mSamplingInterval = 0;
1299    boolean mAutoStopProfiler = false;
1300    int mProfileType = 0;
1301    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1302    String mMemWatchDumpProcName;
1303    String mMemWatchDumpFile;
1304    int mMemWatchDumpPid;
1305    int mMemWatchDumpUid;
1306    String mTrackAllocationApp = null;
1307
1308    final long[] mTmpLong = new long[2];
1309
1310    static final class ProcessChangeItem {
1311        static final int CHANGE_ACTIVITIES = 1<<0;
1312        static final int CHANGE_PROCESS_STATE = 1<<1;
1313        int changes;
1314        int uid;
1315        int pid;
1316        int processState;
1317        boolean foregroundActivities;
1318    }
1319
1320    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1321    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1322
1323    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1324    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1325
1326    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1327    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1328
1329    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1330    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1331
1332    ArraySet<String> mAppsNotReportingCrashes;
1333
1334    /**
1335     * Runtime CPU use collection thread.  This object's lock is used to
1336     * perform synchronization with the thread (notifying it to run).
1337     */
1338    final Thread mProcessCpuThread;
1339
1340    /**
1341     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1342     * Must acquire this object's lock when accessing it.
1343     * NOTE: this lock will be held while doing long operations (trawling
1344     * through all processes in /proc), so it should never be acquired by
1345     * any critical paths such as when holding the main activity manager lock.
1346     */
1347    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1348            MONITOR_THREAD_CPU_USAGE);
1349    final AtomicLong mLastCpuTime = new AtomicLong(0);
1350    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1351
1352    long mLastWriteTime = 0;
1353
1354    /**
1355     * Used to retain an update lock when the foreground activity is in
1356     * immersive mode.
1357     */
1358    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1359
1360    /**
1361     * Set to true after the system has finished booting.
1362     */
1363    boolean mBooted = false;
1364
1365    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1366    int mProcessLimitOverride = -1;
1367
1368    WindowManagerService mWindowManager;
1369
1370    final ActivityThread mSystemThread;
1371
1372    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1373        final ProcessRecord mApp;
1374        final int mPid;
1375        final IApplicationThread mAppThread;
1376
1377        AppDeathRecipient(ProcessRecord app, int pid,
1378                IApplicationThread thread) {
1379            if (DEBUG_ALL) Slog.v(
1380                TAG, "New death recipient " + this
1381                + " for thread " + thread.asBinder());
1382            mApp = app;
1383            mPid = pid;
1384            mAppThread = thread;
1385        }
1386
1387        @Override
1388        public void binderDied() {
1389            if (DEBUG_ALL) Slog.v(
1390                TAG, "Death received in " + this
1391                + " for thread " + mAppThread.asBinder());
1392            synchronized(ActivityManagerService.this) {
1393                appDiedLocked(mApp, mPid, mAppThread, true);
1394            }
1395        }
1396    }
1397
1398    static final int SHOW_ERROR_UI_MSG = 1;
1399    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1400    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1401    static final int UPDATE_CONFIGURATION_MSG = 4;
1402    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1403    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1404    static final int SERVICE_TIMEOUT_MSG = 12;
1405    static final int UPDATE_TIME_ZONE = 13;
1406    static final int SHOW_UID_ERROR_UI_MSG = 14;
1407    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1408    static final int PROC_START_TIMEOUT_MSG = 20;
1409    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1410    static final int KILL_APPLICATION_MSG = 22;
1411    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1412    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1413    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1414    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1415    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1416    static final int CLEAR_DNS_CACHE_MSG = 28;
1417    static final int UPDATE_HTTP_PROXY_MSG = 29;
1418    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1419    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1420    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1421    static final int REPORT_MEM_USAGE_MSG = 33;
1422    static final int REPORT_USER_SWITCH_MSG = 34;
1423    static final int CONTINUE_USER_SWITCH_MSG = 35;
1424    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1425    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1426    static final int PERSIST_URI_GRANTS_MSG = 38;
1427    static final int REQUEST_ALL_PSS_MSG = 39;
1428    static final int START_PROFILES_MSG = 40;
1429    static final int UPDATE_TIME = 41;
1430    static final int SYSTEM_USER_START_MSG = 42;
1431    static final int SYSTEM_USER_CURRENT_MSG = 43;
1432    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1433    static final int FINISH_BOOTING_MSG = 45;
1434    static final int START_USER_SWITCH_UI_MSG = 46;
1435    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1436    static final int DISMISS_DIALOG_UI_MSG = 48;
1437    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1438    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1439    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1440    static final int DELETE_DUMPHEAP_MSG = 52;
1441    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1442    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1443    static final int REPORT_TIME_TRACKER_MSG = 55;
1444    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1445    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1446    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1447    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1448    static final int IDLE_UIDS_MSG = 60;
1449    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1450    static final int LOG_STACK_STATE = 62;
1451    static final int VR_MODE_CHANGE_MSG = 63;
1452    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1453
1454    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1455    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1456    static final int FIRST_COMPAT_MODE_MSG = 300;
1457    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1458
1459    CompatModeDialog mCompatModeDialog;
1460    long mLastMemUsageReportTime = 0;
1461
1462    /**
1463     * Flag whether the current user is a "monkey", i.e. whether
1464     * the UI is driven by a UI automation tool.
1465     */
1466    private boolean mUserIsMonkey;
1467
1468    /** Flag whether the device has a Recents UI */
1469    boolean mHasRecents;
1470
1471    /** The dimensions of the thumbnails in the Recents UI. */
1472    int mThumbnailWidth;
1473    int mThumbnailHeight;
1474
1475    final ServiceThread mHandlerThread;
1476    final MainHandler mHandler;
1477    final UiHandler mUiHandler;
1478
1479    PackageManagerInternal mPackageManagerInt;
1480
1481    final class UiHandler extends Handler {
1482        public UiHandler() {
1483            super(com.android.server.UiThread.get().getLooper(), null, true);
1484        }
1485
1486        @Override
1487        public void handleMessage(Message msg) {
1488            switch (msg.what) {
1489            case SHOW_ERROR_UI_MSG: {
1490                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1491                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1492                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1493                synchronized (ActivityManagerService.this) {
1494                    ProcessRecord proc = (ProcessRecord)data.get("app");
1495                    AppErrorResult res = (AppErrorResult) data.get("result");
1496                    if (proc != null && proc.crashDialog != null) {
1497                        Slog.e(TAG, "App already has crash dialog: " + proc);
1498                        if (res != null) {
1499                            res.set(0);
1500                        }
1501                        return;
1502                    }
1503                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1504                            >= Process.FIRST_APPLICATION_UID
1505                            && proc.pid != MY_PID);
1506                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1507                        isBackground &= (proc.userId != userId);
1508                    }
1509                    if (isBackground && !showBackground) {
1510                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1511                        if (res != null) {
1512                            res.set(0);
1513                        }
1514                        return;
1515                    }
1516                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1517                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1518                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1519                        Dialog d = new AppErrorDialog(mContext,
1520                                ActivityManagerService.this, res, proc);
1521                        d.show();
1522                        proc.crashDialog = d;
1523                    } else {
1524                        // The device is asleep, so just pretend that the user
1525                        // saw a crash dialog and hit "force quit".
1526                        if (res != null) {
1527                            res.set(0);
1528                        }
1529                    }
1530                }
1531
1532                ensureBootCompleted();
1533            } break;
1534            case SHOW_NOT_RESPONDING_UI_MSG: {
1535                synchronized (ActivityManagerService.this) {
1536                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1537                    ProcessRecord proc = (ProcessRecord)data.get("app");
1538                    if (proc != null && proc.anrDialog != null) {
1539                        Slog.e(TAG, "App already has anr dialog: " + proc);
1540                        return;
1541                    }
1542
1543                    Intent intent = new Intent("android.intent.action.ANR");
1544                    if (!mProcessesReady) {
1545                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1546                                | Intent.FLAG_RECEIVER_FOREGROUND);
1547                    }
1548                    broadcastIntentLocked(null, null, intent,
1549                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1550                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1551
1552                    if (mShowDialogs) {
1553                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1554                                mContext, proc, (ActivityRecord)data.get("activity"),
1555                                msg.arg1 != 0);
1556                        d.show();
1557                        proc.anrDialog = d;
1558                    } else {
1559                        // Just kill the app if there is no dialog to be shown.
1560                        killAppAtUsersRequest(proc, null);
1561                    }
1562                }
1563
1564                ensureBootCompleted();
1565            } break;
1566            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1567                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1568                synchronized (ActivityManagerService.this) {
1569                    ProcessRecord proc = (ProcessRecord) data.get("app");
1570                    if (proc == null) {
1571                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1572                        break;
1573                    }
1574                    if (proc.crashDialog != null) {
1575                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1576                        return;
1577                    }
1578                    AppErrorResult res = (AppErrorResult) data.get("result");
1579                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1580                        Dialog d = new StrictModeViolationDialog(mContext,
1581                                ActivityManagerService.this, res, proc);
1582                        d.show();
1583                        proc.crashDialog = d;
1584                    } else {
1585                        // The device is asleep, so just pretend that the user
1586                        // saw a crash dialog and hit "force quit".
1587                        res.set(0);
1588                    }
1589                }
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_FACTORY_ERROR_UI_MSG: {
1593                Dialog d = new FactoryErrorDialog(
1594                    mContext, msg.getData().getCharSequence("msg"));
1595                d.show();
1596                ensureBootCompleted();
1597            } break;
1598            case WAIT_FOR_DEBUGGER_UI_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ProcessRecord app = (ProcessRecord)msg.obj;
1601                    if (msg.arg1 != 0) {
1602                        if (!app.waitedForDebugger) {
1603                            Dialog d = new AppWaitingForDebuggerDialog(
1604                                    ActivityManagerService.this,
1605                                    mContext, app);
1606                            app.waitDialog = d;
1607                            app.waitedForDebugger = true;
1608                            d.show();
1609                        }
1610                    } else {
1611                        if (app.waitDialog != null) {
1612                            app.waitDialog.dismiss();
1613                            app.waitDialog = null;
1614                        }
1615                    }
1616                }
1617            } break;
1618            case SHOW_UID_ERROR_UI_MSG: {
1619                if (mShowDialogs) {
1620                    AlertDialog d = new BaseErrorDialog(mContext);
1621                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1622                    d.setCancelable(false);
1623                    d.setTitle(mContext.getText(R.string.android_system_label));
1624                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1625                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1626                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1627                    d.show();
1628                }
1629            } break;
1630            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1631                if (mShowDialogs) {
1632                    AlertDialog d = new BaseErrorDialog(mContext);
1633                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1634                    d.setCancelable(false);
1635                    d.setTitle(mContext.getText(R.string.android_system_label));
1636                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1637                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1638                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1639                    d.show();
1640                }
1641            } break;
1642            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1643                synchronized (ActivityManagerService.this) {
1644                    ActivityRecord ar = (ActivityRecord) msg.obj;
1645                    if (mCompatModeDialog != null) {
1646                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1647                                ar.info.applicationInfo.packageName)) {
1648                            return;
1649                        }
1650                        mCompatModeDialog.dismiss();
1651                        mCompatModeDialog = null;
1652                    }
1653                    if (ar != null && false) {
1654                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1655                                ar.packageName)) {
1656                            int mode = mCompatModePackages.computeCompatModeLocked(
1657                                    ar.info.applicationInfo);
1658                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1659                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1660                                mCompatModeDialog = new CompatModeDialog(
1661                                        ActivityManagerService.this, mContext,
1662                                        ar.info.applicationInfo);
1663                                mCompatModeDialog.show();
1664                            }
1665                        }
1666                    }
1667                }
1668                break;
1669            }
1670            case START_USER_SWITCH_UI_MSG: {
1671                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1672                break;
1673            }
1674            case DISMISS_DIALOG_UI_MSG: {
1675                final Dialog d = (Dialog) msg.obj;
1676                d.dismiss();
1677                break;
1678            }
1679            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1680                dispatchProcessesChanged();
1681                break;
1682            }
1683            case DISPATCH_PROCESS_DIED_UI_MSG: {
1684                final int pid = msg.arg1;
1685                final int uid = msg.arg2;
1686                dispatchProcessDied(pid, uid);
1687                break;
1688            }
1689            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1690                dispatchUidsChanged();
1691            } break;
1692            }
1693        }
1694    }
1695
1696    final class MainHandler extends Handler {
1697        public MainHandler(Looper looper) {
1698            super(looper, null, true);
1699        }
1700
1701        @Override
1702        public void handleMessage(Message msg) {
1703            switch (msg.what) {
1704            case UPDATE_CONFIGURATION_MSG: {
1705                final ContentResolver resolver = mContext.getContentResolver();
1706                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1707                        msg.arg1);
1708            } break;
1709            case GC_BACKGROUND_PROCESSES_MSG: {
1710                synchronized (ActivityManagerService.this) {
1711                    performAppGcsIfAppropriateLocked();
1712                }
1713            } break;
1714            case SERVICE_TIMEOUT_MSG: {
1715                if (mDidDexOpt) {
1716                    mDidDexOpt = false;
1717                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1718                    nmsg.obj = msg.obj;
1719                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1720                    return;
1721                }
1722                mServices.serviceTimeout((ProcessRecord)msg.obj);
1723            } break;
1724            case UPDATE_TIME_ZONE: {
1725                synchronized (ActivityManagerService.this) {
1726                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1727                        ProcessRecord r = mLruProcesses.get(i);
1728                        if (r.thread != null) {
1729                            try {
1730                                r.thread.updateTimeZone();
1731                            } catch (RemoteException ex) {
1732                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1733                            }
1734                        }
1735                    }
1736                }
1737            } break;
1738            case CLEAR_DNS_CACHE_MSG: {
1739                synchronized (ActivityManagerService.this) {
1740                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1741                        ProcessRecord r = mLruProcesses.get(i);
1742                        if (r.thread != null) {
1743                            try {
1744                                r.thread.clearDnsCache();
1745                            } catch (RemoteException ex) {
1746                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1747                            }
1748                        }
1749                    }
1750                }
1751            } break;
1752            case UPDATE_HTTP_PROXY_MSG: {
1753                ProxyInfo proxy = (ProxyInfo)msg.obj;
1754                String host = "";
1755                String port = "";
1756                String exclList = "";
1757                Uri pacFileUrl = Uri.EMPTY;
1758                if (proxy != null) {
1759                    host = proxy.getHost();
1760                    port = Integer.toString(proxy.getPort());
1761                    exclList = proxy.getExclusionListAsString();
1762                    pacFileUrl = proxy.getPacFileUrl();
1763                }
1764                synchronized (ActivityManagerService.this) {
1765                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1766                        ProcessRecord r = mLruProcesses.get(i);
1767                        if (r.thread != null) {
1768                            try {
1769                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1770                            } catch (RemoteException ex) {
1771                                Slog.w(TAG, "Failed to update http proxy for: " +
1772                                        r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case PROC_START_TIMEOUT_MSG: {
1779                if (mDidDexOpt) {
1780                    mDidDexOpt = false;
1781                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1782                    nmsg.obj = msg.obj;
1783                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1784                    return;
1785                }
1786                ProcessRecord app = (ProcessRecord)msg.obj;
1787                synchronized (ActivityManagerService.this) {
1788                    processStartTimedOutLocked(app);
1789                }
1790            } break;
1791            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1792                ProcessRecord app = (ProcessRecord)msg.obj;
1793                synchronized (ActivityManagerService.this) {
1794                    processContentProviderPublishTimedOutLocked(app);
1795                }
1796            } break;
1797            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1798                synchronized (ActivityManagerService.this) {
1799                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1800                }
1801            } break;
1802            case KILL_APPLICATION_MSG: {
1803                synchronized (ActivityManagerService.this) {
1804                    int appid = msg.arg1;
1805                    boolean restart = (msg.arg2 == 1);
1806                    Bundle bundle = (Bundle)msg.obj;
1807                    String pkg = bundle.getString("pkg");
1808                    String reason = bundle.getString("reason");
1809                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1810                            false, UserHandle.USER_ALL, reason);
1811                }
1812            } break;
1813            case FINALIZE_PENDING_INTENT_MSG: {
1814                ((PendingIntentRecord)msg.obj).completeFinalize();
1815            } break;
1816            case POST_HEAVY_NOTIFICATION_MSG: {
1817                INotificationManager inm = NotificationManager.getService();
1818                if (inm == null) {
1819                    return;
1820                }
1821
1822                ActivityRecord root = (ActivityRecord)msg.obj;
1823                ProcessRecord process = root.app;
1824                if (process == null) {
1825                    return;
1826                }
1827
1828                try {
1829                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1830                    String text = mContext.getString(R.string.heavy_weight_notification,
1831                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1832                    Notification notification = new Notification.Builder(context)
1833                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1834                            .setWhen(0)
1835                            .setOngoing(true)
1836                            .setTicker(text)
1837                            .setColor(mContext.getColor(
1838                                    com.android.internal.R.color.system_notification_accent_color))
1839                            .setContentTitle(text)
1840                            .setContentText(
1841                                    mContext.getText(R.string.heavy_weight_notification_detail))
1842                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1843                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1844                                    new UserHandle(root.userId)))
1845                            .build();
1846                    try {
1847                        int[] outId = new int[1];
1848                        inm.enqueueNotificationWithTag("android", "android", null,
1849                                R.string.heavy_weight_notification,
1850                                notification, outId, root.userId);
1851                    } catch (RuntimeException e) {
1852                        Slog.w(ActivityManagerService.TAG,
1853                                "Error showing notification for heavy-weight app", e);
1854                    } catch (RemoteException e) {
1855                    }
1856                } catch (NameNotFoundException e) {
1857                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1858                }
1859            } break;
1860            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1861                INotificationManager inm = NotificationManager.getService();
1862                if (inm == null) {
1863                    return;
1864                }
1865                try {
1866                    inm.cancelNotificationWithTag("android", null,
1867                            R.string.heavy_weight_notification,  msg.arg1);
1868                } catch (RuntimeException e) {
1869                    Slog.w(ActivityManagerService.TAG,
1870                            "Error canceling notification for service", e);
1871                } catch (RemoteException e) {
1872                }
1873            } break;
1874            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1875                synchronized (ActivityManagerService.this) {
1876                    checkExcessivePowerUsageLocked(true);
1877                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1878                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1879                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1880                }
1881            } break;
1882            case REPORT_MEM_USAGE_MSG: {
1883                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1884                Thread thread = new Thread() {
1885                    @Override public void run() {
1886                        reportMemUsage(memInfos);
1887                    }
1888                };
1889                thread.start();
1890                break;
1891            }
1892            case REPORT_USER_SWITCH_MSG: {
1893                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1894                break;
1895            }
1896            case CONTINUE_USER_SWITCH_MSG: {
1897                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1898                break;
1899            }
1900            case USER_SWITCH_TIMEOUT_MSG: {
1901                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1902                break;
1903            }
1904            case IMMERSIVE_MODE_LOCK_MSG: {
1905                final boolean nextState = (msg.arg1 != 0);
1906                if (mUpdateLock.isHeld() != nextState) {
1907                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1908                            "Applying new update lock state '" + nextState
1909                            + "' for " + (ActivityRecord)msg.obj);
1910                    if (nextState) {
1911                        mUpdateLock.acquire();
1912                    } else {
1913                        mUpdateLock.release();
1914                    }
1915                }
1916                break;
1917            }
1918            case PERSIST_URI_GRANTS_MSG: {
1919                writeGrantedUriPermissions();
1920                break;
1921            }
1922            case REQUEST_ALL_PSS_MSG: {
1923                synchronized (ActivityManagerService.this) {
1924                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1925                }
1926                break;
1927            }
1928            case START_PROFILES_MSG: {
1929                synchronized (ActivityManagerService.this) {
1930                    mUserController.startProfilesLocked();
1931                }
1932                break;
1933            }
1934            case UPDATE_TIME: {
1935                synchronized (ActivityManagerService.this) {
1936                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1937                        ProcessRecord r = mLruProcesses.get(i);
1938                        if (r.thread != null) {
1939                            try {
1940                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1941                            } catch (RemoteException ex) {
1942                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1943                            }
1944                        }
1945                    }
1946                }
1947                break;
1948            }
1949            case SYSTEM_USER_START_MSG: {
1950                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1951                        Integer.toString(msg.arg1), msg.arg1);
1952                mSystemServiceManager.startUser(msg.arg1);
1953                break;
1954            }
1955            case SYSTEM_USER_UNLOCK_MSG: {
1956                final int userId = msg.arg1;
1957                mSystemServiceManager.unlockUser(userId);
1958                mRecentTasks.cleanupLocked(userId);
1959                installEncryptionUnawareProviders(userId);
1960                break;
1961            }
1962            case SYSTEM_USER_CURRENT_MSG: {
1963                mBatteryStatsService.noteEvent(
1964                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1965                        Integer.toString(msg.arg2), msg.arg2);
1966                mBatteryStatsService.noteEvent(
1967                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1968                        Integer.toString(msg.arg1), msg.arg1);
1969                mSystemServiceManager.switchUser(msg.arg1);
1970                break;
1971            }
1972            case ENTER_ANIMATION_COMPLETE_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1975                    if (r != null && r.app != null && r.app.thread != null) {
1976                        try {
1977                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1978                        } catch (RemoteException e) {
1979                        }
1980                    }
1981                }
1982                break;
1983            }
1984            case FINISH_BOOTING_MSG: {
1985                if (msg.arg1 != 0) {
1986                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1987                    finishBooting();
1988                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1989                }
1990                if (msg.arg2 != 0) {
1991                    enableScreenAfterBoot();
1992                }
1993                break;
1994            }
1995            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1996                try {
1997                    Locale l = (Locale) msg.obj;
1998                    IBinder service = ServiceManager.getService("mount");
1999                    IMountService mountService = IMountService.Stub.asInterface(service);
2000                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2001                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2002                } catch (RemoteException e) {
2003                    Log.e(TAG, "Error storing locale for decryption UI", e);
2004                }
2005                break;
2006            }
2007            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2010                        try {
2011                            // Make a one-way callback to the listener
2012                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2013                        } catch (RemoteException e){
2014                            // Handled by the RemoteCallbackList
2015                        }
2016                    }
2017                    mTaskStackListeners.finishBroadcast();
2018                }
2019                break;
2020            }
2021            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2022                synchronized (ActivityManagerService.this) {
2023                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2024                        try {
2025                            // Make a one-way callback to the listener
2026                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2027                        } catch (RemoteException e){
2028                            // Handled by the RemoteCallbackList
2029                        }
2030                    }
2031                    mTaskStackListeners.finishBroadcast();
2032                }
2033                break;
2034            }
2035            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2036                final int uid = msg.arg1;
2037                final byte[] firstPacket = (byte[]) msg.obj;
2038
2039                synchronized (mPidsSelfLocked) {
2040                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2041                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2042                        if (p.uid == uid) {
2043                            try {
2044                                p.thread.notifyCleartextNetwork(firstPacket);
2045                            } catch (RemoteException ignored) {
2046                            }
2047                        }
2048                    }
2049                }
2050                break;
2051            }
2052            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2053                final String procName;
2054                final int uid;
2055                final long memLimit;
2056                final String reportPackage;
2057                synchronized (ActivityManagerService.this) {
2058                    procName = mMemWatchDumpProcName;
2059                    uid = mMemWatchDumpUid;
2060                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2061                    if (val == null) {
2062                        val = mMemWatchProcesses.get(procName, 0);
2063                    }
2064                    if (val != null) {
2065                        memLimit = val.first;
2066                        reportPackage = val.second;
2067                    } else {
2068                        memLimit = 0;
2069                        reportPackage = null;
2070                    }
2071                }
2072                if (procName == null) {
2073                    return;
2074                }
2075
2076                if (DEBUG_PSS) Slog.d(TAG_PSS,
2077                        "Showing dump heap notification from " + procName + "/" + uid);
2078
2079                INotificationManager inm = NotificationManager.getService();
2080                if (inm == null) {
2081                    return;
2082                }
2083
2084                String text = mContext.getString(R.string.dump_heap_notification, procName);
2085
2086
2087                Intent deleteIntent = new Intent();
2088                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2089                Intent intent = new Intent();
2090                intent.setClassName("android", DumpHeapActivity.class.getName());
2091                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2092                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2093                if (reportPackage != null) {
2094                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2095                }
2096                int userId = UserHandle.getUserId(uid);
2097                Notification notification = new Notification.Builder(mContext)
2098                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2099                        .setWhen(0)
2100                        .setOngoing(true)
2101                        .setAutoCancel(true)
2102                        .setTicker(text)
2103                        .setColor(mContext.getColor(
2104                                com.android.internal.R.color.system_notification_accent_color))
2105                        .setContentTitle(text)
2106                        .setContentText(
2107                                mContext.getText(R.string.dump_heap_notification_detail))
2108                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2109                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2110                                new UserHandle(userId)))
2111                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2112                                deleteIntent, 0, UserHandle.SYSTEM))
2113                        .build();
2114
2115                try {
2116                    int[] outId = new int[1];
2117                    inm.enqueueNotificationWithTag("android", "android", null,
2118                            R.string.dump_heap_notification,
2119                            notification, outId, userId);
2120                } catch (RuntimeException e) {
2121                    Slog.w(ActivityManagerService.TAG,
2122                            "Error showing notification for dump heap", e);
2123                } catch (RemoteException e) {
2124                }
2125            } break;
2126            case DELETE_DUMPHEAP_MSG: {
2127                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2128                        DumpHeapActivity.JAVA_URI,
2129                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2130                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2131                        UserHandle.myUserId());
2132                synchronized (ActivityManagerService.this) {
2133                    mMemWatchDumpFile = null;
2134                    mMemWatchDumpProcName = null;
2135                    mMemWatchDumpPid = -1;
2136                    mMemWatchDumpUid = -1;
2137                }
2138            } break;
2139            case FOREGROUND_PROFILE_CHANGED_MSG: {
2140                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2141            } break;
2142            case REPORT_TIME_TRACKER_MSG: {
2143                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2144                tracker.deliverResult(mContext);
2145            } break;
2146            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2147                mUserController.dispatchUserSwitchComplete(msg.arg1);
2148            } break;
2149            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2150                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2151                try {
2152                    connection.shutdown();
2153                } catch (RemoteException e) {
2154                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2155                }
2156                // Only a UiAutomation can set this flag and now that
2157                // it is finished we make sure it is reset to its default.
2158                mUserIsMonkey = false;
2159            } break;
2160            case APP_BOOST_DEACTIVATE_MSG: {
2161                synchronized(ActivityManagerService.this) {
2162                    if (mIsBoosted) {
2163                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2164                            nativeMigrateFromBoost();
2165                            mIsBoosted = false;
2166                            mBoostStartTime = 0;
2167                        } else {
2168                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2169                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2170                        }
2171                    }
2172                }
2173            } break;
2174            case IDLE_UIDS_MSG: {
2175                idleUids();
2176            } break;
2177            case LOG_STACK_STATE: {
2178                synchronized (ActivityManagerService.this) {
2179                    mStackSupervisor.logStackState();
2180                }
2181            } break;
2182            case VR_MODE_CHANGE_MSG: {
2183                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2184                vrService.setVrMode(msg.arg1 != 0);
2185            } break;
2186            }
2187        }
2188    };
2189
2190    static final int COLLECT_PSS_BG_MSG = 1;
2191
2192    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2193        @Override
2194        public void handleMessage(Message msg) {
2195            switch (msg.what) {
2196            case COLLECT_PSS_BG_MSG: {
2197                long start = SystemClock.uptimeMillis();
2198                MemInfoReader memInfo = null;
2199                synchronized (ActivityManagerService.this) {
2200                    if (mFullPssPending) {
2201                        mFullPssPending = false;
2202                        memInfo = new MemInfoReader();
2203                    }
2204                }
2205                if (memInfo != null) {
2206                    updateCpuStatsNow();
2207                    long nativeTotalPss = 0;
2208                    synchronized (mProcessCpuTracker) {
2209                        final int N = mProcessCpuTracker.countStats();
2210                        for (int j=0; j<N; j++) {
2211                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2212                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2213                                // This is definitely an application process; skip it.
2214                                continue;
2215                            }
2216                            synchronized (mPidsSelfLocked) {
2217                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2218                                    // This is one of our own processes; skip it.
2219                                    continue;
2220                                }
2221                            }
2222                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2223                        }
2224                    }
2225                    memInfo.readMemInfo();
2226                    synchronized (ActivityManagerService.this) {
2227                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2228                                + (SystemClock.uptimeMillis()-start) + "ms");
2229                        final long cachedKb = memInfo.getCachedSizeKb();
2230                        final long freeKb = memInfo.getFreeSizeKb();
2231                        final long zramKb = memInfo.getZramTotalSizeKb();
2232                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2233                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2234                                kernelKb*1024, nativeTotalPss*1024);
2235                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2236                                nativeTotalPss);
2237                    }
2238                }
2239
2240                int num = 0;
2241                long[] tmp = new long[2];
2242                do {
2243                    ProcessRecord proc;
2244                    int procState;
2245                    int pid;
2246                    long lastPssTime;
2247                    synchronized (ActivityManagerService.this) {
2248                        if (mPendingPssProcesses.size() <= 0) {
2249                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2250                                    "Collected PSS of " + num + " processes in "
2251                                    + (SystemClock.uptimeMillis() - start) + "ms");
2252                            mPendingPssProcesses.clear();
2253                            return;
2254                        }
2255                        proc = mPendingPssProcesses.remove(0);
2256                        procState = proc.pssProcState;
2257                        lastPssTime = proc.lastPssTime;
2258                        if (proc.thread != null && procState == proc.setProcState
2259                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2260                                        < SystemClock.uptimeMillis()) {
2261                            pid = proc.pid;
2262                        } else {
2263                            proc = null;
2264                            pid = 0;
2265                        }
2266                    }
2267                    if (proc != null) {
2268                        long pss = Debug.getPss(pid, tmp, null);
2269                        synchronized (ActivityManagerService.this) {
2270                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2271                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2272                                num++;
2273                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2274                                        SystemClock.uptimeMillis());
2275                            }
2276                        }
2277                    }
2278                } while (true);
2279            }
2280            }
2281        }
2282    };
2283
2284    public void setSystemProcess() {
2285        try {
2286            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2287            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2288            ServiceManager.addService("meminfo", new MemBinder(this));
2289            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2290            ServiceManager.addService("dbinfo", new DbBinder(this));
2291            if (MONITOR_CPU_USAGE) {
2292                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2293            }
2294            ServiceManager.addService("permission", new PermissionController(this));
2295            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2296
2297            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2298                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2299            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2300
2301            synchronized (this) {
2302                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2303                app.persistent = true;
2304                app.pid = MY_PID;
2305                app.maxAdj = ProcessList.SYSTEM_ADJ;
2306                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2307                synchronized (mPidsSelfLocked) {
2308                    mPidsSelfLocked.put(app.pid, app);
2309                }
2310                updateLruProcessLocked(app, false, null);
2311                updateOomAdjLocked();
2312            }
2313        } catch (PackageManager.NameNotFoundException e) {
2314            throw new RuntimeException(
2315                    "Unable to find android system package", e);
2316        }
2317    }
2318
2319    public void setWindowManager(WindowManagerService wm) {
2320        mWindowManager = wm;
2321        mStackSupervisor.setWindowManager(wm);
2322        mActivityStarter.setWindowManager(wm);
2323    }
2324
2325    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2326        mUsageStatsService = usageStatsManager;
2327    }
2328
2329    public void startObservingNativeCrashes() {
2330        final NativeCrashListener ncl = new NativeCrashListener(this);
2331        ncl.start();
2332    }
2333
2334    public IAppOpsService getAppOpsService() {
2335        return mAppOpsService;
2336    }
2337
2338    static class MemBinder extends Binder {
2339        ActivityManagerService mActivityManagerService;
2340        MemBinder(ActivityManagerService activityManagerService) {
2341            mActivityManagerService = activityManagerService;
2342        }
2343
2344        @Override
2345        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2346            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2347                    != PackageManager.PERMISSION_GRANTED) {
2348                pw.println("Permission Denial: can't dump meminfo from from pid="
2349                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2350                        + " without permission " + android.Manifest.permission.DUMP);
2351                return;
2352            }
2353
2354            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2355        }
2356    }
2357
2358    static class GraphicsBinder extends Binder {
2359        ActivityManagerService mActivityManagerService;
2360        GraphicsBinder(ActivityManagerService activityManagerService) {
2361            mActivityManagerService = activityManagerService;
2362        }
2363
2364        @Override
2365        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2366            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2367                    != PackageManager.PERMISSION_GRANTED) {
2368                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2369                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2370                        + " without permission " + android.Manifest.permission.DUMP);
2371                return;
2372            }
2373
2374            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2375        }
2376    }
2377
2378    static class DbBinder extends Binder {
2379        ActivityManagerService mActivityManagerService;
2380        DbBinder(ActivityManagerService activityManagerService) {
2381            mActivityManagerService = activityManagerService;
2382        }
2383
2384        @Override
2385        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2386            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2387                    != PackageManager.PERMISSION_GRANTED) {
2388                pw.println("Permission Denial: can't dump dbinfo from from pid="
2389                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2390                        + " without permission " + android.Manifest.permission.DUMP);
2391                return;
2392            }
2393
2394            mActivityManagerService.dumpDbInfo(fd, pw, args);
2395        }
2396    }
2397
2398    static class CpuBinder extends Binder {
2399        ActivityManagerService mActivityManagerService;
2400        CpuBinder(ActivityManagerService activityManagerService) {
2401            mActivityManagerService = activityManagerService;
2402        }
2403
2404        @Override
2405        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2406            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2407                    != PackageManager.PERMISSION_GRANTED) {
2408                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2409                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2410                        + " without permission " + android.Manifest.permission.DUMP);
2411                return;
2412            }
2413
2414            synchronized (mActivityManagerService.mProcessCpuTracker) {
2415                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2416                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2417                        SystemClock.uptimeMillis()));
2418            }
2419        }
2420    }
2421
2422    public static final class Lifecycle extends SystemService {
2423        private final ActivityManagerService mService;
2424
2425        public Lifecycle(Context context) {
2426            super(context);
2427            mService = new ActivityManagerService(context);
2428        }
2429
2430        @Override
2431        public void onStart() {
2432            mService.start();
2433        }
2434
2435        public ActivityManagerService getService() {
2436            return mService;
2437        }
2438    }
2439
2440    // Note: This method is invoked on the main thread but may need to attach various
2441    // handlers to other threads.  So take care to be explicit about the looper.
2442    public ActivityManagerService(Context systemContext) {
2443        mContext = systemContext;
2444        mFactoryTest = FactoryTest.getMode();
2445        mSystemThread = ActivityThread.currentActivityThread();
2446
2447        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2448
2449        mHandlerThread = new ServiceThread(TAG,
2450                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2451        mHandlerThread.start();
2452        mHandler = new MainHandler(mHandlerThread.getLooper());
2453        mUiHandler = new UiHandler();
2454
2455        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2456                "foreground", BROADCAST_FG_TIMEOUT, false);
2457        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2458                "background", BROADCAST_BG_TIMEOUT, true);
2459        mBroadcastQueues[0] = mFgBroadcastQueue;
2460        mBroadcastQueues[1] = mBgBroadcastQueue;
2461
2462        mServices = new ActiveServices(this);
2463        mProviderMap = new ProviderMap(this);
2464
2465        // TODO: Move creation of battery stats service outside of activity manager service.
2466        File dataDir = Environment.getDataDirectory();
2467        File systemDir = new File(dataDir, "system");
2468        systemDir.mkdirs();
2469        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2470        mBatteryStatsService.getActiveStatistics().readLocked();
2471        mBatteryStatsService.scheduleWriteToDisk();
2472        mOnBattery = DEBUG_POWER ? true
2473                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2474        mBatteryStatsService.getActiveStatistics().setCallback(this);
2475
2476        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2477
2478        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2479        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2480                new IAppOpsCallback.Stub() {
2481                    @Override public void opChanged(int op, int uid, String packageName) {
2482                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2483                            if (mAppOpsService.checkOperation(op, uid, packageName)
2484                                    != AppOpsManager.MODE_ALLOWED) {
2485                                runInBackgroundDisabled(uid);
2486                            }
2487                        }
2488                    }
2489                });
2490
2491        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2492
2493        mUserController = new UserController(this);
2494
2495        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2496            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2497
2498        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2499
2500        mConfiguration.setToDefaults();
2501        mConfiguration.setLocales(LocaleList.getDefault());
2502
2503        mConfigurationSeq = mConfiguration.seq = 1;
2504        mProcessCpuTracker.init();
2505
2506        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2507        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2508        mStackSupervisor = new ActivityStackSupervisor(this);
2509        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2510        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2511
2512
2513        mProcessCpuThread = new Thread("CpuTracker") {
2514            @Override
2515            public void run() {
2516                while (true) {
2517                    try {
2518                        try {
2519                            synchronized(this) {
2520                                final long now = SystemClock.uptimeMillis();
2521                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2522                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2523                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2524                                //        + ", write delay=" + nextWriteDelay);
2525                                if (nextWriteDelay < nextCpuDelay) {
2526                                    nextCpuDelay = nextWriteDelay;
2527                                }
2528                                if (nextCpuDelay > 0) {
2529                                    mProcessCpuMutexFree.set(true);
2530                                    this.wait(nextCpuDelay);
2531                                }
2532                            }
2533                        } catch (InterruptedException e) {
2534                        }
2535                        updateCpuStatsNow();
2536                    } catch (Exception e) {
2537                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2538                    }
2539                }
2540            }
2541        };
2542
2543        Watchdog.getInstance().addMonitor(this);
2544        Watchdog.getInstance().addThread(mHandler);
2545    }
2546
2547    public void setSystemServiceManager(SystemServiceManager mgr) {
2548        mSystemServiceManager = mgr;
2549    }
2550
2551    public void setInstaller(Installer installer) {
2552        mInstaller = installer;
2553    }
2554
2555    private void start() {
2556        Process.removeAllProcessGroups();
2557        mProcessCpuThread.start();
2558
2559        mBatteryStatsService.publish(mContext);
2560        mAppOpsService.publish(mContext);
2561        Slog.d("AppOps", "AppOpsService published");
2562        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2563    }
2564
2565    void onUserStoppedLocked(int userId) {
2566        mRecentTasks.unloadUserRecentsLocked(userId);
2567    }
2568
2569    public void initPowerManagement() {
2570        mStackSupervisor.initPowerManagement();
2571        mBatteryStatsService.initPowerManagement();
2572        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2573        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2574        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2575        mVoiceWakeLock.setReferenceCounted(false);
2576    }
2577
2578    @Override
2579    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2580            throws RemoteException {
2581        if (code == SYSPROPS_TRANSACTION) {
2582            // We need to tell all apps about the system property change.
2583            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2584            synchronized(this) {
2585                final int NP = mProcessNames.getMap().size();
2586                for (int ip=0; ip<NP; ip++) {
2587                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2588                    final int NA = apps.size();
2589                    for (int ia=0; ia<NA; ia++) {
2590                        ProcessRecord app = apps.valueAt(ia);
2591                        if (app.thread != null) {
2592                            procs.add(app.thread.asBinder());
2593                        }
2594                    }
2595                }
2596            }
2597
2598            int N = procs.size();
2599            for (int i=0; i<N; i++) {
2600                Parcel data2 = Parcel.obtain();
2601                try {
2602                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2603                } catch (RemoteException e) {
2604                }
2605                data2.recycle();
2606            }
2607        }
2608        try {
2609            return super.onTransact(code, data, reply, flags);
2610        } catch (RuntimeException e) {
2611            // The activity manager only throws security exceptions, so let's
2612            // log all others.
2613            if (!(e instanceof SecurityException)) {
2614                Slog.wtf(TAG, "Activity Manager Crash", e);
2615            }
2616            throw e;
2617        }
2618    }
2619
2620    void updateCpuStats() {
2621        final long now = SystemClock.uptimeMillis();
2622        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2623            return;
2624        }
2625        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2626            synchronized (mProcessCpuThread) {
2627                mProcessCpuThread.notify();
2628            }
2629        }
2630    }
2631
2632    void updateCpuStatsNow() {
2633        synchronized (mProcessCpuTracker) {
2634            mProcessCpuMutexFree.set(false);
2635            final long now = SystemClock.uptimeMillis();
2636            boolean haveNewCpuStats = false;
2637
2638            if (MONITOR_CPU_USAGE &&
2639                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2640                mLastCpuTime.set(now);
2641                mProcessCpuTracker.update();
2642                if (mProcessCpuTracker.hasGoodLastStats()) {
2643                    haveNewCpuStats = true;
2644                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2645                    //Slog.i(TAG, "Total CPU usage: "
2646                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2647
2648                    // Slog the cpu usage if the property is set.
2649                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2650                        int user = mProcessCpuTracker.getLastUserTime();
2651                        int system = mProcessCpuTracker.getLastSystemTime();
2652                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2653                        int irq = mProcessCpuTracker.getLastIrqTime();
2654                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2655                        int idle = mProcessCpuTracker.getLastIdleTime();
2656
2657                        int total = user + system + iowait + irq + softIrq + idle;
2658                        if (total == 0) total = 1;
2659
2660                        EventLog.writeEvent(EventLogTags.CPU,
2661                                ((user+system+iowait+irq+softIrq) * 100) / total,
2662                                (user * 100) / total,
2663                                (system * 100) / total,
2664                                (iowait * 100) / total,
2665                                (irq * 100) / total,
2666                                (softIrq * 100) / total);
2667                    }
2668                }
2669            }
2670
2671            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2672            synchronized(bstats) {
2673                synchronized(mPidsSelfLocked) {
2674                    if (haveNewCpuStats) {
2675                        if (bstats.startAddingCpuLocked()) {
2676                            int totalUTime = 0;
2677                            int totalSTime = 0;
2678                            final int N = mProcessCpuTracker.countStats();
2679                            for (int i=0; i<N; i++) {
2680                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2681                                if (!st.working) {
2682                                    continue;
2683                                }
2684                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2685                                totalUTime += st.rel_utime;
2686                                totalSTime += st.rel_stime;
2687                                if (pr != null) {
2688                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2689                                    if (ps == null || !ps.isActive()) {
2690                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2691                                                pr.info.uid, pr.processName);
2692                                    }
2693                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2694                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2695                                } else {
2696                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2697                                    if (ps == null || !ps.isActive()) {
2698                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2699                                                bstats.mapUid(st.uid), st.name);
2700                                    }
2701                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2702                                }
2703                            }
2704                            final int userTime = mProcessCpuTracker.getLastUserTime();
2705                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2706                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2707                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2708                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2709                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2710                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2711                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2712                        }
2713                    }
2714                }
2715
2716                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2717                    mLastWriteTime = now;
2718                    mBatteryStatsService.scheduleWriteToDisk();
2719                }
2720            }
2721        }
2722    }
2723
2724    @Override
2725    public void batteryNeedsCpuUpdate() {
2726        updateCpuStatsNow();
2727    }
2728
2729    @Override
2730    public void batteryPowerChanged(boolean onBattery) {
2731        // When plugging in, update the CPU stats first before changing
2732        // the plug state.
2733        updateCpuStatsNow();
2734        synchronized (this) {
2735            synchronized(mPidsSelfLocked) {
2736                mOnBattery = DEBUG_POWER ? true : onBattery;
2737            }
2738        }
2739    }
2740
2741    @Override
2742    public void batterySendBroadcast(Intent intent) {
2743        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2744                AppOpsManager.OP_NONE, null, false, false,
2745                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2746    }
2747
2748    /**
2749     * Initialize the application bind args. These are passed to each
2750     * process when the bindApplication() IPC is sent to the process. They're
2751     * lazily setup to make sure the services are running when they're asked for.
2752     */
2753    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2754        if (mAppBindArgs == null) {
2755            mAppBindArgs = new HashMap<>();
2756
2757            // Isolated processes won't get this optimization, so that we don't
2758            // violate the rules about which services they have access to.
2759            if (!isolated) {
2760                // Setup the application init args
2761                mAppBindArgs.put("package", ServiceManager.getService("package"));
2762                mAppBindArgs.put("window", ServiceManager.getService("window"));
2763                mAppBindArgs.put(Context.ALARM_SERVICE,
2764                        ServiceManager.getService(Context.ALARM_SERVICE));
2765            }
2766        }
2767        return mAppBindArgs;
2768    }
2769
2770    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2771        if (r == null || mFocusedActivity == r) {
2772            return false;
2773        }
2774
2775        if (!r.isFocusable()) {
2776            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2777            return false;
2778        }
2779
2780        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2781        final ActivityRecord last = mFocusedActivity;
2782        mFocusedActivity = r;
2783        if (r.task.isApplicationTask()) {
2784            if (mCurAppTimeTracker != r.appTimeTracker) {
2785                // We are switching app tracking.  Complete the current one.
2786                if (mCurAppTimeTracker != null) {
2787                    mCurAppTimeTracker.stop();
2788                    mHandler.obtainMessage(
2789                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2790                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2791                    mCurAppTimeTracker = null;
2792                }
2793                if (r.appTimeTracker != null) {
2794                    mCurAppTimeTracker = r.appTimeTracker;
2795                    startTimeTrackingFocusedActivityLocked();
2796                }
2797            } else {
2798                startTimeTrackingFocusedActivityLocked();
2799            }
2800        } else {
2801            r.appTimeTracker = null;
2802        }
2803        if (r.task.voiceInteractor != null) {
2804            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2805        } else {
2806            finishRunningVoiceLocked();
2807            if (last != null && last.task.voiceSession != null) {
2808                // We had been in a voice interaction session, but now focused has
2809                // move to something different.  Just finish the session, we can't
2810                // return to it and retain the proper state and synchronization with
2811                // the voice interaction service.
2812                finishVoiceTask(last.task.voiceSession);
2813            }
2814        }
2815        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2816            mWindowManager.setFocusedApp(r.appToken, true);
2817        }
2818        applyUpdateLockStateLocked(r);
2819        applyUpdateVrModeLocked(r);
2820        if (mFocusedActivity.userId != mLastFocusedUserId) {
2821            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2822            mHandler.obtainMessage(
2823                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2824            mLastFocusedUserId = mFocusedActivity.userId;
2825        }
2826
2827        EventLogTags.writeAmFocusedActivity(
2828                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2829                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2830                reason);
2831        return true;
2832    }
2833
2834    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2835        if (mFocusedActivity != goingAway) {
2836            return;
2837        }
2838
2839        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2840        if (focusedStack != null) {
2841            final ActivityRecord top = focusedStack.topActivity();
2842            if (top != null && top.userId != mLastFocusedUserId) {
2843                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2844                mHandler.sendMessage(
2845                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2846                mLastFocusedUserId = top.userId;
2847            }
2848        }
2849
2850        // Try to move focus to another activity if possible.
2851        if (setFocusedActivityLocked(
2852                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2853            return;
2854        }
2855
2856        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2857                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2858        mFocusedActivity = null;
2859        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2860    }
2861
2862    @Override
2863    public void setFocusedStack(int stackId) {
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2865        synchronized (ActivityManagerService.this) {
2866            ActivityStack stack = mStackSupervisor.getStack(stackId);
2867            if (stack != null) {
2868                ActivityRecord r = stack.topRunningActivityLocked();
2869                if (r != null) {
2870                    setFocusedActivityLocked(r, "setFocusedStack");
2871                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2872                }
2873            }
2874        }
2875    }
2876
2877    @Override
2878    public void setFocusedTask(int taskId) {
2879        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2880        long callingId = Binder.clearCallingIdentity();
2881        try {
2882            synchronized (ActivityManagerService.this) {
2883                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2884                if (task != null) {
2885                    final ActivityRecord r = task.topRunningActivityLocked();
2886                    if (setFocusedActivityLocked(r, "setFocusedTask")) {
2887                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
2888                    }
2889                }
2890            }
2891        } finally {
2892            Binder.restoreCallingIdentity(callingId);
2893        }
2894    }
2895
2896    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2897    @Override
2898    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2899        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2900        synchronized (this) {
2901            if (listener != null) {
2902                mTaskStackListeners.register(listener);
2903            }
2904        }
2905    }
2906
2907    @Override
2908    public void notifyActivityDrawn(IBinder token) {
2909        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2910        synchronized (this) {
2911            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2912            if (r != null) {
2913                r.task.stack.notifyActivityDrawnLocked(r);
2914            }
2915        }
2916    }
2917
2918    final void applyUpdateLockStateLocked(ActivityRecord r) {
2919        // Modifications to the UpdateLock state are done on our handler, outside
2920        // the activity manager's locks.  The new state is determined based on the
2921        // state *now* of the relevant activity record.  The object is passed to
2922        // the handler solely for logging detail, not to be consulted/modified.
2923        final boolean nextState = r != null && r.immersive;
2924        mHandler.sendMessage(
2925                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2926    }
2927
2928    final void applyUpdateVrModeLocked(ActivityRecord r) {
2929        mHandler.sendMessage(
2930                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2931    }
2932
2933    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2934        Message msg = Message.obtain();
2935        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2936        msg.obj = r.task.askedCompatMode ? null : r;
2937        mUiHandler.sendMessage(msg);
2938    }
2939
2940    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2941            String what, Object obj, ProcessRecord srcApp) {
2942        app.lastActivityTime = now;
2943
2944        if (app.activities.size() > 0) {
2945            // Don't want to touch dependent processes that are hosting activities.
2946            return index;
2947        }
2948
2949        int lrui = mLruProcesses.lastIndexOf(app);
2950        if (lrui < 0) {
2951            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2952                    + what + " " + obj + " from " + srcApp);
2953            return index;
2954        }
2955
2956        if (lrui >= index) {
2957            // Don't want to cause this to move dependent processes *back* in the
2958            // list as if they were less frequently used.
2959            return index;
2960        }
2961
2962        if (lrui >= mLruProcessActivityStart) {
2963            // Don't want to touch dependent processes that are hosting activities.
2964            return index;
2965        }
2966
2967        mLruProcesses.remove(lrui);
2968        if (index > 0) {
2969            index--;
2970        }
2971        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2972                + " in LRU list: " + app);
2973        mLruProcesses.add(index, app);
2974        return index;
2975    }
2976
2977    private static void killProcessGroup(int uid, int pid) {
2978        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2979        Process.killProcessGroup(uid, pid);
2980        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2981    }
2982
2983    final void removeLruProcessLocked(ProcessRecord app) {
2984        int lrui = mLruProcesses.lastIndexOf(app);
2985        if (lrui >= 0) {
2986            if (!app.killed) {
2987                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2988                Process.killProcessQuiet(app.pid);
2989                killProcessGroup(app.info.uid, app.pid);
2990            }
2991            if (lrui <= mLruProcessActivityStart) {
2992                mLruProcessActivityStart--;
2993            }
2994            if (lrui <= mLruProcessServiceStart) {
2995                mLruProcessServiceStart--;
2996            }
2997            mLruProcesses.remove(lrui);
2998        }
2999    }
3000
3001    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3002            ProcessRecord client) {
3003        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3004                || app.treatLikeActivity;
3005        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3006        if (!activityChange && hasActivity) {
3007            // The process has activities, so we are only allowing activity-based adjustments
3008            // to move it.  It should be kept in the front of the list with other
3009            // processes that have activities, and we don't want those to change their
3010            // order except due to activity operations.
3011            return;
3012        }
3013
3014        mLruSeq++;
3015        final long now = SystemClock.uptimeMillis();
3016        app.lastActivityTime = now;
3017
3018        // First a quick reject: if the app is already at the position we will
3019        // put it, then there is nothing to do.
3020        if (hasActivity) {
3021            final int N = mLruProcesses.size();
3022            if (N > 0 && mLruProcesses.get(N-1) == app) {
3023                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3024                return;
3025            }
3026        } else {
3027            if (mLruProcessServiceStart > 0
3028                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3029                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3030                return;
3031            }
3032        }
3033
3034        int lrui = mLruProcesses.lastIndexOf(app);
3035
3036        if (app.persistent && lrui >= 0) {
3037            // We don't care about the position of persistent processes, as long as
3038            // they are in the list.
3039            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3040            return;
3041        }
3042
3043        /* In progress: compute new position first, so we can avoid doing work
3044           if the process is not actually going to move.  Not yet working.
3045        int addIndex;
3046        int nextIndex;
3047        boolean inActivity = false, inService = false;
3048        if (hasActivity) {
3049            // Process has activities, put it at the very tipsy-top.
3050            addIndex = mLruProcesses.size();
3051            nextIndex = mLruProcessServiceStart;
3052            inActivity = true;
3053        } else if (hasService) {
3054            // Process has services, put it at the top of the service list.
3055            addIndex = mLruProcessActivityStart;
3056            nextIndex = mLruProcessServiceStart;
3057            inActivity = true;
3058            inService = true;
3059        } else  {
3060            // Process not otherwise of interest, it goes to the top of the non-service area.
3061            addIndex = mLruProcessServiceStart;
3062            if (client != null) {
3063                int clientIndex = mLruProcesses.lastIndexOf(client);
3064                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3065                        + app);
3066                if (clientIndex >= 0 && addIndex > clientIndex) {
3067                    addIndex = clientIndex;
3068                }
3069            }
3070            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3071        }
3072
3073        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3074                + mLruProcessActivityStart + "): " + app);
3075        */
3076
3077        if (lrui >= 0) {
3078            if (lrui < mLruProcessActivityStart) {
3079                mLruProcessActivityStart--;
3080            }
3081            if (lrui < mLruProcessServiceStart) {
3082                mLruProcessServiceStart--;
3083            }
3084            /*
3085            if (addIndex > lrui) {
3086                addIndex--;
3087            }
3088            if (nextIndex > lrui) {
3089                nextIndex--;
3090            }
3091            */
3092            mLruProcesses.remove(lrui);
3093        }
3094
3095        /*
3096        mLruProcesses.add(addIndex, app);
3097        if (inActivity) {
3098            mLruProcessActivityStart++;
3099        }
3100        if (inService) {
3101            mLruProcessActivityStart++;
3102        }
3103        */
3104
3105        int nextIndex;
3106        if (hasActivity) {
3107            final int N = mLruProcesses.size();
3108            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3109                // Process doesn't have activities, but has clients with
3110                // activities...  move it up, but one below the top (the top
3111                // should always have a real activity).
3112                if (DEBUG_LRU) Slog.d(TAG_LRU,
3113                        "Adding to second-top of LRU activity list: " + app);
3114                mLruProcesses.add(N - 1, app);
3115                // To keep it from spamming the LRU list (by making a bunch of clients),
3116                // we will push down any other entries owned by the app.
3117                final int uid = app.info.uid;
3118                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3119                    ProcessRecord subProc = mLruProcesses.get(i);
3120                    if (subProc.info.uid == uid) {
3121                        // We want to push this one down the list.  If the process after
3122                        // it is for the same uid, however, don't do so, because we don't
3123                        // want them internally to be re-ordered.
3124                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3125                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3126                                    "Pushing uid " + uid + " swapping at " + i + ": "
3127                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3128                            ProcessRecord tmp = mLruProcesses.get(i);
3129                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3130                            mLruProcesses.set(i - 1, tmp);
3131                            i--;
3132                        }
3133                    } else {
3134                        // A gap, we can stop here.
3135                        break;
3136                    }
3137                }
3138            } else {
3139                // Process has activities, put it at the very tipsy-top.
3140                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3141                mLruProcesses.add(app);
3142            }
3143            nextIndex = mLruProcessServiceStart;
3144        } else if (hasService) {
3145            // Process has services, put it at the top of the service list.
3146            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3147            mLruProcesses.add(mLruProcessActivityStart, app);
3148            nextIndex = mLruProcessServiceStart;
3149            mLruProcessActivityStart++;
3150        } else  {
3151            // Process not otherwise of interest, it goes to the top of the non-service area.
3152            int index = mLruProcessServiceStart;
3153            if (client != null) {
3154                // If there is a client, don't allow the process to be moved up higher
3155                // in the list than that client.
3156                int clientIndex = mLruProcesses.lastIndexOf(client);
3157                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3158                        + " when updating " + app);
3159                if (clientIndex <= lrui) {
3160                    // Don't allow the client index restriction to push it down farther in the
3161                    // list than it already is.
3162                    clientIndex = lrui;
3163                }
3164                if (clientIndex >= 0 && index > clientIndex) {
3165                    index = clientIndex;
3166                }
3167            }
3168            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3169            mLruProcesses.add(index, app);
3170            nextIndex = index-1;
3171            mLruProcessActivityStart++;
3172            mLruProcessServiceStart++;
3173        }
3174
3175        // If the app is currently using a content provider or service,
3176        // bump those processes as well.
3177        for (int j=app.connections.size()-1; j>=0; j--) {
3178            ConnectionRecord cr = app.connections.valueAt(j);
3179            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3180                    && cr.binding.service.app != null
3181                    && cr.binding.service.app.lruSeq != mLruSeq
3182                    && !cr.binding.service.app.persistent) {
3183                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3184                        "service connection", cr, app);
3185            }
3186        }
3187        for (int j=app.conProviders.size()-1; j>=0; j--) {
3188            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3189            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3190                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3191                        "provider reference", cpr, app);
3192            }
3193        }
3194    }
3195
3196    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3197        if (uid == Process.SYSTEM_UID) {
3198            // The system gets to run in any process.  If there are multiple
3199            // processes with the same uid, just pick the first (this
3200            // should never happen).
3201            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3202            if (procs == null) return null;
3203            final int procCount = procs.size();
3204            for (int i = 0; i < procCount; i++) {
3205                final int procUid = procs.keyAt(i);
3206                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3207                    // Don't use an app process or different user process for system component.
3208                    continue;
3209                }
3210                return procs.valueAt(i);
3211            }
3212        }
3213        ProcessRecord proc = mProcessNames.get(processName, uid);
3214        if (false && proc != null && !keepIfLarge
3215                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3216                && proc.lastCachedPss >= 4000) {
3217            // Turn this condition on to cause killing to happen regularly, for testing.
3218            if (proc.baseProcessTracker != null) {
3219                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3220            }
3221            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3222        } else if (proc != null && !keepIfLarge
3223                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3224                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3225            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3226            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3227                if (proc.baseProcessTracker != null) {
3228                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3229                }
3230                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3231            }
3232        }
3233        return proc;
3234    }
3235
3236    void notifyPackageUse(String packageName) {
3237        IPackageManager pm = AppGlobals.getPackageManager();
3238        try {
3239            pm.notifyPackageUse(packageName);
3240        } catch (RemoteException e) {
3241        }
3242    }
3243
3244    boolean isNextTransitionForward() {
3245        int transit = mWindowManager.getPendingAppTransition();
3246        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3247                || transit == AppTransition.TRANSIT_TASK_OPEN
3248                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3249    }
3250
3251    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3252            String processName, String abiOverride, int uid, Runnable crashHandler) {
3253        synchronized(this) {
3254            ApplicationInfo info = new ApplicationInfo();
3255            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3256            // For isolated processes, the former contains the parent's uid and the latter the
3257            // actual uid of the isolated process.
3258            // In the special case introduced by this method (which is, starting an isolated
3259            // process directly from the SystemServer without an actual parent app process) the
3260            // closest thing to a parent's uid is SYSTEM_UID.
3261            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3262            // the |isolated| logic in the ProcessRecord constructor.
3263            info.uid = Process.SYSTEM_UID;
3264            info.processName = processName;
3265            info.className = entryPoint;
3266            info.packageName = "android";
3267            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3268                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3269                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3270                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3271                    crashHandler);
3272            return proc != null ? proc.pid : 0;
3273        }
3274    }
3275
3276    final ProcessRecord startProcessLocked(String processName,
3277            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3278            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3279            boolean isolated, boolean keepIfLarge) {
3280        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3281                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3282                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3283                null /* crashHandler */);
3284    }
3285
3286    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3287            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3288            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3289            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3290        long startTime = SystemClock.elapsedRealtime();
3291        ProcessRecord app;
3292        if (!isolated) {
3293            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3294            checkTime(startTime, "startProcess: after getProcessRecord");
3295
3296            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3297                // If we are in the background, then check to see if this process
3298                // is bad.  If so, we will just silently fail.
3299                if (mBadProcesses.get(info.processName, info.uid) != null) {
3300                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3301                            + "/" + info.processName);
3302                    return null;
3303                }
3304            } else {
3305                // When the user is explicitly starting a process, then clear its
3306                // crash count so that we won't make it bad until they see at
3307                // least one crash dialog again, and make the process good again
3308                // if it had been bad.
3309                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3310                        + "/" + info.processName);
3311                mProcessCrashTimes.remove(info.processName, info.uid);
3312                if (mBadProcesses.get(info.processName, info.uid) != null) {
3313                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3314                            UserHandle.getUserId(info.uid), info.uid,
3315                            info.processName);
3316                    mBadProcesses.remove(info.processName, info.uid);
3317                    if (app != null) {
3318                        app.bad = false;
3319                    }
3320                }
3321            }
3322        } else {
3323            // If this is an isolated process, it can't re-use an existing process.
3324            app = null;
3325        }
3326
3327        // app launch boost for big.little configurations
3328        // use cpusets to migrate freshly launched tasks to big cores
3329        synchronized(ActivityManagerService.this) {
3330            nativeMigrateToBoost();
3331            mIsBoosted = true;
3332            mBoostStartTime = SystemClock.uptimeMillis();
3333            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3334            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3335        }
3336
3337        // We don't have to do anything more if:
3338        // (1) There is an existing application record; and
3339        // (2) The caller doesn't think it is dead, OR there is no thread
3340        //     object attached to it so we know it couldn't have crashed; and
3341        // (3) There is a pid assigned to it, so it is either starting or
3342        //     already running.
3343        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3344                + " app=" + app + " knownToBeDead=" + knownToBeDead
3345                + " thread=" + (app != null ? app.thread : null)
3346                + " pid=" + (app != null ? app.pid : -1));
3347        if (app != null && app.pid > 0) {
3348            if (!knownToBeDead || app.thread == null) {
3349                // We already have the app running, or are waiting for it to
3350                // come up (we have a pid but not yet its thread), so keep it.
3351                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3352                // If this is a new package in the process, add the package to the list
3353                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3354                checkTime(startTime, "startProcess: done, added package to proc");
3355                return app;
3356            }
3357
3358            // An application record is attached to a previous process,
3359            // clean it up now.
3360            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3361            checkTime(startTime, "startProcess: bad proc running, killing");
3362            killProcessGroup(app.info.uid, app.pid);
3363            handleAppDiedLocked(app, true, true);
3364            checkTime(startTime, "startProcess: done killing old proc");
3365        }
3366
3367        String hostingNameStr = hostingName != null
3368                ? hostingName.flattenToShortString() : null;
3369
3370        if (app == null) {
3371            checkTime(startTime, "startProcess: creating new process record");
3372            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3373            if (app == null) {
3374                Slog.w(TAG, "Failed making new process record for "
3375                        + processName + "/" + info.uid + " isolated=" + isolated);
3376                return null;
3377            }
3378            app.crashHandler = crashHandler;
3379            checkTime(startTime, "startProcess: done creating new process record");
3380        } else {
3381            // If this is a new package in the process, add the package to the list
3382            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3383            checkTime(startTime, "startProcess: added package to existing proc");
3384        }
3385
3386        // If the system is not ready yet, then hold off on starting this
3387        // process until it is.
3388        if (!mProcessesReady
3389                && !isAllowedWhileBooting(info)
3390                && !allowWhileBooting) {
3391            if (!mProcessesOnHold.contains(app)) {
3392                mProcessesOnHold.add(app);
3393            }
3394            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3395                    "System not ready, putting on hold: " + app);
3396            checkTime(startTime, "startProcess: returning with proc on hold");
3397            return app;
3398        }
3399
3400        checkTime(startTime, "startProcess: stepping in to startProcess");
3401        startProcessLocked(
3402                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3403        checkTime(startTime, "startProcess: done starting proc!");
3404        return (app.pid != 0) ? app : null;
3405    }
3406
3407    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3408        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3409    }
3410
3411    private final void startProcessLocked(ProcessRecord app,
3412            String hostingType, String hostingNameStr) {
3413        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3414                null /* entryPoint */, null /* entryPointArgs */);
3415    }
3416
3417    private final void startProcessLocked(ProcessRecord app, String hostingType,
3418            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3419        long startTime = SystemClock.elapsedRealtime();
3420        if (app.pid > 0 && app.pid != MY_PID) {
3421            checkTime(startTime, "startProcess: removing from pids map");
3422            synchronized (mPidsSelfLocked) {
3423                mPidsSelfLocked.remove(app.pid);
3424                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3425            }
3426            checkTime(startTime, "startProcess: done removing from pids map");
3427            app.setPid(0);
3428        }
3429
3430        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3431                "startProcessLocked removing on hold: " + app);
3432        mProcessesOnHold.remove(app);
3433
3434        checkTime(startTime, "startProcess: starting to update cpu stats");
3435        updateCpuStats();
3436        checkTime(startTime, "startProcess: done updating cpu stats");
3437
3438        try {
3439            try {
3440                final int userId = UserHandle.getUserId(app.uid);
3441                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3442            } catch (RemoteException e) {
3443                throw e.rethrowAsRuntimeException();
3444            }
3445
3446            int uid = app.uid;
3447            int[] gids = null;
3448            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3449            if (!app.isolated) {
3450                int[] permGids = null;
3451                try {
3452                    checkTime(startTime, "startProcess: getting gids from package manager");
3453                    final IPackageManager pm = AppGlobals.getPackageManager();
3454                    permGids = pm.getPackageGids(app.info.packageName,
3455                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3456                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3457                            MountServiceInternal.class);
3458                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3459                            app.info.packageName);
3460                } catch (RemoteException e) {
3461                    throw e.rethrowAsRuntimeException();
3462                }
3463
3464                /*
3465                 * Add shared application and profile GIDs so applications can share some
3466                 * resources like shared libraries and access user-wide resources
3467                 */
3468                if (ArrayUtils.isEmpty(permGids)) {
3469                    gids = new int[2];
3470                } else {
3471                    gids = new int[permGids.length + 2];
3472                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3473                }
3474                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3475                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3476            }
3477            checkTime(startTime, "startProcess: building args");
3478            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3479                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3480                        && mTopComponent != null
3481                        && app.processName.equals(mTopComponent.getPackageName())) {
3482                    uid = 0;
3483                }
3484                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3485                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3486                    uid = 0;
3487                }
3488            }
3489            int debugFlags = 0;
3490            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3491                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3492                // Also turn on CheckJNI for debuggable apps. It's quite
3493                // awkward to turn on otherwise.
3494                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3495            }
3496            // Run the app in safe mode if its manifest requests so or the
3497            // system is booted in safe mode.
3498            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3499                mSafeMode == true) {
3500                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3501            }
3502            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3503                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3504            }
3505            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3506            if ("true".equals(genDebugInfoProperty)) {
3507                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3508            }
3509            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3510                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3511            }
3512            if ("1".equals(SystemProperties.get("debug.assert"))) {
3513                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3514            }
3515
3516            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3517            if (requiredAbi == null) {
3518                requiredAbi = Build.SUPPORTED_ABIS[0];
3519            }
3520
3521            String instructionSet = null;
3522            if (app.info.primaryCpuAbi != null) {
3523                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3524            }
3525
3526            app.gids = gids;
3527            app.requiredAbi = requiredAbi;
3528            app.instructionSet = instructionSet;
3529
3530            // Start the process.  It will either succeed and return a result containing
3531            // the PID of the new process, or else throw a RuntimeException.
3532            boolean isActivityProcess = (entryPoint == null);
3533            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3534            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3535                    app.processName);
3536            checkTime(startTime, "startProcess: asking zygote to start proc");
3537            Process.ProcessStartResult startResult = Process.start(entryPoint,
3538                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3539                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3540                    app.info.dataDir, entryPointArgs);
3541            checkTime(startTime, "startProcess: returned from zygote!");
3542            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3543
3544            if (app.isolated) {
3545                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3546            }
3547            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3548            checkTime(startTime, "startProcess: done updating battery stats");
3549
3550            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3551                    UserHandle.getUserId(uid), startResult.pid, uid,
3552                    app.processName, hostingType,
3553                    hostingNameStr != null ? hostingNameStr : "");
3554
3555            if (app.persistent) {
3556                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3557            }
3558
3559            if (DEBUG_PROCESSES) {
3560                checkTime(startTime, "startProcess: building log message");
3561                StringBuilder buf = mStringBuilder;
3562                buf.setLength(0);
3563                buf.append("Start proc ");
3564                buf.append(startResult.pid);
3565                buf.append(':');
3566                buf.append(app.processName);
3567                buf.append('/');
3568                UserHandle.formatUid(buf, uid);
3569                if (!isActivityProcess) {
3570                    buf.append(" [");
3571                    buf.append(entryPoint);
3572                    buf.append("]");
3573                }
3574                buf.append(" for ");
3575                buf.append(hostingType);
3576                if (hostingNameStr != null) {
3577                    buf.append(" ");
3578                    buf.append(hostingNameStr);
3579                }
3580                Slog.i(TAG, buf.toString());
3581            }
3582            app.setPid(startResult.pid);
3583            app.usingWrapper = startResult.usingWrapper;
3584            app.removed = false;
3585            app.killed = false;
3586            app.killedByAm = false;
3587            checkTime(startTime, "startProcess: starting to update pids map");
3588            synchronized (mPidsSelfLocked) {
3589                this.mPidsSelfLocked.put(startResult.pid, app);
3590                if (isActivityProcess) {
3591                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3592                    msg.obj = app;
3593                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3594                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3595                }
3596            }
3597            checkTime(startTime, "startProcess: done updating pids map");
3598        } catch (RuntimeException e) {
3599            // XXX do better error recovery.
3600            app.setPid(0);
3601            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3602            if (app.isolated) {
3603                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3604            }
3605            Slog.e(TAG, "Failure starting process " + app.processName, e);
3606        }
3607    }
3608
3609    void updateUsageStats(ActivityRecord component, boolean resumed) {
3610        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3611                "updateUsageStats: comp=" + component + "res=" + resumed);
3612        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3613        if (resumed) {
3614            if (mUsageStatsService != null) {
3615                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3616                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3617            }
3618            synchronized (stats) {
3619                stats.noteActivityResumedLocked(component.app.uid);
3620            }
3621        } else {
3622            if (mUsageStatsService != null) {
3623                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3624                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3625            }
3626            synchronized (stats) {
3627                stats.noteActivityPausedLocked(component.app.uid);
3628            }
3629        }
3630    }
3631
3632    Intent getHomeIntent() {
3633        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3634        intent.setComponent(mTopComponent);
3635        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3636        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3637            intent.addCategory(Intent.CATEGORY_HOME);
3638        }
3639        return intent;
3640    }
3641
3642    boolean startHomeActivityLocked(int userId, String reason) {
3643        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3644                && mTopAction == null) {
3645            // We are running in factory test mode, but unable to find
3646            // the factory test app, so just sit around displaying the
3647            // error message and don't try to start anything.
3648            return false;
3649        }
3650        Intent intent = getHomeIntent();
3651        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3652        if (aInfo != null) {
3653            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3654            // Don't do this if the home app is currently being
3655            // instrumented.
3656            aInfo = new ActivityInfo(aInfo);
3657            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3658            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3659                    aInfo.applicationInfo.uid, true);
3660            if (app == null || app.instrumentationClass == null) {
3661                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3662                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3663            }
3664        }
3665
3666        return true;
3667    }
3668
3669    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3670        ActivityInfo ai = null;
3671        ComponentName comp = intent.getComponent();
3672        try {
3673            if (comp != null) {
3674                // Factory test.
3675                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3676            } else {
3677                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3678                        intent,
3679                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3680                        flags, userId);
3681
3682                if (info != null) {
3683                    ai = info.activityInfo;
3684                }
3685            }
3686        } catch (RemoteException e) {
3687            // ignore
3688        }
3689
3690        return ai;
3691    }
3692
3693    /**
3694     * Starts the "new version setup screen" if appropriate.
3695     */
3696    void startSetupActivityLocked() {
3697        // Only do this once per boot.
3698        if (mCheckedForSetup) {
3699            return;
3700        }
3701
3702        // We will show this screen if the current one is a different
3703        // version than the last one shown, and we are not running in
3704        // low-level factory test mode.
3705        final ContentResolver resolver = mContext.getContentResolver();
3706        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3707                Settings.Global.getInt(resolver,
3708                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3709            mCheckedForSetup = true;
3710
3711            // See if we should be showing the platform update setup UI.
3712            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3713            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3714                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3715            if (!ris.isEmpty()) {
3716                final ResolveInfo ri = ris.get(0);
3717                String vers = ri.activityInfo.metaData != null
3718                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3719                        : null;
3720                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3721                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3722                            Intent.METADATA_SETUP_VERSION);
3723                }
3724                String lastVers = Settings.Secure.getString(
3725                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3726                if (vers != null && !vers.equals(lastVers)) {
3727                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3728                    intent.setComponent(new ComponentName(
3729                            ri.activityInfo.packageName, ri.activityInfo.name));
3730                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3731                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3732                            null, 0, 0, 0, null, false, false, null, null, null);
3733                }
3734            }
3735        }
3736    }
3737
3738    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3739        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3740    }
3741
3742    void enforceNotIsolatedCaller(String caller) {
3743        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3744            throw new SecurityException("Isolated process not allowed to call " + caller);
3745        }
3746    }
3747
3748    void enforceShellRestriction(String restriction, int userHandle) {
3749        if (Binder.getCallingUid() == Process.SHELL_UID) {
3750            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3751                throw new SecurityException("Shell does not have permission to access user "
3752                        + userHandle);
3753            }
3754        }
3755    }
3756
3757    @Override
3758    public int getFrontActivityScreenCompatMode() {
3759        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3760        synchronized (this) {
3761            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3762        }
3763    }
3764
3765    @Override
3766    public void setFrontActivityScreenCompatMode(int mode) {
3767        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3768                "setFrontActivityScreenCompatMode");
3769        synchronized (this) {
3770            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3771        }
3772    }
3773
3774    @Override
3775    public int getPackageScreenCompatMode(String packageName) {
3776        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3777        synchronized (this) {
3778            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3779        }
3780    }
3781
3782    @Override
3783    public void setPackageScreenCompatMode(String packageName, int mode) {
3784        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3785                "setPackageScreenCompatMode");
3786        synchronized (this) {
3787            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3788        }
3789    }
3790
3791    @Override
3792    public boolean getPackageAskScreenCompat(String packageName) {
3793        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3794        synchronized (this) {
3795            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3796        }
3797    }
3798
3799    @Override
3800    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3801        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3802                "setPackageAskScreenCompat");
3803        synchronized (this) {
3804            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3805        }
3806    }
3807
3808    private boolean hasUsageStatsPermission(String callingPackage) {
3809        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3810                Binder.getCallingUid(), callingPackage);
3811        if (mode == AppOpsManager.MODE_DEFAULT) {
3812            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3813                    == PackageManager.PERMISSION_GRANTED;
3814        }
3815        return mode == AppOpsManager.MODE_ALLOWED;
3816    }
3817
3818    @Override
3819    public int getPackageProcessState(String packageName, String callingPackage) {
3820        if (!hasUsageStatsPermission(callingPackage)) {
3821            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3822                    "getPackageProcessState");
3823        }
3824
3825        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3826        synchronized (this) {
3827            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3828                final ProcessRecord proc = mLruProcesses.get(i);
3829                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3830                        || procState > proc.setProcState) {
3831                    boolean found = false;
3832                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3833                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3834                            procState = proc.setProcState;
3835                            found = true;
3836                        }
3837                    }
3838                    if (proc.pkgDeps != null && !found) {
3839                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3840                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3841                                procState = proc.setProcState;
3842                                break;
3843                            }
3844                        }
3845                    }
3846                }
3847            }
3848        }
3849        return procState;
3850    }
3851
3852    @Override
3853    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3854        synchronized (this) {
3855            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3856            if (app == null) {
3857                return false;
3858            }
3859            if (app.trimMemoryLevel < level && app.thread != null &&
3860                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3861                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3862                try {
3863                    app.thread.scheduleTrimMemory(level);
3864                    app.trimMemoryLevel = level;
3865                    return true;
3866                } catch (RemoteException e) {
3867                    // Fallthrough to failure case.
3868                }
3869            }
3870        }
3871        return false;
3872    }
3873
3874    private void dispatchProcessesChanged() {
3875        int N;
3876        synchronized (this) {
3877            N = mPendingProcessChanges.size();
3878            if (mActiveProcessChanges.length < N) {
3879                mActiveProcessChanges = new ProcessChangeItem[N];
3880            }
3881            mPendingProcessChanges.toArray(mActiveProcessChanges);
3882            mPendingProcessChanges.clear();
3883            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3884                    "*** Delivering " + N + " process changes");
3885        }
3886
3887        int i = mProcessObservers.beginBroadcast();
3888        while (i > 0) {
3889            i--;
3890            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3891            if (observer != null) {
3892                try {
3893                    for (int j=0; j<N; j++) {
3894                        ProcessChangeItem item = mActiveProcessChanges[j];
3895                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3896                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3897                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3898                                    + item.uid + ": " + item.foregroundActivities);
3899                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3900                                    item.foregroundActivities);
3901                        }
3902                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3903                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3904                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3905                                    + ": " + item.processState);
3906                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3907                        }
3908                    }
3909                } catch (RemoteException e) {
3910                }
3911            }
3912        }
3913        mProcessObservers.finishBroadcast();
3914
3915        synchronized (this) {
3916            for (int j=0; j<N; j++) {
3917                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3918            }
3919        }
3920    }
3921
3922    private void dispatchProcessDied(int pid, int uid) {
3923        int i = mProcessObservers.beginBroadcast();
3924        while (i > 0) {
3925            i--;
3926            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3927            if (observer != null) {
3928                try {
3929                    observer.onProcessDied(pid, uid);
3930                } catch (RemoteException e) {
3931                }
3932            }
3933        }
3934        mProcessObservers.finishBroadcast();
3935    }
3936
3937    private void dispatchUidsChanged() {
3938        int N;
3939        synchronized (this) {
3940            N = mPendingUidChanges.size();
3941            if (mActiveUidChanges.length < N) {
3942                mActiveUidChanges = new UidRecord.ChangeItem[N];
3943            }
3944            for (int i=0; i<N; i++) {
3945                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3946                mActiveUidChanges[i] = change;
3947                if (change.uidRecord != null) {
3948                    change.uidRecord.pendingChange = null;
3949                    change.uidRecord = null;
3950                }
3951            }
3952            mPendingUidChanges.clear();
3953            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3954                    "*** Delivering " + N + " uid changes");
3955        }
3956
3957        if (mLocalPowerManager != null) {
3958            for (int j=0; j<N; j++) {
3959                UidRecord.ChangeItem item = mActiveUidChanges[j];
3960                if (item.change == UidRecord.CHANGE_GONE
3961                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3962                    mLocalPowerManager.uidGone(item.uid);
3963                } else {
3964                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3965                }
3966            }
3967        }
3968
3969        int i = mUidObservers.beginBroadcast();
3970        while (i > 0) {
3971            i--;
3972            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3973            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3974            if (observer != null) {
3975                try {
3976                    for (int j=0; j<N; j++) {
3977                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3978                        final int change = item.change;
3979                        UidRecord validateUid = null;
3980                        if (VALIDATE_UID_STATES && i == 0) {
3981                            validateUid = mValidateUids.get(item.uid);
3982                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3983                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3984                                validateUid = new UidRecord(item.uid);
3985                                mValidateUids.put(item.uid, validateUid);
3986                            }
3987                        }
3988                        if (change == UidRecord.CHANGE_IDLE
3989                                || change == UidRecord.CHANGE_GONE_IDLE) {
3990                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3991                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3992                                        "UID idle uid=" + item.uid);
3993                                observer.onUidIdle(item.uid);
3994                            }
3995                            if (VALIDATE_UID_STATES && i == 0) {
3996                                if (validateUid != null) {
3997                                    validateUid.idle = true;
3998                                }
3999                            }
4000                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4001                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4002                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4003                                        "UID active uid=" + item.uid);
4004                                observer.onUidActive(item.uid);
4005                            }
4006                            if (VALIDATE_UID_STATES && i == 0) {
4007                                validateUid.idle = false;
4008                            }
4009                        }
4010                        if (change == UidRecord.CHANGE_GONE
4011                                || change == UidRecord.CHANGE_GONE_IDLE) {
4012                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4013                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4014                                        "UID gone uid=" + item.uid);
4015                                observer.onUidGone(item.uid);
4016                            }
4017                            if (VALIDATE_UID_STATES && i == 0) {
4018                                if (validateUid != null) {
4019                                    mValidateUids.remove(item.uid);
4020                                }
4021                            }
4022                        } else {
4023                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4024                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4025                                        "UID CHANGED uid=" + item.uid
4026                                                + ": " + item.processState);
4027                                observer.onUidStateChanged(item.uid, item.processState);
4028                            }
4029                            if (VALIDATE_UID_STATES && i == 0) {
4030                                validateUid.curProcState = validateUid.setProcState
4031                                        = item.processState;
4032                            }
4033                        }
4034                    }
4035                } catch (RemoteException e) {
4036                }
4037            }
4038        }
4039        mUidObservers.finishBroadcast();
4040
4041        synchronized (this) {
4042            for (int j=0; j<N; j++) {
4043                mAvailUidChanges.add(mActiveUidChanges[j]);
4044            }
4045        }
4046    }
4047
4048    @Override
4049    public final int startActivity(IApplicationThread caller, String callingPackage,
4050            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4051            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4052        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4053                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4054                UserHandle.getCallingUserId());
4055    }
4056
4057    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4058        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4059        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4060                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4061                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4062
4063        // TODO: Switch to user app stacks here.
4064        String mimeType = intent.getType();
4065        final Uri data = intent.getData();
4066        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4067            mimeType = getProviderMimeType(data, userId);
4068        }
4069        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4070
4071        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4072        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4073                null, 0, 0, null, null, null, null, false, userId, container, null);
4074    }
4075
4076    @Override
4077    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4078            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4079            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4080        enforceNotIsolatedCaller("startActivity");
4081        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4082                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4083        // TODO: Switch to user app stacks here.
4084        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4085                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4086                profilerInfo, null, null, bOptions, false, userId, null, null);
4087    }
4088
4089    @Override
4090    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4091            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4092            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4093            int userId) {
4094
4095        // This is very dangerous -- it allows you to perform a start activity (including
4096        // permission grants) as any app that may launch one of your own activities.  So
4097        // we will only allow this to be done from activities that are part of the core framework,
4098        // and then only when they are running as the system.
4099        final ActivityRecord sourceRecord;
4100        final int targetUid;
4101        final String targetPackage;
4102        synchronized (this) {
4103            if (resultTo == null) {
4104                throw new SecurityException("Must be called from an activity");
4105            }
4106            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4107            if (sourceRecord == null) {
4108                throw new SecurityException("Called with bad activity token: " + resultTo);
4109            }
4110            if (!sourceRecord.info.packageName.equals("android")) {
4111                throw new SecurityException(
4112                        "Must be called from an activity that is declared in the android package");
4113            }
4114            if (sourceRecord.app == null) {
4115                throw new SecurityException("Called without a process attached to activity");
4116            }
4117            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4118                // This is still okay, as long as this activity is running under the
4119                // uid of the original calling activity.
4120                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4121                    throw new SecurityException(
4122                            "Calling activity in uid " + sourceRecord.app.uid
4123                                    + " must be system uid or original calling uid "
4124                                    + sourceRecord.launchedFromUid);
4125                }
4126            }
4127            if (ignoreTargetSecurity) {
4128                if (intent.getComponent() == null) {
4129                    throw new SecurityException(
4130                            "Component must be specified with ignoreTargetSecurity");
4131                }
4132                if (intent.getSelector() != null) {
4133                    throw new SecurityException(
4134                            "Selector not allowed with ignoreTargetSecurity");
4135                }
4136            }
4137            targetUid = sourceRecord.launchedFromUid;
4138            targetPackage = sourceRecord.launchedFromPackage;
4139        }
4140
4141        if (userId == UserHandle.USER_NULL) {
4142            userId = UserHandle.getUserId(sourceRecord.app.uid);
4143        }
4144
4145        // TODO: Switch to user app stacks here.
4146        try {
4147            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4148                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4149                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4150            return ret;
4151        } catch (SecurityException e) {
4152            // XXX need to figure out how to propagate to original app.
4153            // A SecurityException here is generally actually a fault of the original
4154            // calling activity (such as a fairly granting permissions), so propagate it
4155            // back to them.
4156            /*
4157            StringBuilder msg = new StringBuilder();
4158            msg.append("While launching");
4159            msg.append(intent.toString());
4160            msg.append(": ");
4161            msg.append(e.getMessage());
4162            */
4163            throw e;
4164        }
4165    }
4166
4167    @Override
4168    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4169            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4170            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4171        enforceNotIsolatedCaller("startActivityAndWait");
4172        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4173                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4174        WaitResult res = new WaitResult();
4175        // TODO: Switch to user app stacks here.
4176        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4177                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4178                bOptions, false, userId, null, null);
4179        return res;
4180    }
4181
4182    @Override
4183    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4184            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4185            int startFlags, Configuration config, Bundle bOptions, int userId) {
4186        enforceNotIsolatedCaller("startActivityWithConfig");
4187        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4188                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4189        // TODO: Switch to user app stacks here.
4190        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4191                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4192                null, null, config, bOptions, false, userId, null, null);
4193        return ret;
4194    }
4195
4196    @Override
4197    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4198            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4199            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4200            throws TransactionTooLargeException {
4201        enforceNotIsolatedCaller("startActivityIntentSender");
4202        // Refuse possible leaked file descriptors
4203        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4204            throw new IllegalArgumentException("File descriptors passed in Intent");
4205        }
4206
4207        IIntentSender sender = intent.getTarget();
4208        if (!(sender instanceof PendingIntentRecord)) {
4209            throw new IllegalArgumentException("Bad PendingIntent object");
4210        }
4211
4212        PendingIntentRecord pir = (PendingIntentRecord)sender;
4213
4214        synchronized (this) {
4215            // If this is coming from the currently resumed activity, it is
4216            // effectively saying that app switches are allowed at this point.
4217            final ActivityStack stack = getFocusedStack();
4218            if (stack.mResumedActivity != null &&
4219                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4220                mAppSwitchesAllowedTime = 0;
4221            }
4222        }
4223        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4224                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4225        return ret;
4226    }
4227
4228    @Override
4229    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4230            Intent intent, String resolvedType, IVoiceInteractionSession session,
4231            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4232            Bundle bOptions, int userId) {
4233        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4234                != PackageManager.PERMISSION_GRANTED) {
4235            String msg = "Permission Denial: startVoiceActivity() from pid="
4236                    + Binder.getCallingPid()
4237                    + ", uid=" + Binder.getCallingUid()
4238                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4239            Slog.w(TAG, msg);
4240            throw new SecurityException(msg);
4241        }
4242        if (session == null || interactor == null) {
4243            throw new NullPointerException("null session or interactor");
4244        }
4245        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4246                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4247        // TODO: Switch to user app stacks here.
4248        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4249                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4250                null, bOptions, false, userId, null, null);
4251    }
4252
4253    @Override
4254    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4255        synchronized (this) {
4256            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4257                if (keepAwake) {
4258                    mVoiceWakeLock.acquire();
4259                } else {
4260                    mVoiceWakeLock.release();
4261                }
4262            }
4263        }
4264    }
4265
4266    @Override
4267    public boolean startNextMatchingActivity(IBinder callingActivity,
4268            Intent intent, Bundle bOptions) {
4269        // Refuse possible leaked file descriptors
4270        if (intent != null && intent.hasFileDescriptors() == true) {
4271            throw new IllegalArgumentException("File descriptors passed in Intent");
4272        }
4273        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4274
4275        synchronized (this) {
4276            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4277            if (r == null) {
4278                ActivityOptions.abort(options);
4279                return false;
4280            }
4281            if (r.app == null || r.app.thread == null) {
4282                // The caller is not running...  d'oh!
4283                ActivityOptions.abort(options);
4284                return false;
4285            }
4286            intent = new Intent(intent);
4287            // The caller is not allowed to change the data.
4288            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4289            // And we are resetting to find the next component...
4290            intent.setComponent(null);
4291
4292            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4293
4294            ActivityInfo aInfo = null;
4295            try {
4296                List<ResolveInfo> resolves =
4297                    AppGlobals.getPackageManager().queryIntentActivities(
4298                            intent, r.resolvedType,
4299                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4300                            UserHandle.getCallingUserId());
4301
4302                // Look for the original activity in the list...
4303                final int N = resolves != null ? resolves.size() : 0;
4304                for (int i=0; i<N; i++) {
4305                    ResolveInfo rInfo = resolves.get(i);
4306                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4307                            && rInfo.activityInfo.name.equals(r.info.name)) {
4308                        // We found the current one...  the next matching is
4309                        // after it.
4310                        i++;
4311                        if (i<N) {
4312                            aInfo = resolves.get(i).activityInfo;
4313                        }
4314                        if (debug) {
4315                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4316                                    + "/" + r.info.name);
4317                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4318                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4319                        }
4320                        break;
4321                    }
4322                }
4323            } catch (RemoteException e) {
4324            }
4325
4326            if (aInfo == null) {
4327                // Nobody who is next!
4328                ActivityOptions.abort(options);
4329                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4330                return false;
4331            }
4332
4333            intent.setComponent(new ComponentName(
4334                    aInfo.applicationInfo.packageName, aInfo.name));
4335            intent.setFlags(intent.getFlags()&~(
4336                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4337                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4338                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4339                    Intent.FLAG_ACTIVITY_NEW_TASK));
4340
4341            // Okay now we need to start the new activity, replacing the
4342            // currently running activity.  This is a little tricky because
4343            // we want to start the new one as if the current one is finished,
4344            // but not finish the current one first so that there is no flicker.
4345            // And thus...
4346            final boolean wasFinishing = r.finishing;
4347            r.finishing = true;
4348
4349            // Propagate reply information over to the new activity.
4350            final ActivityRecord resultTo = r.resultTo;
4351            final String resultWho = r.resultWho;
4352            final int requestCode = r.requestCode;
4353            r.resultTo = null;
4354            if (resultTo != null) {
4355                resultTo.removeResultsLocked(r, resultWho, requestCode);
4356            }
4357
4358            final long origId = Binder.clearCallingIdentity();
4359            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4360                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4361                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4362                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4363                    false, false, null, null, null);
4364            Binder.restoreCallingIdentity(origId);
4365
4366            r.finishing = wasFinishing;
4367            if (res != ActivityManager.START_SUCCESS) {
4368                return false;
4369            }
4370            return true;
4371        }
4372    }
4373
4374    @Override
4375    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4376        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4377            String msg = "Permission Denial: startActivityFromRecents called without " +
4378                    START_TASKS_FROM_RECENTS;
4379            Slog.w(TAG, msg);
4380            throw new SecurityException(msg);
4381        }
4382        final long origId = Binder.clearCallingIdentity();
4383        try {
4384            return startActivityFromRecentsInner(taskId, bOptions);
4385        } finally {
4386            Binder.restoreCallingIdentity(origId);
4387        }
4388    }
4389
4390    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4391        final TaskRecord task;
4392        final int callingUid;
4393        final String callingPackage;
4394        final Intent intent;
4395        final int userId;
4396        synchronized (this) {
4397            final ActivityOptions activityOptions = (bOptions != null)
4398                    ? new ActivityOptions(bOptions) : null;
4399            final int launchStackId = (activityOptions != null)
4400                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4401
4402            if (launchStackId == HOME_STACK_ID) {
4403                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4404                        + taskId + " can't be launch in the home stack.");
4405            }
4406            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4407            if (task == null) {
4408                throw new IllegalArgumentException(
4409                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4410            }
4411
4412            if (launchStackId != INVALID_STACK_ID) {
4413                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4414                    mWindowManager.setDockedStackCreateState(
4415                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4416                }
4417                if (task.stack.mStackId != launchStackId) {
4418                    mStackSupervisor.moveTaskToStackLocked(
4419                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4420                            ANIMATE);
4421                }
4422            }
4423
4424            // If the user must confirm credentials (e.g. when first launching a work app and the
4425            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4426            if (!mUserController.shouldConfirmCredentials(task.userId)
4427                    && task.getRootActivity() != null) {
4428                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4429                return ActivityManager.START_TASK_TO_FRONT;
4430            }
4431            callingUid = task.mCallingUid;
4432            callingPackage = task.mCallingPackage;
4433            intent = task.intent;
4434            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4435            userId = task.userId;
4436        }
4437        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4438                bOptions, userId, null, task);
4439    }
4440
4441    final int startActivityInPackage(int uid, String callingPackage,
4442            Intent intent, String resolvedType, IBinder resultTo,
4443            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4444            IActivityContainer container, TaskRecord inTask) {
4445
4446        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4447                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4448
4449        // TODO: Switch to user app stacks here.
4450        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4451                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4452                null, null, null, bOptions, false, userId, container, inTask);
4453        return ret;
4454    }
4455
4456    @Override
4457    public final int startActivities(IApplicationThread caller, String callingPackage,
4458            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4459            int userId) {
4460        enforceNotIsolatedCaller("startActivities");
4461        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4462                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4463        // TODO: Switch to user app stacks here.
4464        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4465                resolvedTypes, resultTo, bOptions, userId);
4466        return ret;
4467    }
4468
4469    final int startActivitiesInPackage(int uid, String callingPackage,
4470            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4471            Bundle bOptions, int userId) {
4472
4473        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4474                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4475        // TODO: Switch to user app stacks here.
4476        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4477                resultTo, bOptions, userId);
4478        return ret;
4479    }
4480
4481    @Override
4482    public void reportActivityFullyDrawn(IBinder token) {
4483        synchronized (this) {
4484            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4485            if (r == null) {
4486                return;
4487            }
4488            r.reportFullyDrawnLocked();
4489        }
4490    }
4491
4492    @Override
4493    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4494        synchronized (this) {
4495            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4496            if (r == null) {
4497                return;
4498            }
4499            TaskRecord task = r.task;
4500            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4501                // Fixed screen orientation isn't supported when activities aren't in full screen
4502                // mode.
4503                return;
4504            }
4505            final long origId = Binder.clearCallingIdentity();
4506            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4507            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4508                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4509            if (config != null) {
4510                r.frozenBeforeDestroy = true;
4511                if (!updateConfigurationLocked(config, r, false)) {
4512                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4513                }
4514            }
4515            Binder.restoreCallingIdentity(origId);
4516        }
4517    }
4518
4519    @Override
4520    public int getRequestedOrientation(IBinder token) {
4521        synchronized (this) {
4522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4523            if (r == null) {
4524                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4525            }
4526            return mWindowManager.getAppOrientation(r.appToken);
4527        }
4528    }
4529
4530    /**
4531     * This is the internal entry point for handling Activity.finish().
4532     *
4533     * @param token The Binder token referencing the Activity we want to finish.
4534     * @param resultCode Result code, if any, from this Activity.
4535     * @param resultData Result data (Intent), if any, from this Activity.
4536     * @param finishTask Whether to finish the task associated with this Activity.
4537     *
4538     * @return Returns true if the activity successfully finished, or false if it is still running.
4539     */
4540    @Override
4541    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4542            int finishTask) {
4543        // Refuse possible leaked file descriptors
4544        if (resultData != null && resultData.hasFileDescriptors() == true) {
4545            throw new IllegalArgumentException("File descriptors passed in Intent");
4546        }
4547
4548        synchronized(this) {
4549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4550            if (r == null) {
4551                return true;
4552            }
4553            // Keep track of the root activity of the task before we finish it
4554            TaskRecord tr = r.task;
4555            ActivityRecord rootR = tr.getRootActivity();
4556            if (rootR == null) {
4557                Slog.w(TAG, "Finishing task with all activities already finished");
4558            }
4559            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4560            // finish.
4561            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4562                    mStackSupervisor.isLastLockedTask(tr)) {
4563                Slog.i(TAG, "Not finishing task in lock task mode");
4564                mStackSupervisor.showLockTaskToast();
4565                return false;
4566            }
4567            if (mController != null) {
4568                // Find the first activity that is not finishing.
4569                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4570                if (next != null) {
4571                    // ask watcher if this is allowed
4572                    boolean resumeOK = true;
4573                    try {
4574                        resumeOK = mController.activityResuming(next.packageName);
4575                    } catch (RemoteException e) {
4576                        mController = null;
4577                        Watchdog.getInstance().setActivityController(null);
4578                    }
4579
4580                    if (!resumeOK) {
4581                        Slog.i(TAG, "Not finishing activity because controller resumed");
4582                        return false;
4583                    }
4584                }
4585            }
4586            final long origId = Binder.clearCallingIdentity();
4587            try {
4588                boolean res;
4589                final boolean finishWithRootActivity =
4590                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4591                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4592                        || (finishWithRootActivity && r == rootR)) {
4593                    // If requested, remove the task that is associated to this activity only if it
4594                    // was the root activity in the task. The result code and data is ignored
4595                    // because we don't support returning them across task boundaries. Also, to
4596                    // keep backwards compatibility we remove the task from recents when finishing
4597                    // task with root activity.
4598                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4599                    if (!res) {
4600                        Slog.i(TAG, "Removing task failed to finish activity");
4601                    }
4602                } else {
4603                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4604                            resultData, "app-request", true);
4605                    if (!res) {
4606                        Slog.i(TAG, "Failed to finish by app-request");
4607                    }
4608                }
4609                return res;
4610            } finally {
4611                Binder.restoreCallingIdentity(origId);
4612            }
4613        }
4614    }
4615
4616    @Override
4617    public final void finishHeavyWeightApp() {
4618        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4619                != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        synchronized(this) {
4629            if (mHeavyWeightProcess == null) {
4630                return;
4631            }
4632
4633            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4634            for (int i = 0; i < activities.size(); i++) {
4635                ActivityRecord r = activities.get(i);
4636                if (!r.finishing && r.isInStackLocked()) {
4637                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4638                            null, "finish-heavy", true);
4639                }
4640            }
4641
4642            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4643                    mHeavyWeightProcess.userId, 0));
4644            mHeavyWeightProcess = null;
4645        }
4646    }
4647
4648    @Override
4649    public void crashApplication(int uid, int initialPid, String packageName,
4650            String message) {
4651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4652                != PackageManager.PERMISSION_GRANTED) {
4653            String msg = "Permission Denial: crashApplication() from pid="
4654                    + Binder.getCallingPid()
4655                    + ", uid=" + Binder.getCallingUid()
4656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4657            Slog.w(TAG, msg);
4658            throw new SecurityException(msg);
4659        }
4660
4661        synchronized(this) {
4662            ProcessRecord proc = null;
4663
4664            // Figure out which process to kill.  We don't trust that initialPid
4665            // still has any relation to current pids, so must scan through the
4666            // list.
4667            synchronized (mPidsSelfLocked) {
4668                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4669                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4670                    if (p.uid != uid) {
4671                        continue;
4672                    }
4673                    if (p.pid == initialPid) {
4674                        proc = p;
4675                        break;
4676                    }
4677                    if (p.pkgList.containsKey(packageName)) {
4678                        proc = p;
4679                    }
4680                }
4681            }
4682
4683            if (proc == null) {
4684                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4685                        + " initialPid=" + initialPid
4686                        + " packageName=" + packageName);
4687                return;
4688            }
4689
4690            if (proc.thread != null) {
4691                if (proc.pid == Process.myPid()) {
4692                    Log.w(TAG, "crashApplication: trying to crash self!");
4693                    return;
4694                }
4695                long ident = Binder.clearCallingIdentity();
4696                try {
4697                    proc.thread.scheduleCrash(message);
4698                } catch (RemoteException e) {
4699                }
4700                Binder.restoreCallingIdentity(ident);
4701            }
4702        }
4703    }
4704
4705    @Override
4706    public final void finishSubActivity(IBinder token, String resultWho,
4707            int requestCode) {
4708        synchronized(this) {
4709            final long origId = Binder.clearCallingIdentity();
4710            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4711            if (r != null) {
4712                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4713            }
4714            Binder.restoreCallingIdentity(origId);
4715        }
4716    }
4717
4718    @Override
4719    public boolean finishActivityAffinity(IBinder token) {
4720        synchronized(this) {
4721            final long origId = Binder.clearCallingIdentity();
4722            try {
4723                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4724                if (r == null) {
4725                    return false;
4726                }
4727
4728                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4729                // can finish.
4730                final TaskRecord task = r.task;
4731                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4732                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4733                    mStackSupervisor.showLockTaskToast();
4734                    return false;
4735                }
4736                return task.stack.finishActivityAffinityLocked(r);
4737            } finally {
4738                Binder.restoreCallingIdentity(origId);
4739            }
4740        }
4741    }
4742
4743    @Override
4744    public void finishVoiceTask(IVoiceInteractionSession session) {
4745        synchronized(this) {
4746            final long origId = Binder.clearCallingIdentity();
4747            try {
4748                mStackSupervisor.finishVoiceTask(session);
4749            } finally {
4750                Binder.restoreCallingIdentity(origId);
4751            }
4752        }
4753
4754    }
4755
4756    @Override
4757    public boolean releaseActivityInstance(IBinder token) {
4758        synchronized(this) {
4759            final long origId = Binder.clearCallingIdentity();
4760            try {
4761                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4762                if (r == null) {
4763                    return false;
4764                }
4765                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4766            } finally {
4767                Binder.restoreCallingIdentity(origId);
4768            }
4769        }
4770    }
4771
4772    @Override
4773    public void releaseSomeActivities(IApplicationThread appInt) {
4774        synchronized(this) {
4775            final long origId = Binder.clearCallingIdentity();
4776            try {
4777                ProcessRecord app = getRecordForAppLocked(appInt);
4778                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4779            } finally {
4780                Binder.restoreCallingIdentity(origId);
4781            }
4782        }
4783    }
4784
4785    @Override
4786    public boolean willActivityBeVisible(IBinder token) {
4787        synchronized(this) {
4788            ActivityStack stack = ActivityRecord.getStackLocked(token);
4789            if (stack != null) {
4790                return stack.willActivityBeVisibleLocked(token);
4791            }
4792            return false;
4793        }
4794    }
4795
4796    @Override
4797    public void overridePendingTransition(IBinder token, String packageName,
4798            int enterAnim, int exitAnim) {
4799        synchronized(this) {
4800            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4801            if (self == null) {
4802                return;
4803            }
4804
4805            final long origId = Binder.clearCallingIdentity();
4806
4807            if (self.state == ActivityState.RESUMED
4808                    || self.state == ActivityState.PAUSING) {
4809                mWindowManager.overridePendingAppTransition(packageName,
4810                        enterAnim, exitAnim, null);
4811            }
4812
4813            Binder.restoreCallingIdentity(origId);
4814        }
4815    }
4816
4817    /**
4818     * Main function for removing an existing process from the activity manager
4819     * as a result of that process going away.  Clears out all connections
4820     * to the process.
4821     */
4822    private final void handleAppDiedLocked(ProcessRecord app,
4823            boolean restarting, boolean allowRestart) {
4824        int pid = app.pid;
4825        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4826        if (!kept && !restarting) {
4827            removeLruProcessLocked(app);
4828            if (pid > 0) {
4829                ProcessList.remove(pid);
4830            }
4831        }
4832
4833        if (mProfileProc == app) {
4834            clearProfilerLocked();
4835        }
4836
4837        // Remove this application's activities from active lists.
4838        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4839
4840        app.activities.clear();
4841
4842        if (app.instrumentationClass != null) {
4843            Slog.w(TAG, "Crash of app " + app.processName
4844                  + " running instrumentation " + app.instrumentationClass);
4845            Bundle info = new Bundle();
4846            info.putString("shortMsg", "Process crashed.");
4847            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4848        }
4849
4850        if (!restarting && hasVisibleActivities
4851                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4852            // If there was nothing to resume, and we are not already restarting this process, but
4853            // there is a visible activity that is hosted by the process...  then make sure all
4854            // visible activities are running, taking care of restarting this process.
4855            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4856        }
4857    }
4858
4859    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4860        IBinder threadBinder = thread.asBinder();
4861        // Find the application record.
4862        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4863            ProcessRecord rec = mLruProcesses.get(i);
4864            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4865                return i;
4866            }
4867        }
4868        return -1;
4869    }
4870
4871    final ProcessRecord getRecordForAppLocked(
4872            IApplicationThread thread) {
4873        if (thread == null) {
4874            return null;
4875        }
4876
4877        int appIndex = getLRURecordIndexForAppLocked(thread);
4878        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4879    }
4880
4881    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4882        // If there are no longer any background processes running,
4883        // and the app that died was not running instrumentation,
4884        // then tell everyone we are now low on memory.
4885        boolean haveBg = false;
4886        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4887            ProcessRecord rec = mLruProcesses.get(i);
4888            if (rec.thread != null
4889                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4890                haveBg = true;
4891                break;
4892            }
4893        }
4894
4895        if (!haveBg) {
4896            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4897            if (doReport) {
4898                long now = SystemClock.uptimeMillis();
4899                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4900                    doReport = false;
4901                } else {
4902                    mLastMemUsageReportTime = now;
4903                }
4904            }
4905            final ArrayList<ProcessMemInfo> memInfos
4906                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4907            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4908            long now = SystemClock.uptimeMillis();
4909            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4910                ProcessRecord rec = mLruProcesses.get(i);
4911                if (rec == dyingProc || rec.thread == null) {
4912                    continue;
4913                }
4914                if (doReport) {
4915                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4916                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4917                }
4918                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4919                    // The low memory report is overriding any current
4920                    // state for a GC request.  Make sure to do
4921                    // heavy/important/visible/foreground processes first.
4922                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4923                        rec.lastRequestedGc = 0;
4924                    } else {
4925                        rec.lastRequestedGc = rec.lastLowMemory;
4926                    }
4927                    rec.reportLowMemory = true;
4928                    rec.lastLowMemory = now;
4929                    mProcessesToGc.remove(rec);
4930                    addProcessToGcListLocked(rec);
4931                }
4932            }
4933            if (doReport) {
4934                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4935                mHandler.sendMessage(msg);
4936            }
4937            scheduleAppGcsLocked();
4938        }
4939    }
4940
4941    final void appDiedLocked(ProcessRecord app) {
4942       appDiedLocked(app, app.pid, app.thread, false);
4943    }
4944
4945    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4946            boolean fromBinderDied) {
4947        // First check if this ProcessRecord is actually active for the pid.
4948        synchronized (mPidsSelfLocked) {
4949            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4950            if (curProc != app) {
4951                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4952                return;
4953            }
4954        }
4955
4956        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4957        synchronized (stats) {
4958            stats.noteProcessDiedLocked(app.info.uid, pid);
4959        }
4960
4961        if (!app.killed) {
4962            if (!fromBinderDied) {
4963                Process.killProcessQuiet(pid);
4964            }
4965            killProcessGroup(app.info.uid, pid);
4966            app.killed = true;
4967        }
4968
4969        // Clean up already done if the process has been re-started.
4970        if (app.pid == pid && app.thread != null &&
4971                app.thread.asBinder() == thread.asBinder()) {
4972            boolean doLowMem = app.instrumentationClass == null;
4973            boolean doOomAdj = doLowMem;
4974            if (!app.killedByAm) {
4975                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4976                        + ") has died");
4977                mAllowLowerMemLevel = true;
4978            } else {
4979                // Note that we always want to do oom adj to update our state with the
4980                // new number of procs.
4981                mAllowLowerMemLevel = false;
4982                doLowMem = false;
4983            }
4984            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4985            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4986                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4987            handleAppDiedLocked(app, false, true);
4988
4989            if (doOomAdj) {
4990                updateOomAdjLocked();
4991            }
4992            if (doLowMem) {
4993                doLowMemReportIfNeededLocked(app);
4994            }
4995        } else if (app.pid != pid) {
4996            // A new process has already been started.
4997            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4998                    + ") has died and restarted (pid " + app.pid + ").");
4999            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5000        } else if (DEBUG_PROCESSES) {
5001            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5002                    + thread.asBinder());
5003        }
5004    }
5005
5006    /**
5007     * If a stack trace dump file is configured, dump process stack traces.
5008     * @param clearTraces causes the dump file to be erased prior to the new
5009     *    traces being written, if true; when false, the new traces will be
5010     *    appended to any existing file content.
5011     * @param firstPids of dalvik VM processes to dump stack traces for first
5012     * @param lastPids of dalvik VM processes to dump stack traces for last
5013     * @param nativeProcs optional list of native process names to dump stack crawls
5014     * @return file containing stack traces, or null if no dump file is configured
5015     */
5016    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5017            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5018        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5019        if (tracesPath == null || tracesPath.length() == 0) {
5020            return null;
5021        }
5022
5023        File tracesFile = new File(tracesPath);
5024        try {
5025            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5026            tracesFile.createNewFile();
5027            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5028        } catch (IOException e) {
5029            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5030            return null;
5031        }
5032
5033        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5034        return tracesFile;
5035    }
5036
5037    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5038            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5039        // Use a FileObserver to detect when traces finish writing.
5040        // The order of traces is considered important to maintain for legibility.
5041        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5042            @Override
5043            public synchronized void onEvent(int event, String path) { notify(); }
5044        };
5045
5046        try {
5047            observer.startWatching();
5048
5049            // First collect all of the stacks of the most important pids.
5050            if (firstPids != null) {
5051                try {
5052                    int num = firstPids.size();
5053                    for (int i = 0; i < num; i++) {
5054                        synchronized (observer) {
5055                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5056                            observer.wait(200);  // Wait for write-close, give up after 200msec
5057                        }
5058                    }
5059                } catch (InterruptedException e) {
5060                    Slog.wtf(TAG, e);
5061                }
5062            }
5063
5064            // Next collect the stacks of the native pids
5065            if (nativeProcs != null) {
5066                int[] pids = Process.getPidsForCommands(nativeProcs);
5067                if (pids != null) {
5068                    for (int pid : pids) {
5069                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5070                    }
5071                }
5072            }
5073
5074            // Lastly, measure CPU usage.
5075            if (processCpuTracker != null) {
5076                processCpuTracker.init();
5077                System.gc();
5078                processCpuTracker.update();
5079                try {
5080                    synchronized (processCpuTracker) {
5081                        processCpuTracker.wait(500); // measure over 1/2 second.
5082                    }
5083                } catch (InterruptedException e) {
5084                }
5085                processCpuTracker.update();
5086
5087                // We'll take the stack crawls of just the top apps using CPU.
5088                final int N = processCpuTracker.countWorkingStats();
5089                int numProcs = 0;
5090                for (int i=0; i<N && numProcs<5; i++) {
5091                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5092                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5093                        numProcs++;
5094                        try {
5095                            synchronized (observer) {
5096                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5097                                observer.wait(200);  // Wait for write-close, give up after 200msec
5098                            }
5099                        } catch (InterruptedException e) {
5100                            Slog.wtf(TAG, e);
5101                        }
5102
5103                    }
5104                }
5105            }
5106        } finally {
5107            observer.stopWatching();
5108        }
5109    }
5110
5111    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5112        if (true || IS_USER_BUILD) {
5113            return;
5114        }
5115        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5116        if (tracesPath == null || tracesPath.length() == 0) {
5117            return;
5118        }
5119
5120        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5121        StrictMode.allowThreadDiskWrites();
5122        try {
5123            final File tracesFile = new File(tracesPath);
5124            final File tracesDir = tracesFile.getParentFile();
5125            final File tracesTmp = new File(tracesDir, "__tmp__");
5126            try {
5127                if (tracesFile.exists()) {
5128                    tracesTmp.delete();
5129                    tracesFile.renameTo(tracesTmp);
5130                }
5131                StringBuilder sb = new StringBuilder();
5132                Time tobj = new Time();
5133                tobj.set(System.currentTimeMillis());
5134                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5135                sb.append(": ");
5136                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5137                sb.append(" since ");
5138                sb.append(msg);
5139                FileOutputStream fos = new FileOutputStream(tracesFile);
5140                fos.write(sb.toString().getBytes());
5141                if (app == null) {
5142                    fos.write("\n*** No application process!".getBytes());
5143                }
5144                fos.close();
5145                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5146            } catch (IOException e) {
5147                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5148                return;
5149            }
5150
5151            if (app != null) {
5152                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5153                firstPids.add(app.pid);
5154                dumpStackTraces(tracesPath, firstPids, null, null, null);
5155            }
5156
5157            File lastTracesFile = null;
5158            File curTracesFile = null;
5159            for (int i=9; i>=0; i--) {
5160                String name = String.format(Locale.US, "slow%02d.txt", i);
5161                curTracesFile = new File(tracesDir, name);
5162                if (curTracesFile.exists()) {
5163                    if (lastTracesFile != null) {
5164                        curTracesFile.renameTo(lastTracesFile);
5165                    } else {
5166                        curTracesFile.delete();
5167                    }
5168                }
5169                lastTracesFile = curTracesFile;
5170            }
5171            tracesFile.renameTo(curTracesFile);
5172            if (tracesTmp.exists()) {
5173                tracesTmp.renameTo(tracesFile);
5174            }
5175        } finally {
5176            StrictMode.setThreadPolicy(oldPolicy);
5177        }
5178    }
5179
5180    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5181            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5182        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5183        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5184
5185        if (mController != null) {
5186            try {
5187                // 0 == continue, -1 = kill process immediately
5188                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5189                if (res < 0 && app.pid != MY_PID) {
5190                    app.kill("anr", true);
5191                }
5192            } catch (RemoteException e) {
5193                mController = null;
5194                Watchdog.getInstance().setActivityController(null);
5195            }
5196        }
5197
5198        long anrTime = SystemClock.uptimeMillis();
5199        if (MONITOR_CPU_USAGE) {
5200            updateCpuStatsNow();
5201        }
5202
5203        synchronized (this) {
5204            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5205            if (mShuttingDown) {
5206                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5207                return;
5208            } else if (app.notResponding) {
5209                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5210                return;
5211            } else if (app.crashing) {
5212                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5213                return;
5214            }
5215
5216            // In case we come through here for the same app before completing
5217            // this one, mark as anring now so we will bail out.
5218            app.notResponding = true;
5219
5220            // Log the ANR to the event log.
5221            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5222                    app.processName, app.info.flags, annotation);
5223
5224            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5225            firstPids.add(app.pid);
5226
5227            int parentPid = app.pid;
5228            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5229            if (parentPid != app.pid) firstPids.add(parentPid);
5230
5231            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5232
5233            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5234                ProcessRecord r = mLruProcesses.get(i);
5235                if (r != null && r.thread != null) {
5236                    int pid = r.pid;
5237                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5238                        if (r.persistent) {
5239                            firstPids.add(pid);
5240                        } else {
5241                            lastPids.put(pid, Boolean.TRUE);
5242                        }
5243                    }
5244                }
5245            }
5246        }
5247
5248        // Log the ANR to the main log.
5249        StringBuilder info = new StringBuilder();
5250        info.setLength(0);
5251        info.append("ANR in ").append(app.processName);
5252        if (activity != null && activity.shortComponentName != null) {
5253            info.append(" (").append(activity.shortComponentName).append(")");
5254        }
5255        info.append("\n");
5256        info.append("PID: ").append(app.pid).append("\n");
5257        if (annotation != null) {
5258            info.append("Reason: ").append(annotation).append("\n");
5259        }
5260        if (parent != null && parent != activity) {
5261            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5262        }
5263
5264        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5265
5266        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5267                NATIVE_STACKS_OF_INTEREST);
5268
5269        String cpuInfo = null;
5270        if (MONITOR_CPU_USAGE) {
5271            updateCpuStatsNow();
5272            synchronized (mProcessCpuTracker) {
5273                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5274            }
5275            info.append(processCpuTracker.printCurrentLoad());
5276            info.append(cpuInfo);
5277        }
5278
5279        info.append(processCpuTracker.printCurrentState(anrTime));
5280
5281        Slog.e(TAG, info.toString());
5282        if (tracesFile == null) {
5283            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5284            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5285        }
5286
5287        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5288                cpuInfo, tracesFile, null);
5289
5290        if (mController != null) {
5291            try {
5292                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5293                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5294                if (res != 0) {
5295                    if (res < 0 && app.pid != MY_PID) {
5296                        app.kill("anr", true);
5297                    } else {
5298                        synchronized (this) {
5299                            mServices.scheduleServiceTimeoutLocked(app);
5300                        }
5301                    }
5302                    return;
5303                }
5304            } catch (RemoteException e) {
5305                mController = null;
5306                Watchdog.getInstance().setActivityController(null);
5307            }
5308        }
5309
5310        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5311        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5312                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5313
5314        synchronized (this) {
5315            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5316
5317            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5318                app.kill("bg anr", true);
5319                return;
5320            }
5321
5322            // Set the app's notResponding state, and look up the errorReportReceiver
5323            makeAppNotRespondingLocked(app,
5324                    activity != null ? activity.shortComponentName : null,
5325                    annotation != null ? "ANR " + annotation : "ANR",
5326                    info.toString());
5327
5328            // Bring up the infamous App Not Responding dialog
5329            Message msg = Message.obtain();
5330            HashMap<String, Object> map = new HashMap<String, Object>();
5331            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5332            msg.obj = map;
5333            msg.arg1 = aboveSystem ? 1 : 0;
5334            map.put("app", app);
5335            if (activity != null) {
5336                map.put("activity", activity);
5337            }
5338
5339            mUiHandler.sendMessage(msg);
5340        }
5341    }
5342
5343    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5344        if (!mLaunchWarningShown) {
5345            mLaunchWarningShown = true;
5346            mUiHandler.post(new Runnable() {
5347                @Override
5348                public void run() {
5349                    synchronized (ActivityManagerService.this) {
5350                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5351                        d.show();
5352                        mUiHandler.postDelayed(new Runnable() {
5353                            @Override
5354                            public void run() {
5355                                synchronized (ActivityManagerService.this) {
5356                                    d.dismiss();
5357                                    mLaunchWarningShown = false;
5358                                }
5359                            }
5360                        }, 4000);
5361                    }
5362                }
5363            });
5364        }
5365    }
5366
5367    @Override
5368    public boolean clearApplicationUserData(final String packageName,
5369            final IPackageDataObserver observer, int userId) {
5370        enforceNotIsolatedCaller("clearApplicationUserData");
5371        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5372            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5373        }
5374        int uid = Binder.getCallingUid();
5375        int pid = Binder.getCallingPid();
5376        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5377                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5378        long callingId = Binder.clearCallingIdentity();
5379        try {
5380            IPackageManager pm = AppGlobals.getPackageManager();
5381            int pkgUid = -1;
5382            synchronized(this) {
5383                try {
5384                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5385                } catch (RemoteException e) {
5386                }
5387                if (pkgUid == -1) {
5388                    Slog.w(TAG, "Invalid packageName: " + packageName);
5389                    if (observer != null) {
5390                        try {
5391                            observer.onRemoveCompleted(packageName, false);
5392                        } catch (RemoteException e) {
5393                            Slog.i(TAG, "Observer no longer exists.");
5394                        }
5395                    }
5396                    return false;
5397                }
5398                if (uid == pkgUid || checkComponentPermission(
5399                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5400                        pid, uid, -1, true)
5401                        == PackageManager.PERMISSION_GRANTED) {
5402                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5403                } else {
5404                    throw new SecurityException("PID " + pid + " does not have permission "
5405                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5406                                    + " of package " + packageName);
5407                }
5408
5409                // Remove all tasks match the cleared application package and user
5410                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5411                    final TaskRecord tr = mRecentTasks.get(i);
5412                    final String taskPackageName =
5413                            tr.getBaseIntent().getComponent().getPackageName();
5414                    if (tr.userId != userId) continue;
5415                    if (!taskPackageName.equals(packageName)) continue;
5416                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5417                }
5418            }
5419
5420            try {
5421                // Clear application user data
5422                pm.clearApplicationUserData(packageName, observer, userId);
5423
5424                synchronized(this) {
5425                    // Remove all permissions granted from/to this package
5426                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5427                }
5428
5429                // Remove all zen rules created by this package; revoke it's zen access.
5430                INotificationManager inm = NotificationManager.getService();
5431                inm.removeAutomaticZenRules(packageName);
5432                inm.setNotificationPolicyAccessGranted(packageName, false);
5433
5434                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5435                        Uri.fromParts("package", packageName, null));
5436                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5437                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438                        null, null, 0, null, null, null, null, false, false, userId);
5439            } catch (RemoteException e) {
5440            }
5441        } finally {
5442            Binder.restoreCallingIdentity(callingId);
5443        }
5444        return true;
5445    }
5446
5447    @Override
5448    public void killBackgroundProcesses(final String packageName, int userId) {
5449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5450                != PackageManager.PERMISSION_GRANTED &&
5451                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5452                        != PackageManager.PERMISSION_GRANTED) {
5453            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5454                    + Binder.getCallingPid()
5455                    + ", uid=" + Binder.getCallingUid()
5456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5457            Slog.w(TAG, msg);
5458            throw new SecurityException(msg);
5459        }
5460
5461        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5462                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5463        long callingId = Binder.clearCallingIdentity();
5464        try {
5465            IPackageManager pm = AppGlobals.getPackageManager();
5466            synchronized(this) {
5467                int appId = -1;
5468                try {
5469                    appId = UserHandle.getAppId(
5470                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5471                } catch (RemoteException e) {
5472                }
5473                if (appId == -1) {
5474                    Slog.w(TAG, "Invalid packageName: " + packageName);
5475                    return;
5476                }
5477                killPackageProcessesLocked(packageName, appId, userId,
5478                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5479            }
5480        } finally {
5481            Binder.restoreCallingIdentity(callingId);
5482        }
5483    }
5484
5485    @Override
5486    public void killAllBackgroundProcesses() {
5487        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5488                != PackageManager.PERMISSION_GRANTED) {
5489            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5490                    + Binder.getCallingPid()
5491                    + ", uid=" + Binder.getCallingUid()
5492                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5493            Slog.w(TAG, msg);
5494            throw new SecurityException(msg);
5495        }
5496
5497        long callingId = Binder.clearCallingIdentity();
5498        try {
5499            synchronized(this) {
5500                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5501                final int NP = mProcessNames.getMap().size();
5502                for (int ip=0; ip<NP; ip++) {
5503                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5504                    final int NA = apps.size();
5505                    for (int ia=0; ia<NA; ia++) {
5506                        ProcessRecord app = apps.valueAt(ia);
5507                        if (app.persistent) {
5508                            // we don't kill persistent processes
5509                            continue;
5510                        }
5511                        if (app.removed) {
5512                            procs.add(app);
5513                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5514                            app.removed = true;
5515                            procs.add(app);
5516                        }
5517                    }
5518                }
5519
5520                int N = procs.size();
5521                for (int i=0; i<N; i++) {
5522                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5523                }
5524                mAllowLowerMemLevel = true;
5525                updateOomAdjLocked();
5526                doLowMemReportIfNeededLocked(null);
5527            }
5528        } finally {
5529            Binder.restoreCallingIdentity(callingId);
5530        }
5531    }
5532
5533    @Override
5534    public void forceStopPackage(final String packageName, int userId) {
5535        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5536                != PackageManager.PERMISSION_GRANTED) {
5537            String msg = "Permission Denial: forceStopPackage() from pid="
5538                    + Binder.getCallingPid()
5539                    + ", uid=" + Binder.getCallingUid()
5540                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5541            Slog.w(TAG, msg);
5542            throw new SecurityException(msg);
5543        }
5544        final int callingPid = Binder.getCallingPid();
5545        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5546                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5547        long callingId = Binder.clearCallingIdentity();
5548        try {
5549            IPackageManager pm = AppGlobals.getPackageManager();
5550            synchronized(this) {
5551                int[] users = userId == UserHandle.USER_ALL
5552                        ? mUserController.getUsers() : new int[] { userId };
5553                for (int user : users) {
5554                    int pkgUid = -1;
5555                    try {
5556                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5557                                user);
5558                    } catch (RemoteException e) {
5559                    }
5560                    if (pkgUid == -1) {
5561                        Slog.w(TAG, "Invalid packageName: " + packageName);
5562                        continue;
5563                    }
5564                    try {
5565                        pm.setPackageStoppedState(packageName, true, user);
5566                    } catch (RemoteException e) {
5567                    } catch (IllegalArgumentException e) {
5568                        Slog.w(TAG, "Failed trying to unstop package "
5569                                + packageName + ": " + e);
5570                    }
5571                    if (mUserController.isUserRunningLocked(user, 0)) {
5572                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5573                    }
5574                }
5575            }
5576        } finally {
5577            Binder.restoreCallingIdentity(callingId);
5578        }
5579    }
5580
5581    @Override
5582    public void addPackageDependency(String packageName) {
5583        synchronized (this) {
5584            int callingPid = Binder.getCallingPid();
5585            if (callingPid == Process.myPid()) {
5586                //  Yeah, um, no.
5587                return;
5588            }
5589            ProcessRecord proc;
5590            synchronized (mPidsSelfLocked) {
5591                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5592            }
5593            if (proc != null) {
5594                if (proc.pkgDeps == null) {
5595                    proc.pkgDeps = new ArraySet<String>(1);
5596                }
5597                proc.pkgDeps.add(packageName);
5598            }
5599        }
5600    }
5601
5602    /*
5603     * The pkg name and app id have to be specified.
5604     */
5605    @Override
5606    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5607        if (pkg == null) {
5608            return;
5609        }
5610        // Make sure the uid is valid.
5611        if (appid < 0) {
5612            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5613            return;
5614        }
5615        int callerUid = Binder.getCallingUid();
5616        // Only the system server can kill an application
5617        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5618            // Post an aysnc message to kill the application
5619            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5620            msg.arg1 = appid;
5621            msg.arg2 = 0;
5622            Bundle bundle = new Bundle();
5623            bundle.putString("pkg", pkg);
5624            bundle.putString("reason", reason);
5625            msg.obj = bundle;
5626            mHandler.sendMessage(msg);
5627        } else {
5628            throw new SecurityException(callerUid + " cannot kill pkg: " +
5629                    pkg);
5630        }
5631    }
5632
5633    @Override
5634    public void closeSystemDialogs(String reason) {
5635        enforceNotIsolatedCaller("closeSystemDialogs");
5636
5637        final int pid = Binder.getCallingPid();
5638        final int uid = Binder.getCallingUid();
5639        final long origId = Binder.clearCallingIdentity();
5640        try {
5641            synchronized (this) {
5642                // Only allow this from foreground processes, so that background
5643                // applications can't abuse it to prevent system UI from being shown.
5644                if (uid >= Process.FIRST_APPLICATION_UID) {
5645                    ProcessRecord proc;
5646                    synchronized (mPidsSelfLocked) {
5647                        proc = mPidsSelfLocked.get(pid);
5648                    }
5649                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5650                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5651                                + " from background process " + proc);
5652                        return;
5653                    }
5654                }
5655                closeSystemDialogsLocked(reason);
5656            }
5657        } finally {
5658            Binder.restoreCallingIdentity(origId);
5659        }
5660    }
5661
5662    void closeSystemDialogsLocked(String reason) {
5663        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5664        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5665                | Intent.FLAG_RECEIVER_FOREGROUND);
5666        if (reason != null) {
5667            intent.putExtra("reason", reason);
5668        }
5669        mWindowManager.closeSystemDialogs(reason);
5670
5671        mStackSupervisor.closeSystemDialogsLocked();
5672
5673        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5674                AppOpsManager.OP_NONE, null, false, false,
5675                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5676    }
5677
5678    @Override
5679    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5680        enforceNotIsolatedCaller("getProcessMemoryInfo");
5681        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5682        for (int i=pids.length-1; i>=0; i--) {
5683            ProcessRecord proc;
5684            int oomAdj;
5685            synchronized (this) {
5686                synchronized (mPidsSelfLocked) {
5687                    proc = mPidsSelfLocked.get(pids[i]);
5688                    oomAdj = proc != null ? proc.setAdj : 0;
5689                }
5690            }
5691            infos[i] = new Debug.MemoryInfo();
5692            Debug.getMemoryInfo(pids[i], infos[i]);
5693            if (proc != null) {
5694                synchronized (this) {
5695                    if (proc.thread != null && proc.setAdj == oomAdj) {
5696                        // Record this for posterity if the process has been stable.
5697                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5698                                infos[i].getTotalUss(), false, proc.pkgList);
5699                    }
5700                }
5701            }
5702        }
5703        return infos;
5704    }
5705
5706    @Override
5707    public long[] getProcessPss(int[] pids) {
5708        enforceNotIsolatedCaller("getProcessPss");
5709        long[] pss = new long[pids.length];
5710        for (int i=pids.length-1; i>=0; i--) {
5711            ProcessRecord proc;
5712            int oomAdj;
5713            synchronized (this) {
5714                synchronized (mPidsSelfLocked) {
5715                    proc = mPidsSelfLocked.get(pids[i]);
5716                    oomAdj = proc != null ? proc.setAdj : 0;
5717                }
5718            }
5719            long[] tmpUss = new long[1];
5720            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5721            if (proc != null) {
5722                synchronized (this) {
5723                    if (proc.thread != null && proc.setAdj == oomAdj) {
5724                        // Record this for posterity if the process has been stable.
5725                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5726                    }
5727                }
5728            }
5729        }
5730        return pss;
5731    }
5732
5733    @Override
5734    public void killApplicationProcess(String processName, int uid) {
5735        if (processName == null) {
5736            return;
5737        }
5738
5739        int callerUid = Binder.getCallingUid();
5740        // Only the system server can kill an application
5741        if (callerUid == Process.SYSTEM_UID) {
5742            synchronized (this) {
5743                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5744                if (app != null && app.thread != null) {
5745                    try {
5746                        app.thread.scheduleSuicide();
5747                    } catch (RemoteException e) {
5748                        // If the other end already died, then our work here is done.
5749                    }
5750                } else {
5751                    Slog.w(TAG, "Process/uid not found attempting kill of "
5752                            + processName + " / " + uid);
5753                }
5754            }
5755        } else {
5756            throw new SecurityException(callerUid + " cannot kill app process: " +
5757                    processName);
5758        }
5759    }
5760
5761    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5762        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5763                false, true, false, false, UserHandle.getUserId(uid), reason);
5764        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5765                Uri.fromParts("package", packageName, null));
5766        if (!mProcessesReady) {
5767            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5768                    | Intent.FLAG_RECEIVER_FOREGROUND);
5769        }
5770        intent.putExtra(Intent.EXTRA_UID, uid);
5771        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5772        broadcastIntentLocked(null, null, intent,
5773                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5774                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5775    }
5776
5777
5778    private final boolean killPackageProcessesLocked(String packageName, int appId,
5779            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5780            boolean doit, boolean evenPersistent, String reason) {
5781        ArrayList<ProcessRecord> procs = new ArrayList<>();
5782
5783        // Remove all processes this package may have touched: all with the
5784        // same UID (except for the system or root user), and all whose name
5785        // matches the package name.
5786        final int NP = mProcessNames.getMap().size();
5787        for (int ip=0; ip<NP; ip++) {
5788            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5789            final int NA = apps.size();
5790            for (int ia=0; ia<NA; ia++) {
5791                ProcessRecord app = apps.valueAt(ia);
5792                if (app.persistent && !evenPersistent) {
5793                    // we don't kill persistent processes
5794                    continue;
5795                }
5796                if (app.removed) {
5797                    if (doit) {
5798                        procs.add(app);
5799                    }
5800                    continue;
5801                }
5802
5803                // Skip process if it doesn't meet our oom adj requirement.
5804                if (app.setAdj < minOomAdj) {
5805                    continue;
5806                }
5807
5808                // If no package is specified, we call all processes under the
5809                // give user id.
5810                if (packageName == null) {
5811                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5812                        continue;
5813                    }
5814                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5815                        continue;
5816                    }
5817                // Package has been specified, we want to hit all processes
5818                // that match it.  We need to qualify this by the processes
5819                // that are running under the specified app and user ID.
5820                } else {
5821                    final boolean isDep = app.pkgDeps != null
5822                            && app.pkgDeps.contains(packageName);
5823                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5824                        continue;
5825                    }
5826                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5827                        continue;
5828                    }
5829                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5830                        continue;
5831                    }
5832                }
5833
5834                // Process has passed all conditions, kill it!
5835                if (!doit) {
5836                    return true;
5837                }
5838                app.removed = true;
5839                procs.add(app);
5840            }
5841        }
5842
5843        int N = procs.size();
5844        for (int i=0; i<N; i++) {
5845            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5846        }
5847        updateOomAdjLocked();
5848        return N > 0;
5849    }
5850
5851    private void cleanupDisabledPackageComponentsLocked(
5852            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5853
5854        Set<String> disabledClasses = null;
5855        boolean packageDisabled = false;
5856        IPackageManager pm = AppGlobals.getPackageManager();
5857
5858        if (changedClasses == null) {
5859            // Nothing changed...
5860            return;
5861        }
5862
5863        // Determine enable/disable state of the package and its components.
5864        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5865        for (int i = changedClasses.length - 1; i >= 0; i--) {
5866            final String changedClass = changedClasses[i];
5867
5868            if (changedClass.equals(packageName)) {
5869                try {
5870                    // Entire package setting changed
5871                    enabled = pm.getApplicationEnabledSetting(packageName,
5872                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5873                } catch (Exception e) {
5874                    // No such package/component; probably racing with uninstall.  In any
5875                    // event it means we have nothing further to do here.
5876                    return;
5877                }
5878                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5879                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5880                if (packageDisabled) {
5881                    // Entire package is disabled.
5882                    // No need to continue to check component states.
5883                    disabledClasses = null;
5884                    break;
5885                }
5886            } else {
5887                try {
5888                    enabled = pm.getComponentEnabledSetting(
5889                            new ComponentName(packageName, changedClass),
5890                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5891                } catch (Exception e) {
5892                    // As above, probably racing with uninstall.
5893                    return;
5894                }
5895                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5896                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5897                    if (disabledClasses == null) {
5898                        disabledClasses = new ArraySet<>(changedClasses.length);
5899                    }
5900                    disabledClasses.add(changedClass);
5901                }
5902            }
5903        }
5904
5905        if (!packageDisabled && disabledClasses == null) {
5906            // Nothing to do here...
5907            return;
5908        }
5909
5910        // Clean-up disabled activities.
5911        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5912                packageName, disabledClasses, true, false, userId) && mBooted) {
5913            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5914            mStackSupervisor.scheduleIdleLocked();
5915        }
5916
5917        // Clean-up disabled tasks
5918        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5919
5920        // Clean-up disabled services.
5921        mServices.bringDownDisabledPackageServicesLocked(
5922                packageName, disabledClasses, userId, false, killProcess, true);
5923
5924        // Clean-up disabled providers.
5925        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5926        mProviderMap.collectPackageProvidersLocked(
5927                packageName, disabledClasses, true, false, userId, providers);
5928        for (int i = providers.size() - 1; i >= 0; i--) {
5929            removeDyingProviderLocked(null, providers.get(i), true);
5930        }
5931
5932        // Clean-up disabled broadcast receivers.
5933        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5934            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5935                    packageName, disabledClasses, userId, true);
5936        }
5937
5938    }
5939
5940    final boolean forceStopPackageLocked(String packageName, int appId,
5941            boolean callerWillRestart, boolean purgeCache, boolean doit,
5942            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5943        int i;
5944
5945        if (userId == UserHandle.USER_ALL && packageName == null) {
5946            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5947        }
5948
5949        if (appId < 0 && packageName != null) {
5950            try {
5951                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5952                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5953            } catch (RemoteException e) {
5954            }
5955        }
5956
5957        if (doit) {
5958            if (packageName != null) {
5959                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5960                        + " user=" + userId + ": " + reason);
5961            } else {
5962                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5963            }
5964
5965            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5966            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5967                SparseArray<Long> ba = pmap.valueAt(ip);
5968                for (i = ba.size() - 1; i >= 0; i--) {
5969                    boolean remove = false;
5970                    final int entUid = ba.keyAt(i);
5971                    if (packageName != null) {
5972                        if (userId == UserHandle.USER_ALL) {
5973                            if (UserHandle.getAppId(entUid) == appId) {
5974                                remove = true;
5975                            }
5976                        } else {
5977                            if (entUid == UserHandle.getUid(userId, appId)) {
5978                                remove = true;
5979                            }
5980                        }
5981                    } else if (UserHandle.getUserId(entUid) == userId) {
5982                        remove = true;
5983                    }
5984                    if (remove) {
5985                        ba.removeAt(i);
5986                    }
5987                }
5988                if (ba.size() == 0) {
5989                    pmap.removeAt(ip);
5990                }
5991            }
5992        }
5993
5994        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5995                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5996                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5997
5998        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5999                packageName, null, doit, evenPersistent, userId)) {
6000            if (!doit) {
6001                return true;
6002            }
6003            didSomething = true;
6004        }
6005
6006        if (mServices.bringDownDisabledPackageServicesLocked(
6007                packageName, null, userId, evenPersistent, true, doit)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013
6014        if (packageName == null) {
6015            // Remove all sticky broadcasts from this user.
6016            mStickyBroadcasts.remove(userId);
6017        }
6018
6019        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6020        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6021                userId, providers)) {
6022            if (!doit) {
6023                return true;
6024            }
6025            didSomething = true;
6026        }
6027        for (i = providers.size() - 1; i >= 0; i--) {
6028            removeDyingProviderLocked(null, providers.get(i), true);
6029        }
6030
6031        // Remove transient permissions granted from/to this package/user
6032        removeUriPermissionsForPackageLocked(packageName, userId, false);
6033
6034        if (doit) {
6035            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6036                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6037                        packageName, null, userId, doit);
6038            }
6039        }
6040
6041        if (packageName == null || uninstalling) {
6042            // Remove pending intents.  For now we only do this when force
6043            // stopping users, because we have some problems when doing this
6044            // for packages -- app widgets are not currently cleaned up for
6045            // such packages, so they can be left with bad pending intents.
6046            if (mIntentSenderRecords.size() > 0) {
6047                Iterator<WeakReference<PendingIntentRecord>> it
6048                        = mIntentSenderRecords.values().iterator();
6049                while (it.hasNext()) {
6050                    WeakReference<PendingIntentRecord> wpir = it.next();
6051                    if (wpir == null) {
6052                        it.remove();
6053                        continue;
6054                    }
6055                    PendingIntentRecord pir = wpir.get();
6056                    if (pir == null) {
6057                        it.remove();
6058                        continue;
6059                    }
6060                    if (packageName == null) {
6061                        // Stopping user, remove all objects for the user.
6062                        if (pir.key.userId != userId) {
6063                            // Not the same user, skip it.
6064                            continue;
6065                        }
6066                    } else {
6067                        if (UserHandle.getAppId(pir.uid) != appId) {
6068                            // Different app id, skip it.
6069                            continue;
6070                        }
6071                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6072                            // Different user, skip it.
6073                            continue;
6074                        }
6075                        if (!pir.key.packageName.equals(packageName)) {
6076                            // Different package, skip it.
6077                            continue;
6078                        }
6079                    }
6080                    if (!doit) {
6081                        return true;
6082                    }
6083                    didSomething = true;
6084                    it.remove();
6085                    pir.canceled = true;
6086                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6087                        pir.key.activity.pendingResults.remove(pir.ref);
6088                    }
6089                }
6090            }
6091        }
6092
6093        if (doit) {
6094            if (purgeCache && packageName != null) {
6095                AttributeCache ac = AttributeCache.instance();
6096                if (ac != null) {
6097                    ac.removePackage(packageName);
6098                }
6099            }
6100            if (mBooted) {
6101                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6102                mStackSupervisor.scheduleIdleLocked();
6103            }
6104        }
6105
6106        return didSomething;
6107    }
6108
6109    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6110        ProcessRecord old = mProcessNames.remove(name, uid);
6111        if (old != null) {
6112            old.uidRecord.numProcs--;
6113            if (old.uidRecord.numProcs == 0) {
6114                // No more processes using this uid, tell clients it is gone.
6115                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6116                        "No more processes in " + old.uidRecord);
6117                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6118                mActiveUids.remove(uid);
6119                mBatteryStatsService.noteUidProcessState(uid,
6120                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6121            }
6122            old.uidRecord = null;
6123        }
6124        mIsolatedProcesses.remove(uid);
6125        return old;
6126    }
6127
6128    private final void addProcessNameLocked(ProcessRecord proc) {
6129        // We shouldn't already have a process under this name, but just in case we
6130        // need to clean up whatever may be there now.
6131        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6132        if (old == proc && proc.persistent) {
6133            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6134            Slog.w(TAG, "Re-adding persistent process " + proc);
6135        } else if (old != null) {
6136            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6137        }
6138        UidRecord uidRec = mActiveUids.get(proc.uid);
6139        if (uidRec == null) {
6140            uidRec = new UidRecord(proc.uid);
6141            // This is the first appearance of the uid, report it now!
6142            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6143                    "Creating new process uid: " + uidRec);
6144            mActiveUids.put(proc.uid, uidRec);
6145            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6146            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6147        }
6148        proc.uidRecord = uidRec;
6149        uidRec.numProcs++;
6150        mProcessNames.put(proc.processName, proc.uid, proc);
6151        if (proc.isolated) {
6152            mIsolatedProcesses.put(proc.uid, proc);
6153        }
6154    }
6155
6156    private final boolean removeProcessLocked(ProcessRecord app,
6157            boolean callerWillRestart, boolean allowRestart, String reason) {
6158        final String name = app.processName;
6159        final int uid = app.uid;
6160        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6161            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6162
6163        removeProcessNameLocked(name, uid);
6164        if (mHeavyWeightProcess == app) {
6165            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6166                    mHeavyWeightProcess.userId, 0));
6167            mHeavyWeightProcess = null;
6168        }
6169        boolean needRestart = false;
6170        if (app.pid > 0 && app.pid != MY_PID) {
6171            int pid = app.pid;
6172            synchronized (mPidsSelfLocked) {
6173                mPidsSelfLocked.remove(pid);
6174                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6175            }
6176            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6177            if (app.isolated) {
6178                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6179            }
6180            boolean willRestart = false;
6181            if (app.persistent && !app.isolated) {
6182                if (!callerWillRestart) {
6183                    willRestart = true;
6184                } else {
6185                    needRestart = true;
6186                }
6187            }
6188            app.kill(reason, true);
6189            handleAppDiedLocked(app, willRestart, allowRestart);
6190            if (willRestart) {
6191                removeLruProcessLocked(app);
6192                addAppLocked(app.info, false, null /* ABI override */);
6193            }
6194        } else {
6195            mRemovedProcesses.add(app);
6196        }
6197
6198        return needRestart;
6199    }
6200
6201    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6202        cleanupAppInLaunchingProvidersLocked(app, true);
6203        removeProcessLocked(app, false, true, "timeout publishing content providers");
6204    }
6205
6206    private final void processStartTimedOutLocked(ProcessRecord app) {
6207        final int pid = app.pid;
6208        boolean gone = false;
6209        synchronized (mPidsSelfLocked) {
6210            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6211            if (knownApp != null && knownApp.thread == null) {
6212                mPidsSelfLocked.remove(pid);
6213                gone = true;
6214            }
6215        }
6216
6217        if (gone) {
6218            Slog.w(TAG, "Process " + app + " failed to attach");
6219            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6220                    pid, app.uid, app.processName);
6221            removeProcessNameLocked(app.processName, app.uid);
6222            if (mHeavyWeightProcess == app) {
6223                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6224                        mHeavyWeightProcess.userId, 0));
6225                mHeavyWeightProcess = null;
6226            }
6227            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6228            if (app.isolated) {
6229                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6230            }
6231            // Take care of any launching providers waiting for this process.
6232            cleanupAppInLaunchingProvidersLocked(app, true);
6233            // Take care of any services that are waiting for the process.
6234            mServices.processStartTimedOutLocked(app);
6235            app.kill("start timeout", true);
6236            removeLruProcessLocked(app);
6237            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6238                Slog.w(TAG, "Unattached app died before backup, skipping");
6239                try {
6240                    IBackupManager bm = IBackupManager.Stub.asInterface(
6241                            ServiceManager.getService(Context.BACKUP_SERVICE));
6242                    bm.agentDisconnected(app.info.packageName);
6243                } catch (RemoteException e) {
6244                    // Can't happen; the backup manager is local
6245                }
6246            }
6247            if (isPendingBroadcastProcessLocked(pid)) {
6248                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6249                skipPendingBroadcastLocked(pid);
6250            }
6251        } else {
6252            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6253        }
6254    }
6255
6256    private final boolean attachApplicationLocked(IApplicationThread thread,
6257            int pid) {
6258
6259        // Find the application record that is being attached...  either via
6260        // the pid if we are running in multiple processes, or just pull the
6261        // next app record if we are emulating process with anonymous threads.
6262        ProcessRecord app;
6263        if (pid != MY_PID && pid >= 0) {
6264            synchronized (mPidsSelfLocked) {
6265                app = mPidsSelfLocked.get(pid);
6266            }
6267        } else {
6268            app = null;
6269        }
6270
6271        if (app == null) {
6272            Slog.w(TAG, "No pending application record for pid " + pid
6273                    + " (IApplicationThread " + thread + "); dropping process");
6274            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6275            if (pid > 0 && pid != MY_PID) {
6276                Process.killProcessQuiet(pid);
6277                //TODO: killProcessGroup(app.info.uid, pid);
6278            } else {
6279                try {
6280                    thread.scheduleExit();
6281                } catch (Exception e) {
6282                    // Ignore exceptions.
6283                }
6284            }
6285            return false;
6286        }
6287
6288        // If this application record is still attached to a previous
6289        // process, clean it up now.
6290        if (app.thread != null) {
6291            handleAppDiedLocked(app, true, true);
6292        }
6293
6294        // Tell the process all about itself.
6295
6296        if (DEBUG_ALL) Slog.v(
6297                TAG, "Binding process pid " + pid + " to record " + app);
6298
6299        final String processName = app.processName;
6300        try {
6301            AppDeathRecipient adr = new AppDeathRecipient(
6302                    app, pid, thread);
6303            thread.asBinder().linkToDeath(adr, 0);
6304            app.deathRecipient = adr;
6305        } catch (RemoteException e) {
6306            app.resetPackageList(mProcessStats);
6307            startProcessLocked(app, "link fail", processName);
6308            return false;
6309        }
6310
6311        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6312
6313        app.makeActive(thread, mProcessStats);
6314        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6315        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6316        app.forcingToForeground = null;
6317        updateProcessForegroundLocked(app, false, false);
6318        app.hasShownUi = false;
6319        app.debugging = false;
6320        app.cached = false;
6321        app.killedByAm = false;
6322
6323        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6324
6325        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6326        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6327
6328        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6329            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6330            msg.obj = app;
6331            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6332        }
6333
6334        if (!normalMode) {
6335            Slog.i(TAG, "Launching preboot mode app: " + app);
6336        }
6337
6338        if (DEBUG_ALL) Slog.v(
6339            TAG, "New app record " + app
6340            + " thread=" + thread.asBinder() + " pid=" + pid);
6341        try {
6342            int testMode = IApplicationThread.DEBUG_OFF;
6343            if (mDebugApp != null && mDebugApp.equals(processName)) {
6344                testMode = mWaitForDebugger
6345                    ? IApplicationThread.DEBUG_WAIT
6346                    : IApplicationThread.DEBUG_ON;
6347                app.debugging = true;
6348                if (mDebugTransient) {
6349                    mDebugApp = mOrigDebugApp;
6350                    mWaitForDebugger = mOrigWaitForDebugger;
6351                }
6352            }
6353            String profileFile = app.instrumentationProfileFile;
6354            ParcelFileDescriptor profileFd = null;
6355            int samplingInterval = 0;
6356            boolean profileAutoStop = false;
6357            if (mProfileApp != null && mProfileApp.equals(processName)) {
6358                mProfileProc = app;
6359                profileFile = mProfileFile;
6360                profileFd = mProfileFd;
6361                samplingInterval = mSamplingInterval;
6362                profileAutoStop = mAutoStopProfiler;
6363            }
6364            boolean enableTrackAllocation = false;
6365            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6366                enableTrackAllocation = true;
6367                mTrackAllocationApp = null;
6368            }
6369
6370            // If the app is being launched for restore or full backup, set it up specially
6371            boolean isRestrictedBackupMode = false;
6372            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6373                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6374                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6375                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6376            }
6377
6378            notifyPackageUse(app.instrumentationInfo != null
6379                    ? app.instrumentationInfo.packageName
6380                    : app.info.packageName);
6381            if (app.instrumentationClass != null) {
6382                notifyPackageUse(app.instrumentationClass.getPackageName());
6383            }
6384            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6385                    + processName + " with config " + mConfiguration);
6386            ApplicationInfo appInfo = app.instrumentationInfo != null
6387                    ? app.instrumentationInfo : app.info;
6388            app.compat = compatibilityInfoForPackageLocked(appInfo);
6389            if (profileFd != null) {
6390                profileFd = profileFd.dup();
6391            }
6392            ProfilerInfo profilerInfo = profileFile == null ? null
6393                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6394            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6395                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6396                    app.instrumentationUiAutomationConnection, testMode,
6397                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6398                    isRestrictedBackupMode || !normalMode, app.persistent,
6399                    new Configuration(mConfiguration), app.compat,
6400                    getCommonServicesLocked(app.isolated),
6401                    mCoreSettingsObserver.getCoreSettingsLocked());
6402            updateLruProcessLocked(app, false, null);
6403            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6404        } catch (Exception e) {
6405            // todo: Yikes!  What should we do?  For now we will try to
6406            // start another process, but that could easily get us in
6407            // an infinite loop of restarting processes...
6408            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6409
6410            app.resetPackageList(mProcessStats);
6411            app.unlinkDeathRecipient();
6412            startProcessLocked(app, "bind fail", processName);
6413            return false;
6414        }
6415
6416        // Remove this record from the list of starting applications.
6417        mPersistentStartingProcesses.remove(app);
6418        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6419                "Attach application locked removing on hold: " + app);
6420        mProcessesOnHold.remove(app);
6421
6422        boolean badApp = false;
6423        boolean didSomething = false;
6424
6425        // See if the top visible activity is waiting to run in this process...
6426        if (normalMode) {
6427            try {
6428                if (mStackSupervisor.attachApplicationLocked(app)) {
6429                    didSomething = true;
6430                }
6431            } catch (Exception e) {
6432                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6433                badApp = true;
6434            }
6435        }
6436
6437        // Find any services that should be running in this process...
6438        if (!badApp) {
6439            try {
6440                didSomething |= mServices.attachApplicationLocked(app, processName);
6441            } catch (Exception e) {
6442                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6443                badApp = true;
6444            }
6445        }
6446
6447        // Check if a next-broadcast receiver is in this process...
6448        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6449            try {
6450                didSomething |= sendPendingBroadcastsLocked(app);
6451            } catch (Exception e) {
6452                // If the app died trying to launch the receiver we declare it 'bad'
6453                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6454                badApp = true;
6455            }
6456        }
6457
6458        // Check whether the next backup agent is in this process...
6459        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6460            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6461                    "New app is backup target, launching agent for " + app);
6462            notifyPackageUse(mBackupTarget.appInfo.packageName);
6463            try {
6464                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6465                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6466                        mBackupTarget.backupMode);
6467            } catch (Exception e) {
6468                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6469                badApp = true;
6470            }
6471        }
6472
6473        if (badApp) {
6474            app.kill("error during init", true);
6475            handleAppDiedLocked(app, false, true);
6476            return false;
6477        }
6478
6479        if (!didSomething) {
6480            updateOomAdjLocked();
6481        }
6482
6483        return true;
6484    }
6485
6486    @Override
6487    public final void attachApplication(IApplicationThread thread) {
6488        synchronized (this) {
6489            int callingPid = Binder.getCallingPid();
6490            final long origId = Binder.clearCallingIdentity();
6491            attachApplicationLocked(thread, callingPid);
6492            Binder.restoreCallingIdentity(origId);
6493        }
6494    }
6495
6496    @Override
6497    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6498        final long origId = Binder.clearCallingIdentity();
6499        synchronized (this) {
6500            ActivityStack stack = ActivityRecord.getStackLocked(token);
6501            if (stack != null) {
6502                ActivityRecord r =
6503                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6504                if (stopProfiling) {
6505                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6506                        try {
6507                            mProfileFd.close();
6508                        } catch (IOException e) {
6509                        }
6510                        clearProfilerLocked();
6511                    }
6512                }
6513            }
6514        }
6515        Binder.restoreCallingIdentity(origId);
6516    }
6517
6518    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6519        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6520                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6521    }
6522
6523    void enableScreenAfterBoot() {
6524        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6525                SystemClock.uptimeMillis());
6526        mWindowManager.enableScreenAfterBoot();
6527
6528        synchronized (this) {
6529            updateEventDispatchingLocked();
6530        }
6531    }
6532
6533    @Override
6534    public void showBootMessage(final CharSequence msg, final boolean always) {
6535        if (Binder.getCallingUid() != Process.myUid()) {
6536            // These days only the core system can call this, so apps can't get in
6537            // the way of what we show about running them.
6538        }
6539        mWindowManager.showBootMessage(msg, always);
6540    }
6541
6542    @Override
6543    public void keyguardWaitingForActivityDrawn() {
6544        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6545        final long token = Binder.clearCallingIdentity();
6546        try {
6547            synchronized (this) {
6548                if (DEBUG_LOCKSCREEN) logLockScreen("");
6549                mWindowManager.keyguardWaitingForActivityDrawn();
6550                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6551                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6552                    updateSleepIfNeededLocked();
6553                }
6554            }
6555        } finally {
6556            Binder.restoreCallingIdentity(token);
6557        }
6558    }
6559
6560    @Override
6561    public void keyguardGoingAway(boolean disableWindowAnimations,
6562            boolean keyguardGoingToNotificationShade) {
6563        enforceNotIsolatedCaller("keyguardGoingAway");
6564        final long token = Binder.clearCallingIdentity();
6565        try {
6566            synchronized (this) {
6567                if (DEBUG_LOCKSCREEN) logLockScreen("");
6568                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6569                        keyguardGoingToNotificationShade);
6570                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6571                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6572                    updateSleepIfNeededLocked();
6573                }
6574            }
6575        } finally {
6576            Binder.restoreCallingIdentity(token);
6577        }
6578    }
6579
6580    final void finishBooting() {
6581        synchronized (this) {
6582            if (!mBootAnimationComplete) {
6583                mCallFinishBooting = true;
6584                return;
6585            }
6586            mCallFinishBooting = false;
6587        }
6588
6589        ArraySet<String> completedIsas = new ArraySet<String>();
6590        for (String abi : Build.SUPPORTED_ABIS) {
6591            Process.establishZygoteConnectionForAbi(abi);
6592            final String instructionSet = VMRuntime.getInstructionSet(abi);
6593            if (!completedIsas.contains(instructionSet)) {
6594                try {
6595                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6596                } catch (InstallerException e) {
6597                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6598                }
6599                completedIsas.add(instructionSet);
6600            }
6601        }
6602
6603        IntentFilter pkgFilter = new IntentFilter();
6604        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6605        pkgFilter.addDataScheme("package");
6606        mContext.registerReceiver(new BroadcastReceiver() {
6607            @Override
6608            public void onReceive(Context context, Intent intent) {
6609                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6610                if (pkgs != null) {
6611                    for (String pkg : pkgs) {
6612                        synchronized (ActivityManagerService.this) {
6613                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6614                                    0, "query restart")) {
6615                                setResultCode(Activity.RESULT_OK);
6616                                return;
6617                            }
6618                        }
6619                    }
6620                }
6621            }
6622        }, pkgFilter);
6623
6624        IntentFilter dumpheapFilter = new IntentFilter();
6625        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6626        mContext.registerReceiver(new BroadcastReceiver() {
6627            @Override
6628            public void onReceive(Context context, Intent intent) {
6629                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6630                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6631                } else {
6632                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6633                }
6634            }
6635        }, dumpheapFilter);
6636
6637        // Let system services know.
6638        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6639
6640        synchronized (this) {
6641            // Ensure that any processes we had put on hold are now started
6642            // up.
6643            final int NP = mProcessesOnHold.size();
6644            if (NP > 0) {
6645                ArrayList<ProcessRecord> procs =
6646                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6647                for (int ip=0; ip<NP; ip++) {
6648                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6649                            + procs.get(ip));
6650                    startProcessLocked(procs.get(ip), "on-hold", null);
6651                }
6652            }
6653
6654            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6655                // Start looking for apps that are abusing wake locks.
6656                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6657                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6658                // Tell anyone interested that we are done booting!
6659                SystemProperties.set("sys.boot_completed", "1");
6660
6661                // And trigger dev.bootcomplete if we are not showing encryption progress
6662                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6663                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6664                    SystemProperties.set("dev.bootcomplete", "1");
6665                }
6666                mUserController.sendBootCompletedLocked(
6667                        new IIntentReceiver.Stub() {
6668                            @Override
6669                            public void performReceive(Intent intent, int resultCode,
6670                                    String data, Bundle extras, boolean ordered,
6671                                    boolean sticky, int sendingUser) {
6672                                synchronized (ActivityManagerService.this) {
6673                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6674                                            true, false);
6675                                }
6676                            }
6677                        });
6678                scheduleStartProfilesLocked();
6679            }
6680        }
6681    }
6682
6683    @Override
6684    public void bootAnimationComplete() {
6685        final boolean callFinishBooting;
6686        synchronized (this) {
6687            callFinishBooting = mCallFinishBooting;
6688            mBootAnimationComplete = true;
6689        }
6690        if (callFinishBooting) {
6691            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6692            finishBooting();
6693            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6694        }
6695    }
6696
6697    final void ensureBootCompleted() {
6698        boolean booting;
6699        boolean enableScreen;
6700        synchronized (this) {
6701            booting = mBooting;
6702            mBooting = false;
6703            enableScreen = !mBooted;
6704            mBooted = true;
6705        }
6706
6707        if (booting) {
6708            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6709            finishBooting();
6710            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6711        }
6712
6713        if (enableScreen) {
6714            enableScreenAfterBoot();
6715        }
6716    }
6717
6718    @Override
6719    public final void activityResumed(IBinder token) {
6720        final long origId = Binder.clearCallingIdentity();
6721        synchronized(this) {
6722            ActivityStack stack = ActivityRecord.getStackLocked(token);
6723            if (stack != null) {
6724                ActivityRecord.activityResumedLocked(token);
6725            }
6726        }
6727        Binder.restoreCallingIdentity(origId);
6728    }
6729
6730    @Override
6731    public final void activityPaused(IBinder token) {
6732        final long origId = Binder.clearCallingIdentity();
6733        synchronized(this) {
6734            ActivityStack stack = ActivityRecord.getStackLocked(token);
6735            if (stack != null) {
6736                stack.activityPausedLocked(token, false);
6737            }
6738        }
6739        Binder.restoreCallingIdentity(origId);
6740    }
6741
6742    @Override
6743    public final void activityStopped(IBinder token, Bundle icicle,
6744            PersistableBundle persistentState, CharSequence description) {
6745        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6746
6747        // Refuse possible leaked file descriptors
6748        if (icicle != null && icicle.hasFileDescriptors()) {
6749            throw new IllegalArgumentException("File descriptors passed in Bundle");
6750        }
6751
6752        final long origId = Binder.clearCallingIdentity();
6753
6754        synchronized (this) {
6755            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6756            if (r != null) {
6757                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6758            }
6759        }
6760
6761        trimApplications();
6762
6763        Binder.restoreCallingIdentity(origId);
6764    }
6765
6766    @Override
6767    public final void activityDestroyed(IBinder token) {
6768        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6769        synchronized (this) {
6770            ActivityStack stack = ActivityRecord.getStackLocked(token);
6771            if (stack != null) {
6772                stack.activityDestroyedLocked(token, "activityDestroyed");
6773            }
6774        }
6775    }
6776
6777    @Override
6778    public final void activityRelaunched(IBinder token) {
6779        final long origId = Binder.clearCallingIdentity();
6780        synchronized (this) {
6781            mStackSupervisor.activityRelaunchedLocked(token);
6782        }
6783        Binder.restoreCallingIdentity(origId);
6784    }
6785
6786    @Override
6787    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6788            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6789        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6790                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6791        synchronized (this) {
6792            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6793            if (record == null) {
6794                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6795                        + "found for: " + token);
6796            }
6797            record.setSizeConfigurations(horizontalSizeConfiguration,
6798                    verticalSizeConfigurations, smallestSizeConfigurations);
6799        }
6800    }
6801
6802    @Override
6803    public final void backgroundResourcesReleased(IBinder token) {
6804        final long origId = Binder.clearCallingIdentity();
6805        try {
6806            synchronized (this) {
6807                ActivityStack stack = ActivityRecord.getStackLocked(token);
6808                if (stack != null) {
6809                    stack.backgroundResourcesReleased();
6810                }
6811            }
6812        } finally {
6813            Binder.restoreCallingIdentity(origId);
6814        }
6815    }
6816
6817    @Override
6818    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6819        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6820    }
6821
6822    @Override
6823    public final void notifyEnterAnimationComplete(IBinder token) {
6824        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6825    }
6826
6827    @Override
6828    public String getCallingPackage(IBinder token) {
6829        synchronized (this) {
6830            ActivityRecord r = getCallingRecordLocked(token);
6831            return r != null ? r.info.packageName : null;
6832        }
6833    }
6834
6835    @Override
6836    public ComponentName getCallingActivity(IBinder token) {
6837        synchronized (this) {
6838            ActivityRecord r = getCallingRecordLocked(token);
6839            return r != null ? r.intent.getComponent() : null;
6840        }
6841    }
6842
6843    private ActivityRecord getCallingRecordLocked(IBinder token) {
6844        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6845        if (r == null) {
6846            return null;
6847        }
6848        return r.resultTo;
6849    }
6850
6851    @Override
6852    public ComponentName getActivityClassForToken(IBinder token) {
6853        synchronized(this) {
6854            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6855            if (r == null) {
6856                return null;
6857            }
6858            return r.intent.getComponent();
6859        }
6860    }
6861
6862    @Override
6863    public String getPackageForToken(IBinder token) {
6864        synchronized(this) {
6865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6866            if (r == null) {
6867                return null;
6868            }
6869            return r.packageName;
6870        }
6871    }
6872
6873    @Override
6874    public boolean isRootVoiceInteraction(IBinder token) {
6875        synchronized(this) {
6876            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6877            if (r == null) {
6878                return false;
6879            }
6880            return r.rootVoiceInteraction;
6881        }
6882    }
6883
6884    @Override
6885    public IIntentSender getIntentSender(int type,
6886            String packageName, IBinder token, String resultWho,
6887            int requestCode, Intent[] intents, String[] resolvedTypes,
6888            int flags, Bundle bOptions, int userId) {
6889        enforceNotIsolatedCaller("getIntentSender");
6890        // Refuse possible leaked file descriptors
6891        if (intents != null) {
6892            if (intents.length < 1) {
6893                throw new IllegalArgumentException("Intents array length must be >= 1");
6894            }
6895            for (int i=0; i<intents.length; i++) {
6896                Intent intent = intents[i];
6897                if (intent != null) {
6898                    if (intent.hasFileDescriptors()) {
6899                        throw new IllegalArgumentException("File descriptors passed in Intent");
6900                    }
6901                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6902                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6903                        throw new IllegalArgumentException(
6904                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6905                    }
6906                    intents[i] = new Intent(intent);
6907                }
6908            }
6909            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6910                throw new IllegalArgumentException(
6911                        "Intent array length does not match resolvedTypes length");
6912            }
6913        }
6914        if (bOptions != null) {
6915            if (bOptions.hasFileDescriptors()) {
6916                throw new IllegalArgumentException("File descriptors passed in options");
6917            }
6918        }
6919
6920        synchronized(this) {
6921            int callingUid = Binder.getCallingUid();
6922            int origUserId = userId;
6923            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6924                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6925                    ALLOW_NON_FULL, "getIntentSender", null);
6926            if (origUserId == UserHandle.USER_CURRENT) {
6927                // We don't want to evaluate this until the pending intent is
6928                // actually executed.  However, we do want to always do the
6929                // security checking for it above.
6930                userId = UserHandle.USER_CURRENT;
6931            }
6932            try {
6933                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6934                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6935                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6936                    if (!UserHandle.isSameApp(callingUid, uid)) {
6937                        String msg = "Permission Denial: getIntentSender() from pid="
6938                            + Binder.getCallingPid()
6939                            + ", uid=" + Binder.getCallingUid()
6940                            + ", (need uid=" + uid + ")"
6941                            + " is not allowed to send as package " + packageName;
6942                        Slog.w(TAG, msg);
6943                        throw new SecurityException(msg);
6944                    }
6945                }
6946
6947                return getIntentSenderLocked(type, packageName, callingUid, userId,
6948                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6949
6950            } catch (RemoteException e) {
6951                throw new SecurityException(e);
6952            }
6953        }
6954    }
6955
6956    IIntentSender getIntentSenderLocked(int type, String packageName,
6957            int callingUid, int userId, IBinder token, String resultWho,
6958            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6959            Bundle bOptions) {
6960        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6961        ActivityRecord activity = null;
6962        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6963            activity = ActivityRecord.isInStackLocked(token);
6964            if (activity == null) {
6965                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6966                return null;
6967            }
6968            if (activity.finishing) {
6969                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6970                return null;
6971            }
6972        }
6973
6974        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6975        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6976        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6977        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6978                |PendingIntent.FLAG_UPDATE_CURRENT);
6979
6980        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6981                type, packageName, activity, resultWho,
6982                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6983        WeakReference<PendingIntentRecord> ref;
6984        ref = mIntentSenderRecords.get(key);
6985        PendingIntentRecord rec = ref != null ? ref.get() : null;
6986        if (rec != null) {
6987            if (!cancelCurrent) {
6988                if (updateCurrent) {
6989                    if (rec.key.requestIntent != null) {
6990                        rec.key.requestIntent.replaceExtras(intents != null ?
6991                                intents[intents.length - 1] : null);
6992                    }
6993                    if (intents != null) {
6994                        intents[intents.length-1] = rec.key.requestIntent;
6995                        rec.key.allIntents = intents;
6996                        rec.key.allResolvedTypes = resolvedTypes;
6997                    } else {
6998                        rec.key.allIntents = null;
6999                        rec.key.allResolvedTypes = null;
7000                    }
7001                }
7002                return rec;
7003            }
7004            rec.canceled = true;
7005            mIntentSenderRecords.remove(key);
7006        }
7007        if (noCreate) {
7008            return rec;
7009        }
7010        rec = new PendingIntentRecord(this, key, callingUid);
7011        mIntentSenderRecords.put(key, rec.ref);
7012        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7013            if (activity.pendingResults == null) {
7014                activity.pendingResults
7015                        = new HashSet<WeakReference<PendingIntentRecord>>();
7016            }
7017            activity.pendingResults.add(rec.ref);
7018        }
7019        return rec;
7020    }
7021
7022    @Override
7023    public void cancelIntentSender(IIntentSender sender) {
7024        if (!(sender instanceof PendingIntentRecord)) {
7025            return;
7026        }
7027        synchronized(this) {
7028            PendingIntentRecord rec = (PendingIntentRecord)sender;
7029            try {
7030                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7031                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7032                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7033                    String msg = "Permission Denial: cancelIntentSender() from pid="
7034                        + Binder.getCallingPid()
7035                        + ", uid=" + Binder.getCallingUid()
7036                        + " is not allowed to cancel packges "
7037                        + rec.key.packageName;
7038                    Slog.w(TAG, msg);
7039                    throw new SecurityException(msg);
7040                }
7041            } catch (RemoteException e) {
7042                throw new SecurityException(e);
7043            }
7044            cancelIntentSenderLocked(rec, true);
7045        }
7046    }
7047
7048    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7049        rec.canceled = true;
7050        mIntentSenderRecords.remove(rec.key);
7051        if (cleanActivity && rec.key.activity != null) {
7052            rec.key.activity.pendingResults.remove(rec.ref);
7053        }
7054    }
7055
7056    @Override
7057    public String getPackageForIntentSender(IIntentSender pendingResult) {
7058        if (!(pendingResult instanceof PendingIntentRecord)) {
7059            return null;
7060        }
7061        try {
7062            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7063            return res.key.packageName;
7064        } catch (ClassCastException e) {
7065        }
7066        return null;
7067    }
7068
7069    @Override
7070    public int getUidForIntentSender(IIntentSender sender) {
7071        if (sender instanceof PendingIntentRecord) {
7072            try {
7073                PendingIntentRecord res = (PendingIntentRecord)sender;
7074                return res.uid;
7075            } catch (ClassCastException e) {
7076            }
7077        }
7078        return -1;
7079    }
7080
7081    @Override
7082    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7083        if (!(pendingResult instanceof PendingIntentRecord)) {
7084            return false;
7085        }
7086        try {
7087            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7088            if (res.key.allIntents == null) {
7089                return false;
7090            }
7091            for (int i=0; i<res.key.allIntents.length; i++) {
7092                Intent intent = res.key.allIntents[i];
7093                if (intent.getPackage() != null && intent.getComponent() != null) {
7094                    return false;
7095                }
7096            }
7097            return true;
7098        } catch (ClassCastException e) {
7099        }
7100        return false;
7101    }
7102
7103    @Override
7104    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7105        if (!(pendingResult instanceof PendingIntentRecord)) {
7106            return false;
7107        }
7108        try {
7109            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7110            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7111                return true;
7112            }
7113            return false;
7114        } catch (ClassCastException e) {
7115        }
7116        return false;
7117    }
7118
7119    @Override
7120    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7121        if (!(pendingResult instanceof PendingIntentRecord)) {
7122            return null;
7123        }
7124        try {
7125            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7126            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7127        } catch (ClassCastException e) {
7128        }
7129        return null;
7130    }
7131
7132    @Override
7133    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7134        if (!(pendingResult instanceof PendingIntentRecord)) {
7135            return null;
7136        }
7137        try {
7138            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7139            synchronized (this) {
7140                return getTagForIntentSenderLocked(res, prefix);
7141            }
7142        } catch (ClassCastException e) {
7143        }
7144        return null;
7145    }
7146
7147    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7148        final Intent intent = res.key.requestIntent;
7149        if (intent != null) {
7150            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7151                    || res.lastTagPrefix.equals(prefix))) {
7152                return res.lastTag;
7153            }
7154            res.lastTagPrefix = prefix;
7155            final StringBuilder sb = new StringBuilder(128);
7156            if (prefix != null) {
7157                sb.append(prefix);
7158            }
7159            if (intent.getAction() != null) {
7160                sb.append(intent.getAction());
7161            } else if (intent.getComponent() != null) {
7162                intent.getComponent().appendShortString(sb);
7163            } else {
7164                sb.append("?");
7165            }
7166            return res.lastTag = sb.toString();
7167        }
7168        return null;
7169    }
7170
7171    @Override
7172    public void setProcessLimit(int max) {
7173        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7174                "setProcessLimit()");
7175        synchronized (this) {
7176            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7177            mProcessLimitOverride = max;
7178        }
7179        trimApplications();
7180    }
7181
7182    @Override
7183    public int getProcessLimit() {
7184        synchronized (this) {
7185            return mProcessLimitOverride;
7186        }
7187    }
7188
7189    void foregroundTokenDied(ForegroundToken token) {
7190        synchronized (ActivityManagerService.this) {
7191            synchronized (mPidsSelfLocked) {
7192                ForegroundToken cur
7193                    = mForegroundProcesses.get(token.pid);
7194                if (cur != token) {
7195                    return;
7196                }
7197                mForegroundProcesses.remove(token.pid);
7198                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7199                if (pr == null) {
7200                    return;
7201                }
7202                pr.forcingToForeground = null;
7203                updateProcessForegroundLocked(pr, false, false);
7204            }
7205            updateOomAdjLocked();
7206        }
7207    }
7208
7209    @Override
7210    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7211        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7212                "setProcessForeground()");
7213        synchronized(this) {
7214            boolean changed = false;
7215
7216            synchronized (mPidsSelfLocked) {
7217                ProcessRecord pr = mPidsSelfLocked.get(pid);
7218                if (pr == null && isForeground) {
7219                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7220                    return;
7221                }
7222                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7223                if (oldToken != null) {
7224                    oldToken.token.unlinkToDeath(oldToken, 0);
7225                    mForegroundProcesses.remove(pid);
7226                    if (pr != null) {
7227                        pr.forcingToForeground = null;
7228                    }
7229                    changed = true;
7230                }
7231                if (isForeground && token != null) {
7232                    ForegroundToken newToken = new ForegroundToken() {
7233                        @Override
7234                        public void binderDied() {
7235                            foregroundTokenDied(this);
7236                        }
7237                    };
7238                    newToken.pid = pid;
7239                    newToken.token = token;
7240                    try {
7241                        token.linkToDeath(newToken, 0);
7242                        mForegroundProcesses.put(pid, newToken);
7243                        pr.forcingToForeground = token;
7244                        changed = true;
7245                    } catch (RemoteException e) {
7246                        // If the process died while doing this, we will later
7247                        // do the cleanup with the process death link.
7248                    }
7249                }
7250            }
7251
7252            if (changed) {
7253                updateOomAdjLocked();
7254            }
7255        }
7256    }
7257
7258    @Override
7259    public boolean isAppForeground(int uid) throws RemoteException {
7260        synchronized (this) {
7261            UidRecord uidRec = mActiveUids.get(uid);
7262            if (uidRec == null || uidRec.idle) {
7263                return false;
7264            }
7265            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7266        }
7267    }
7268
7269    @Override
7270    public boolean inMultiWindowMode(IBinder token) {
7271        final long origId = Binder.clearCallingIdentity();
7272        try {
7273            synchronized(this) {
7274                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7275                if (r == null) {
7276                    return false;
7277                }
7278                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7279                return !r.task.mFullscreen;
7280            }
7281        } finally {
7282            Binder.restoreCallingIdentity(origId);
7283        }
7284    }
7285
7286    @Override
7287    public boolean inPictureInPictureMode(IBinder token) {
7288        final long origId = Binder.clearCallingIdentity();
7289        try {
7290            synchronized(this) {
7291                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7292                if (stack == null) {
7293                    return false;
7294                }
7295                return stack.mStackId == PINNED_STACK_ID;
7296            }
7297        } finally {
7298            Binder.restoreCallingIdentity(origId);
7299        }
7300    }
7301
7302    @Override
7303    public void enterPictureInPictureMode(IBinder token) {
7304        final long origId = Binder.clearCallingIdentity();
7305        try {
7306            synchronized(this) {
7307                if (!mSupportsPictureInPicture) {
7308                    throw new IllegalStateException("enterPictureInPictureMode: "
7309                            + "Device doesn't support picture-in-picture mode.");
7310                }
7311
7312                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7313
7314                if (r == null) {
7315                    throw new IllegalStateException("enterPictureInPictureMode: "
7316                            + "Can't find activity for token=" + token);
7317                }
7318
7319                if (!r.supportsPictureInPicture()) {
7320                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7321                            + "Picture-In-Picture not supported for r=" + r);
7322                }
7323
7324                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7325                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7326                        ? mDefaultPinnedStackBounds : null;
7327
7328                mStackSupervisor.moveActivityToStackLocked(
7329                        r, PINNED_STACK_ID, "enterPictureInPictureMode", bounds);
7330            }
7331        } finally {
7332            Binder.restoreCallingIdentity(origId);
7333        }
7334    }
7335
7336    // =========================================================
7337    // PROCESS INFO
7338    // =========================================================
7339
7340    static class ProcessInfoService extends IProcessInfoService.Stub {
7341        final ActivityManagerService mActivityManagerService;
7342        ProcessInfoService(ActivityManagerService activityManagerService) {
7343            mActivityManagerService = activityManagerService;
7344        }
7345
7346        @Override
7347        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7348            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7349                    /*in*/ pids, /*out*/ states, null);
7350        }
7351
7352        @Override
7353        public void getProcessStatesAndOomScoresFromPids(
7354                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7355            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7356                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7357        }
7358    }
7359
7360    /**
7361     * For each PID in the given input array, write the current process state
7362     * for that process into the states array, or -1 to indicate that no
7363     * process with the given PID exists. If scores array is provided, write
7364     * the oom score for the process into the scores array, with INVALID_ADJ
7365     * indicating the PID doesn't exist.
7366     */
7367    public void getProcessStatesAndOomScoresForPIDs(
7368            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7369        if (scores != null) {
7370            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7371                    "getProcessStatesAndOomScoresForPIDs()");
7372        }
7373
7374        if (pids == null) {
7375            throw new NullPointerException("pids");
7376        } else if (states == null) {
7377            throw new NullPointerException("states");
7378        } else if (pids.length != states.length) {
7379            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7380        } else if (scores != null && pids.length != scores.length) {
7381            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7382        }
7383
7384        synchronized (mPidsSelfLocked) {
7385            for (int i = 0; i < pids.length; i++) {
7386                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7387                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7388                        pr.curProcState;
7389                if (scores != null) {
7390                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7391                }
7392            }
7393        }
7394    }
7395
7396    // =========================================================
7397    // PERMISSIONS
7398    // =========================================================
7399
7400    static class PermissionController extends IPermissionController.Stub {
7401        ActivityManagerService mActivityManagerService;
7402        PermissionController(ActivityManagerService activityManagerService) {
7403            mActivityManagerService = activityManagerService;
7404        }
7405
7406        @Override
7407        public boolean checkPermission(String permission, int pid, int uid) {
7408            return mActivityManagerService.checkPermission(permission, pid,
7409                    uid) == PackageManager.PERMISSION_GRANTED;
7410        }
7411
7412        @Override
7413        public String[] getPackagesForUid(int uid) {
7414            return mActivityManagerService.mContext.getPackageManager()
7415                    .getPackagesForUid(uid);
7416        }
7417
7418        @Override
7419        public boolean isRuntimePermission(String permission) {
7420            try {
7421                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7422                        .getPermissionInfo(permission, 0);
7423                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7424            } catch (NameNotFoundException nnfe) {
7425                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7426            }
7427            return false;
7428        }
7429    }
7430
7431    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7432        @Override
7433        public int checkComponentPermission(String permission, int pid, int uid,
7434                int owningUid, boolean exported) {
7435            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7436                    owningUid, exported);
7437        }
7438
7439        @Override
7440        public Object getAMSLock() {
7441            return ActivityManagerService.this;
7442        }
7443    }
7444
7445    /**
7446     * This can be called with or without the global lock held.
7447     */
7448    int checkComponentPermission(String permission, int pid, int uid,
7449            int owningUid, boolean exported) {
7450        if (pid == MY_PID) {
7451            return PackageManager.PERMISSION_GRANTED;
7452        }
7453        return ActivityManager.checkComponentPermission(permission, uid,
7454                owningUid, exported);
7455    }
7456
7457    /**
7458     * As the only public entry point for permissions checking, this method
7459     * can enforce the semantic that requesting a check on a null global
7460     * permission is automatically denied.  (Internally a null permission
7461     * string is used when calling {@link #checkComponentPermission} in cases
7462     * when only uid-based security is needed.)
7463     *
7464     * This can be called with or without the global lock held.
7465     */
7466    @Override
7467    public int checkPermission(String permission, int pid, int uid) {
7468        if (permission == null) {
7469            return PackageManager.PERMISSION_DENIED;
7470        }
7471        return checkComponentPermission(permission, pid, uid, -1, true);
7472    }
7473
7474    @Override
7475    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7476        if (permission == null) {
7477            return PackageManager.PERMISSION_DENIED;
7478        }
7479
7480        // We might be performing an operation on behalf of an indirect binder
7481        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7482        // client identity accordingly before proceeding.
7483        Identity tlsIdentity = sCallerIdentity.get();
7484        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7485            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7486                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7487            uid = tlsIdentity.uid;
7488            pid = tlsIdentity.pid;
7489        }
7490
7491        return checkComponentPermission(permission, pid, uid, -1, true);
7492    }
7493
7494    /**
7495     * Binder IPC calls go through the public entry point.
7496     * This can be called with or without the global lock held.
7497     */
7498    int checkCallingPermission(String permission) {
7499        return checkPermission(permission,
7500                Binder.getCallingPid(),
7501                UserHandle.getAppId(Binder.getCallingUid()));
7502    }
7503
7504    /**
7505     * This can be called with or without the global lock held.
7506     */
7507    void enforceCallingPermission(String permission, String func) {
7508        if (checkCallingPermission(permission)
7509                == PackageManager.PERMISSION_GRANTED) {
7510            return;
7511        }
7512
7513        String msg = "Permission Denial: " + func + " from pid="
7514                + Binder.getCallingPid()
7515                + ", uid=" + Binder.getCallingUid()
7516                + " requires " + permission;
7517        Slog.w(TAG, msg);
7518        throw new SecurityException(msg);
7519    }
7520
7521    /**
7522     * Determine if UID is holding permissions required to access {@link Uri} in
7523     * the given {@link ProviderInfo}. Final permission checking is always done
7524     * in {@link ContentProvider}.
7525     */
7526    private final boolean checkHoldingPermissionsLocked(
7527            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7528        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7529                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7530        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7531            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7532                    != PERMISSION_GRANTED) {
7533                return false;
7534            }
7535        }
7536        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7537    }
7538
7539    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7540            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7541        if (pi.applicationInfo.uid == uid) {
7542            return true;
7543        } else if (!pi.exported) {
7544            return false;
7545        }
7546
7547        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7548        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7549        try {
7550            // check if target holds top-level <provider> permissions
7551            if (!readMet && pi.readPermission != null && considerUidPermissions
7552                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7553                readMet = true;
7554            }
7555            if (!writeMet && pi.writePermission != null && considerUidPermissions
7556                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7557                writeMet = true;
7558            }
7559
7560            // track if unprotected read/write is allowed; any denied
7561            // <path-permission> below removes this ability
7562            boolean allowDefaultRead = pi.readPermission == null;
7563            boolean allowDefaultWrite = pi.writePermission == null;
7564
7565            // check if target holds any <path-permission> that match uri
7566            final PathPermission[] pps = pi.pathPermissions;
7567            if (pps != null) {
7568                final String path = grantUri.uri.getPath();
7569                int i = pps.length;
7570                while (i > 0 && (!readMet || !writeMet)) {
7571                    i--;
7572                    PathPermission pp = pps[i];
7573                    if (pp.match(path)) {
7574                        if (!readMet) {
7575                            final String pprperm = pp.getReadPermission();
7576                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7577                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7578                                    + ": match=" + pp.match(path)
7579                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7580                            if (pprperm != null) {
7581                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7582                                        == PERMISSION_GRANTED) {
7583                                    readMet = true;
7584                                } else {
7585                                    allowDefaultRead = false;
7586                                }
7587                            }
7588                        }
7589                        if (!writeMet) {
7590                            final String ppwperm = pp.getWritePermission();
7591                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7592                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7593                                    + ": match=" + pp.match(path)
7594                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7595                            if (ppwperm != null) {
7596                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7597                                        == PERMISSION_GRANTED) {
7598                                    writeMet = true;
7599                                } else {
7600                                    allowDefaultWrite = false;
7601                                }
7602                            }
7603                        }
7604                    }
7605                }
7606            }
7607
7608            // grant unprotected <provider> read/write, if not blocked by
7609            // <path-permission> above
7610            if (allowDefaultRead) readMet = true;
7611            if (allowDefaultWrite) writeMet = true;
7612
7613        } catch (RemoteException e) {
7614            return false;
7615        }
7616
7617        return readMet && writeMet;
7618    }
7619
7620    public int getAppStartMode(int uid, String packageName) {
7621        synchronized (this) {
7622            return checkAllowBackgroundLocked(uid, packageName, -1);
7623        }
7624    }
7625
7626    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7627        UidRecord uidRec = mActiveUids.get(uid);
7628        if (uidRec == null || uidRec.idle) {
7629            if (callingPid >= 0) {
7630                ProcessRecord proc;
7631                synchronized (mPidsSelfLocked) {
7632                    proc = mPidsSelfLocked.get(callingPid);
7633                }
7634                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7635                    // Whoever is instigating this is in the foreground, so we will allow it
7636                    // to go through.
7637                    return ActivityManager.APP_START_MODE_NORMAL;
7638                }
7639            }
7640            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7641                    != AppOpsManager.MODE_ALLOWED) {
7642                return ActivityManager.APP_START_MODE_DELAYED;
7643            }
7644        }
7645        return ActivityManager.APP_START_MODE_NORMAL;
7646    }
7647
7648    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7649        ProviderInfo pi = null;
7650        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7651        if (cpr != null) {
7652            pi = cpr.info;
7653        } else {
7654            try {
7655                pi = AppGlobals.getPackageManager().resolveContentProvider(
7656                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7657            } catch (RemoteException ex) {
7658            }
7659        }
7660        return pi;
7661    }
7662
7663    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7664        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7665        if (targetUris != null) {
7666            return targetUris.get(grantUri);
7667        }
7668        return null;
7669    }
7670
7671    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7672            String targetPkg, int targetUid, GrantUri grantUri) {
7673        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7674        if (targetUris == null) {
7675            targetUris = Maps.newArrayMap();
7676            mGrantedUriPermissions.put(targetUid, targetUris);
7677        }
7678
7679        UriPermission perm = targetUris.get(grantUri);
7680        if (perm == null) {
7681            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7682            targetUris.put(grantUri, perm);
7683        }
7684
7685        return perm;
7686    }
7687
7688    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7689            final int modeFlags) {
7690        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7691        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7692                : UriPermission.STRENGTH_OWNED;
7693
7694        // Root gets to do everything.
7695        if (uid == 0) {
7696            return true;
7697        }
7698
7699        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7700        if (perms == null) return false;
7701
7702        // First look for exact match
7703        final UriPermission exactPerm = perms.get(grantUri);
7704        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7705            return true;
7706        }
7707
7708        // No exact match, look for prefixes
7709        final int N = perms.size();
7710        for (int i = 0; i < N; i++) {
7711            final UriPermission perm = perms.valueAt(i);
7712            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7713                    && perm.getStrength(modeFlags) >= minStrength) {
7714                return true;
7715            }
7716        }
7717
7718        return false;
7719    }
7720
7721    /**
7722     * @param uri This uri must NOT contain an embedded userId.
7723     * @param userId The userId in which the uri is to be resolved.
7724     */
7725    @Override
7726    public int checkUriPermission(Uri uri, int pid, int uid,
7727            final int modeFlags, int userId, IBinder callerToken) {
7728        enforceNotIsolatedCaller("checkUriPermission");
7729
7730        // Another redirected-binder-call permissions check as in
7731        // {@link checkPermissionWithToken}.
7732        Identity tlsIdentity = sCallerIdentity.get();
7733        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7734            uid = tlsIdentity.uid;
7735            pid = tlsIdentity.pid;
7736        }
7737
7738        // Our own process gets to do everything.
7739        if (pid == MY_PID) {
7740            return PackageManager.PERMISSION_GRANTED;
7741        }
7742        synchronized (this) {
7743            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7744                    ? PackageManager.PERMISSION_GRANTED
7745                    : PackageManager.PERMISSION_DENIED;
7746        }
7747    }
7748
7749    /**
7750     * Check if the targetPkg can be granted permission to access uri by
7751     * the callingUid using the given modeFlags.  Throws a security exception
7752     * if callingUid is not allowed to do this.  Returns the uid of the target
7753     * if the URI permission grant should be performed; returns -1 if it is not
7754     * needed (for example targetPkg already has permission to access the URI).
7755     * If you already know the uid of the target, you can supply it in
7756     * lastTargetUid else set that to -1.
7757     */
7758    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7759            final int modeFlags, int lastTargetUid) {
7760        if (!Intent.isAccessUriMode(modeFlags)) {
7761            return -1;
7762        }
7763
7764        if (targetPkg != null) {
7765            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7766                    "Checking grant " + targetPkg + " permission to " + grantUri);
7767        }
7768
7769        final IPackageManager pm = AppGlobals.getPackageManager();
7770
7771        // If this is not a content: uri, we can't do anything with it.
7772        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7773            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7774                    "Can't grant URI permission for non-content URI: " + grantUri);
7775            return -1;
7776        }
7777
7778        final String authority = grantUri.uri.getAuthority();
7779        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7780        if (pi == null) {
7781            Slog.w(TAG, "No content provider found for permission check: " +
7782                    grantUri.uri.toSafeString());
7783            return -1;
7784        }
7785
7786        int targetUid = lastTargetUid;
7787        if (targetUid < 0 && targetPkg != null) {
7788            try {
7789                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7790                        UserHandle.getUserId(callingUid));
7791                if (targetUid < 0) {
7792                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7793                            "Can't grant URI permission no uid for: " + targetPkg);
7794                    return -1;
7795                }
7796            } catch (RemoteException ex) {
7797                return -1;
7798            }
7799        }
7800
7801        if (targetUid >= 0) {
7802            // First...  does the target actually need this permission?
7803            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7804                // No need to grant the target this permission.
7805                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                        "Target " + targetPkg + " already has full permission to " + grantUri);
7807                return -1;
7808            }
7809        } else {
7810            // First...  there is no target package, so can anyone access it?
7811            boolean allowed = pi.exported;
7812            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7813                if (pi.readPermission != null) {
7814                    allowed = false;
7815                }
7816            }
7817            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7818                if (pi.writePermission != null) {
7819                    allowed = false;
7820                }
7821            }
7822            if (allowed) {
7823                return -1;
7824            }
7825        }
7826
7827        /* There is a special cross user grant if:
7828         * - The target is on another user.
7829         * - Apps on the current user can access the uri without any uid permissions.
7830         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7831         * grant uri permissions.
7832         */
7833        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7834                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7835                modeFlags, false /*without considering the uid permissions*/);
7836
7837        // Second...  is the provider allowing granting of URI permissions?
7838        if (!specialCrossUserGrant) {
7839            if (!pi.grantUriPermissions) {
7840                throw new SecurityException("Provider " + pi.packageName
7841                        + "/" + pi.name
7842                        + " does not allow granting of Uri permissions (uri "
7843                        + grantUri + ")");
7844            }
7845            if (pi.uriPermissionPatterns != null) {
7846                final int N = pi.uriPermissionPatterns.length;
7847                boolean allowed = false;
7848                for (int i=0; i<N; i++) {
7849                    if (pi.uriPermissionPatterns[i] != null
7850                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7851                        allowed = true;
7852                        break;
7853                    }
7854                }
7855                if (!allowed) {
7856                    throw new SecurityException("Provider " + pi.packageName
7857                            + "/" + pi.name
7858                            + " does not allow granting of permission to path of Uri "
7859                            + grantUri);
7860                }
7861            }
7862        }
7863
7864        // Third...  does the caller itself have permission to access
7865        // this uri?
7866        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7867            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7868                // Require they hold a strong enough Uri permission
7869                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7870                    throw new SecurityException("Uid " + callingUid
7871                            + " does not have permission to uri " + grantUri);
7872                }
7873            }
7874        }
7875        return targetUid;
7876    }
7877
7878    /**
7879     * @param uri This uri must NOT contain an embedded userId.
7880     * @param userId The userId in which the uri is to be resolved.
7881     */
7882    @Override
7883    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7884            final int modeFlags, int userId) {
7885        enforceNotIsolatedCaller("checkGrantUriPermission");
7886        synchronized(this) {
7887            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7888                    new GrantUri(userId, uri, false), modeFlags, -1);
7889        }
7890    }
7891
7892    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7893            final int modeFlags, UriPermissionOwner owner) {
7894        if (!Intent.isAccessUriMode(modeFlags)) {
7895            return;
7896        }
7897
7898        // So here we are: the caller has the assumed permission
7899        // to the uri, and the target doesn't.  Let's now give this to
7900        // the target.
7901
7902        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7903                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7904
7905        final String authority = grantUri.uri.getAuthority();
7906        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7907        if (pi == null) {
7908            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7909            return;
7910        }
7911
7912        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7913            grantUri.prefix = true;
7914        }
7915        final UriPermission perm = findOrCreateUriPermissionLocked(
7916                pi.packageName, targetPkg, targetUid, grantUri);
7917        perm.grantModes(modeFlags, owner);
7918    }
7919
7920    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7921            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7922        if (targetPkg == null) {
7923            throw new NullPointerException("targetPkg");
7924        }
7925        int targetUid;
7926        final IPackageManager pm = AppGlobals.getPackageManager();
7927        try {
7928            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7929        } catch (RemoteException ex) {
7930            return;
7931        }
7932
7933        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7934                targetUid);
7935        if (targetUid < 0) {
7936            return;
7937        }
7938
7939        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7940                owner);
7941    }
7942
7943    static class NeededUriGrants extends ArrayList<GrantUri> {
7944        final String targetPkg;
7945        final int targetUid;
7946        final int flags;
7947
7948        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7949            this.targetPkg = targetPkg;
7950            this.targetUid = targetUid;
7951            this.flags = flags;
7952        }
7953    }
7954
7955    /**
7956     * Like checkGrantUriPermissionLocked, but takes an Intent.
7957     */
7958    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7959            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7960        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7961                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7962                + " clip=" + (intent != null ? intent.getClipData() : null)
7963                + " from " + intent + "; flags=0x"
7964                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7965
7966        if (targetPkg == null) {
7967            throw new NullPointerException("targetPkg");
7968        }
7969
7970        if (intent == null) {
7971            return null;
7972        }
7973        Uri data = intent.getData();
7974        ClipData clip = intent.getClipData();
7975        if (data == null && clip == null) {
7976            return null;
7977        }
7978        // Default userId for uris in the intent (if they don't specify it themselves)
7979        int contentUserHint = intent.getContentUserHint();
7980        if (contentUserHint == UserHandle.USER_CURRENT) {
7981            contentUserHint = UserHandle.getUserId(callingUid);
7982        }
7983        final IPackageManager pm = AppGlobals.getPackageManager();
7984        int targetUid;
7985        if (needed != null) {
7986            targetUid = needed.targetUid;
7987        } else {
7988            try {
7989                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7990                        targetUserId);
7991            } catch (RemoteException ex) {
7992                return null;
7993            }
7994            if (targetUid < 0) {
7995                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7996                        "Can't grant URI permission no uid for: " + targetPkg
7997                        + " on user " + targetUserId);
7998                return null;
7999            }
8000        }
8001        if (data != null) {
8002            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8003            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8004                    targetUid);
8005            if (targetUid > 0) {
8006                if (needed == null) {
8007                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8008                }
8009                needed.add(grantUri);
8010            }
8011        }
8012        if (clip != null) {
8013            for (int i=0; i<clip.getItemCount(); i++) {
8014                Uri uri = clip.getItemAt(i).getUri();
8015                if (uri != null) {
8016                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8017                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8018                            targetUid);
8019                    if (targetUid > 0) {
8020                        if (needed == null) {
8021                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8022                        }
8023                        needed.add(grantUri);
8024                    }
8025                } else {
8026                    Intent clipIntent = clip.getItemAt(i).getIntent();
8027                    if (clipIntent != null) {
8028                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8029                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8030                        if (newNeeded != null) {
8031                            needed = newNeeded;
8032                        }
8033                    }
8034                }
8035            }
8036        }
8037
8038        return needed;
8039    }
8040
8041    /**
8042     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8043     */
8044    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8045            UriPermissionOwner owner) {
8046        if (needed != null) {
8047            for (int i=0; i<needed.size(); i++) {
8048                GrantUri grantUri = needed.get(i);
8049                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8050                        grantUri, needed.flags, owner);
8051            }
8052        }
8053    }
8054
8055    void grantUriPermissionFromIntentLocked(int callingUid,
8056            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8057        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8058                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8059        if (needed == null) {
8060            return;
8061        }
8062
8063        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8064    }
8065
8066    /**
8067     * @param uri This uri must NOT contain an embedded userId.
8068     * @param userId The userId in which the uri is to be resolved.
8069     */
8070    @Override
8071    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8072            final int modeFlags, int userId) {
8073        enforceNotIsolatedCaller("grantUriPermission");
8074        GrantUri grantUri = new GrantUri(userId, uri, false);
8075        synchronized(this) {
8076            final ProcessRecord r = getRecordForAppLocked(caller);
8077            if (r == null) {
8078                throw new SecurityException("Unable to find app for caller "
8079                        + caller
8080                        + " when granting permission to uri " + grantUri);
8081            }
8082            if (targetPkg == null) {
8083                throw new IllegalArgumentException("null target");
8084            }
8085            if (grantUri == null) {
8086                throw new IllegalArgumentException("null uri");
8087            }
8088
8089            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8090                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8091                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8092                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8093
8094            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8095                    UserHandle.getUserId(r.uid));
8096        }
8097    }
8098
8099    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8100        if (perm.modeFlags == 0) {
8101            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8102                    perm.targetUid);
8103            if (perms != null) {
8104                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8105                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8106
8107                perms.remove(perm.uri);
8108                if (perms.isEmpty()) {
8109                    mGrantedUriPermissions.remove(perm.targetUid);
8110                }
8111            }
8112        }
8113    }
8114
8115    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8116        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8117                "Revoking all granted permissions to " + grantUri);
8118
8119        final IPackageManager pm = AppGlobals.getPackageManager();
8120        final String authority = grantUri.uri.getAuthority();
8121        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8122        if (pi == null) {
8123            Slog.w(TAG, "No content provider found for permission revoke: "
8124                    + grantUri.toSafeString());
8125            return;
8126        }
8127
8128        // Does the caller have this permission on the URI?
8129        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8130            // If they don't have direct access to the URI, then revoke any
8131            // ownerless URI permissions that have been granted to them.
8132            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8133            if (perms != null) {
8134                boolean persistChanged = false;
8135                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8136                    final UriPermission perm = it.next();
8137                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8138                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8139                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8140                                "Revoking non-owned " + perm.targetUid
8141                                + " permission to " + perm.uri);
8142                        persistChanged |= perm.revokeModes(
8143                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8144                        if (perm.modeFlags == 0) {
8145                            it.remove();
8146                        }
8147                    }
8148                }
8149                if (perms.isEmpty()) {
8150                    mGrantedUriPermissions.remove(callingUid);
8151                }
8152                if (persistChanged) {
8153                    schedulePersistUriGrants();
8154                }
8155            }
8156            return;
8157        }
8158
8159        boolean persistChanged = false;
8160
8161        // Go through all of the permissions and remove any that match.
8162        int N = mGrantedUriPermissions.size();
8163        for (int i = 0; i < N; i++) {
8164            final int targetUid = mGrantedUriPermissions.keyAt(i);
8165            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8166
8167            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8168                final UriPermission perm = it.next();
8169                if (perm.uri.sourceUserId == grantUri.sourceUserId
8170                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8171                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8173                    persistChanged |= perm.revokeModes(
8174                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8175                    if (perm.modeFlags == 0) {
8176                        it.remove();
8177                    }
8178                }
8179            }
8180
8181            if (perms.isEmpty()) {
8182                mGrantedUriPermissions.remove(targetUid);
8183                N--;
8184                i--;
8185            }
8186        }
8187
8188        if (persistChanged) {
8189            schedulePersistUriGrants();
8190        }
8191    }
8192
8193    /**
8194     * @param uri This uri must NOT contain an embedded userId.
8195     * @param userId The userId in which the uri is to be resolved.
8196     */
8197    @Override
8198    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8199            int userId) {
8200        enforceNotIsolatedCaller("revokeUriPermission");
8201        synchronized(this) {
8202            final ProcessRecord r = getRecordForAppLocked(caller);
8203            if (r == null) {
8204                throw new SecurityException("Unable to find app for caller "
8205                        + caller
8206                        + " when revoking permission to uri " + uri);
8207            }
8208            if (uri == null) {
8209                Slog.w(TAG, "revokeUriPermission: null uri");
8210                return;
8211            }
8212
8213            if (!Intent.isAccessUriMode(modeFlags)) {
8214                return;
8215            }
8216
8217            final String authority = uri.getAuthority();
8218            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8219            if (pi == null) {
8220                Slog.w(TAG, "No content provider found for permission revoke: "
8221                        + uri.toSafeString());
8222                return;
8223            }
8224
8225            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8226        }
8227    }
8228
8229    /**
8230     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8231     * given package.
8232     *
8233     * @param packageName Package name to match, or {@code null} to apply to all
8234     *            packages.
8235     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8236     *            to all users.
8237     * @param persistable If persistable grants should be removed.
8238     */
8239    private void removeUriPermissionsForPackageLocked(
8240            String packageName, int userHandle, boolean persistable) {
8241        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8242            throw new IllegalArgumentException("Must narrow by either package or user");
8243        }
8244
8245        boolean persistChanged = false;
8246
8247        int N = mGrantedUriPermissions.size();
8248        for (int i = 0; i < N; i++) {
8249            final int targetUid = mGrantedUriPermissions.keyAt(i);
8250            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8251
8252            // Only inspect grants matching user
8253            if (userHandle == UserHandle.USER_ALL
8254                    || userHandle == UserHandle.getUserId(targetUid)) {
8255                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8256                    final UriPermission perm = it.next();
8257
8258                    // Only inspect grants matching package
8259                    if (packageName == null || perm.sourcePkg.equals(packageName)
8260                            || perm.targetPkg.equals(packageName)) {
8261                        persistChanged |= perm.revokeModes(persistable
8262                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8263
8264                        // Only remove when no modes remain; any persisted grants
8265                        // will keep this alive.
8266                        if (perm.modeFlags == 0) {
8267                            it.remove();
8268                        }
8269                    }
8270                }
8271
8272                if (perms.isEmpty()) {
8273                    mGrantedUriPermissions.remove(targetUid);
8274                    N--;
8275                    i--;
8276                }
8277            }
8278        }
8279
8280        if (persistChanged) {
8281            schedulePersistUriGrants();
8282        }
8283    }
8284
8285    @Override
8286    public IBinder newUriPermissionOwner(String name) {
8287        enforceNotIsolatedCaller("newUriPermissionOwner");
8288        synchronized(this) {
8289            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8290            return owner.getExternalTokenLocked();
8291        }
8292    }
8293
8294    @Override
8295    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8296        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8297        synchronized(this) {
8298            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8299            if (r == null) {
8300                throw new IllegalArgumentException("Activity does not exist; token="
8301                        + activityToken);
8302            }
8303            return r.getUriPermissionsLocked().getExternalTokenLocked();
8304        }
8305    }
8306    /**
8307     * @param uri This uri must NOT contain an embedded userId.
8308     * @param sourceUserId The userId in which the uri is to be resolved.
8309     * @param targetUserId The userId of the app that receives the grant.
8310     */
8311    @Override
8312    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8313            final int modeFlags, int sourceUserId, int targetUserId) {
8314        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8315                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8316                "grantUriPermissionFromOwner", null);
8317        synchronized(this) {
8318            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8319            if (owner == null) {
8320                throw new IllegalArgumentException("Unknown owner: " + token);
8321            }
8322            if (fromUid != Binder.getCallingUid()) {
8323                if (Binder.getCallingUid() != Process.myUid()) {
8324                    // Only system code can grant URI permissions on behalf
8325                    // of other users.
8326                    throw new SecurityException("nice try");
8327                }
8328            }
8329            if (targetPkg == null) {
8330                throw new IllegalArgumentException("null target");
8331            }
8332            if (uri == null) {
8333                throw new IllegalArgumentException("null uri");
8334            }
8335
8336            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8337                    modeFlags, owner, targetUserId);
8338        }
8339    }
8340
8341    /**
8342     * @param uri This uri must NOT contain an embedded userId.
8343     * @param userId The userId in which the uri is to be resolved.
8344     */
8345    @Override
8346    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8347        synchronized(this) {
8348            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8349            if (owner == null) {
8350                throw new IllegalArgumentException("Unknown owner: " + token);
8351            }
8352
8353            if (uri == null) {
8354                owner.removeUriPermissionsLocked(mode);
8355            } else {
8356                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8357            }
8358        }
8359    }
8360
8361    private void schedulePersistUriGrants() {
8362        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8363            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8364                    10 * DateUtils.SECOND_IN_MILLIS);
8365        }
8366    }
8367
8368    private void writeGrantedUriPermissions() {
8369        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8370
8371        // Snapshot permissions so we can persist without lock
8372        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8373        synchronized (this) {
8374            final int size = mGrantedUriPermissions.size();
8375            for (int i = 0; i < size; i++) {
8376                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8377                for (UriPermission perm : perms.values()) {
8378                    if (perm.persistedModeFlags != 0) {
8379                        persist.add(perm.snapshot());
8380                    }
8381                }
8382            }
8383        }
8384
8385        FileOutputStream fos = null;
8386        try {
8387            fos = mGrantFile.startWrite();
8388
8389            XmlSerializer out = new FastXmlSerializer();
8390            out.setOutput(fos, StandardCharsets.UTF_8.name());
8391            out.startDocument(null, true);
8392            out.startTag(null, TAG_URI_GRANTS);
8393            for (UriPermission.Snapshot perm : persist) {
8394                out.startTag(null, TAG_URI_GRANT);
8395                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8396                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8397                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8398                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8399                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8400                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8401                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8402                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8403                out.endTag(null, TAG_URI_GRANT);
8404            }
8405            out.endTag(null, TAG_URI_GRANTS);
8406            out.endDocument();
8407
8408            mGrantFile.finishWrite(fos);
8409        } catch (IOException e) {
8410            if (fos != null) {
8411                mGrantFile.failWrite(fos);
8412            }
8413        }
8414    }
8415
8416    private void readGrantedUriPermissionsLocked() {
8417        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8418
8419        final long now = System.currentTimeMillis();
8420
8421        FileInputStream fis = null;
8422        try {
8423            fis = mGrantFile.openRead();
8424            final XmlPullParser in = Xml.newPullParser();
8425            in.setInput(fis, StandardCharsets.UTF_8.name());
8426
8427            int type;
8428            while ((type = in.next()) != END_DOCUMENT) {
8429                final String tag = in.getName();
8430                if (type == START_TAG) {
8431                    if (TAG_URI_GRANT.equals(tag)) {
8432                        final int sourceUserId;
8433                        final int targetUserId;
8434                        final int userHandle = readIntAttribute(in,
8435                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8436                        if (userHandle != UserHandle.USER_NULL) {
8437                            // For backwards compatibility.
8438                            sourceUserId = userHandle;
8439                            targetUserId = userHandle;
8440                        } else {
8441                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8442                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8443                        }
8444                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8445                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8446                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8447                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8448                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8449                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8450
8451                        // Sanity check that provider still belongs to source package
8452                        final ProviderInfo pi = getProviderInfoLocked(
8453                                uri.getAuthority(), sourceUserId);
8454                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8455                            int targetUid = -1;
8456                            try {
8457                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8458                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8459                            } catch (RemoteException e) {
8460                            }
8461                            if (targetUid != -1) {
8462                                final UriPermission perm = findOrCreateUriPermissionLocked(
8463                                        sourcePkg, targetPkg, targetUid,
8464                                        new GrantUri(sourceUserId, uri, prefix));
8465                                perm.initPersistedModes(modeFlags, createdTime);
8466                            }
8467                        } else {
8468                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8469                                    + " but instead found " + pi);
8470                        }
8471                    }
8472                }
8473            }
8474        } catch (FileNotFoundException e) {
8475            // Missing grants is okay
8476        } catch (IOException e) {
8477            Slog.wtf(TAG, "Failed reading Uri grants", e);
8478        } catch (XmlPullParserException e) {
8479            Slog.wtf(TAG, "Failed reading Uri grants", e);
8480        } finally {
8481            IoUtils.closeQuietly(fis);
8482        }
8483    }
8484
8485    /**
8486     * @param uri This uri must NOT contain an embedded userId.
8487     * @param userId The userId in which the uri is to be resolved.
8488     */
8489    @Override
8490    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8491        enforceNotIsolatedCaller("takePersistableUriPermission");
8492
8493        Preconditions.checkFlagsArgument(modeFlags,
8494                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8495
8496        synchronized (this) {
8497            final int callingUid = Binder.getCallingUid();
8498            boolean persistChanged = false;
8499            GrantUri grantUri = new GrantUri(userId, uri, false);
8500
8501            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8502                    new GrantUri(userId, uri, false));
8503            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8504                    new GrantUri(userId, uri, true));
8505
8506            final boolean exactValid = (exactPerm != null)
8507                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8508            final boolean prefixValid = (prefixPerm != null)
8509                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8510
8511            if (!(exactValid || prefixValid)) {
8512                throw new SecurityException("No persistable permission grants found for UID "
8513                        + callingUid + " and Uri " + grantUri.toSafeString());
8514            }
8515
8516            if (exactValid) {
8517                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8518            }
8519            if (prefixValid) {
8520                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8521            }
8522
8523            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8524
8525            if (persistChanged) {
8526                schedulePersistUriGrants();
8527            }
8528        }
8529    }
8530
8531    /**
8532     * @param uri This uri must NOT contain an embedded userId.
8533     * @param userId The userId in which the uri is to be resolved.
8534     */
8535    @Override
8536    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8537        enforceNotIsolatedCaller("releasePersistableUriPermission");
8538
8539        Preconditions.checkFlagsArgument(modeFlags,
8540                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8541
8542        synchronized (this) {
8543            final int callingUid = Binder.getCallingUid();
8544            boolean persistChanged = false;
8545
8546            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8547                    new GrantUri(userId, uri, false));
8548            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8549                    new GrantUri(userId, uri, true));
8550            if (exactPerm == null && prefixPerm == null) {
8551                throw new SecurityException("No permission grants found for UID " + callingUid
8552                        + " and Uri " + uri.toSafeString());
8553            }
8554
8555            if (exactPerm != null) {
8556                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8557                removeUriPermissionIfNeededLocked(exactPerm);
8558            }
8559            if (prefixPerm != null) {
8560                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8561                removeUriPermissionIfNeededLocked(prefixPerm);
8562            }
8563
8564            if (persistChanged) {
8565                schedulePersistUriGrants();
8566            }
8567        }
8568    }
8569
8570    /**
8571     * Prune any older {@link UriPermission} for the given UID until outstanding
8572     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8573     *
8574     * @return if any mutations occured that require persisting.
8575     */
8576    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8577        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8578        if (perms == null) return false;
8579        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8580
8581        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8582        for (UriPermission perm : perms.values()) {
8583            if (perm.persistedModeFlags != 0) {
8584                persisted.add(perm);
8585            }
8586        }
8587
8588        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8589        if (trimCount <= 0) return false;
8590
8591        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8592        for (int i = 0; i < trimCount; i++) {
8593            final UriPermission perm = persisted.get(i);
8594
8595            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8596                    "Trimming grant created at " + perm.persistedCreateTime);
8597
8598            perm.releasePersistableModes(~0);
8599            removeUriPermissionIfNeededLocked(perm);
8600        }
8601
8602        return true;
8603    }
8604
8605    @Override
8606    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8607            String packageName, boolean incoming) {
8608        enforceNotIsolatedCaller("getPersistedUriPermissions");
8609        Preconditions.checkNotNull(packageName, "packageName");
8610
8611        final int callingUid = Binder.getCallingUid();
8612        final IPackageManager pm = AppGlobals.getPackageManager();
8613        try {
8614            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8615                    UserHandle.getUserId(callingUid));
8616            if (packageUid != callingUid) {
8617                throw new SecurityException(
8618                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8619            }
8620        } catch (RemoteException e) {
8621            throw new SecurityException("Failed to verify package name ownership");
8622        }
8623
8624        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8625        synchronized (this) {
8626            if (incoming) {
8627                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8628                        callingUid);
8629                if (perms == null) {
8630                    Slog.w(TAG, "No permission grants found for " + packageName);
8631                } else {
8632                    for (UriPermission perm : perms.values()) {
8633                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8634                            result.add(perm.buildPersistedPublicApiObject());
8635                        }
8636                    }
8637                }
8638            } else {
8639                final int size = mGrantedUriPermissions.size();
8640                for (int i = 0; i < size; i++) {
8641                    final ArrayMap<GrantUri, UriPermission> perms =
8642                            mGrantedUriPermissions.valueAt(i);
8643                    for (UriPermission perm : perms.values()) {
8644                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8645                            result.add(perm.buildPersistedPublicApiObject());
8646                        }
8647                    }
8648                }
8649            }
8650        }
8651        return new ParceledListSlice<android.content.UriPermission>(result);
8652    }
8653
8654    @Override
8655    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8656            String packageName, int userId) {
8657        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8658                "getGrantedUriPermissions");
8659
8660        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8661        synchronized (this) {
8662            final int size = mGrantedUriPermissions.size();
8663            for (int i = 0; i < size; i++) {
8664                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8665                for (UriPermission perm : perms.values()) {
8666                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8667                            && perm.persistedModeFlags != 0) {
8668                        result.add(perm.buildPersistedPublicApiObject());
8669                    }
8670                }
8671            }
8672        }
8673        return new ParceledListSlice<android.content.UriPermission>(result);
8674    }
8675
8676    @Override
8677    public void clearGrantedUriPermissions(String packageName, int userId) {
8678        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8679                "clearGrantedUriPermissions");
8680        removeUriPermissionsForPackageLocked(packageName, userId, true);
8681    }
8682
8683    @Override
8684    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8685        synchronized (this) {
8686            ProcessRecord app =
8687                who != null ? getRecordForAppLocked(who) : null;
8688            if (app == null) return;
8689
8690            Message msg = Message.obtain();
8691            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8692            msg.obj = app;
8693            msg.arg1 = waiting ? 1 : 0;
8694            mUiHandler.sendMessage(msg);
8695        }
8696    }
8697
8698    @Override
8699    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8700        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8701        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8702        outInfo.availMem = Process.getFreeMemory();
8703        outInfo.totalMem = Process.getTotalMemory();
8704        outInfo.threshold = homeAppMem;
8705        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8706        outInfo.hiddenAppThreshold = cachedAppMem;
8707        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8708                ProcessList.SERVICE_ADJ);
8709        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8710                ProcessList.VISIBLE_APP_ADJ);
8711        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8712                ProcessList.FOREGROUND_APP_ADJ);
8713    }
8714
8715    // =========================================================
8716    // TASK MANAGEMENT
8717    // =========================================================
8718
8719    @Override
8720    public List<IAppTask> getAppTasks(String callingPackage) {
8721        int callingUid = Binder.getCallingUid();
8722        long ident = Binder.clearCallingIdentity();
8723
8724        synchronized(this) {
8725            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8726            try {
8727                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8728
8729                final int N = mRecentTasks.size();
8730                for (int i = 0; i < N; i++) {
8731                    TaskRecord tr = mRecentTasks.get(i);
8732                    // Skip tasks that do not match the caller.  We don't need to verify
8733                    // callingPackage, because we are also limiting to callingUid and know
8734                    // that will limit to the correct security sandbox.
8735                    if (tr.effectiveUid != callingUid) {
8736                        continue;
8737                    }
8738                    Intent intent = tr.getBaseIntent();
8739                    if (intent == null ||
8740                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8741                        continue;
8742                    }
8743                    ActivityManager.RecentTaskInfo taskInfo =
8744                            createRecentTaskInfoFromTaskRecord(tr);
8745                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8746                    list.add(taskImpl);
8747                }
8748            } finally {
8749                Binder.restoreCallingIdentity(ident);
8750            }
8751            return list;
8752        }
8753    }
8754
8755    @Override
8756    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8757        final int callingUid = Binder.getCallingUid();
8758        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8759
8760        synchronized(this) {
8761            if (DEBUG_ALL) Slog.v(
8762                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8763
8764            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8765                    callingUid);
8766
8767            // TODO: Improve with MRU list from all ActivityStacks.
8768            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8769        }
8770
8771        return list;
8772    }
8773
8774    /**
8775     * Creates a new RecentTaskInfo from a TaskRecord.
8776     */
8777    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8778        // Update the task description to reflect any changes in the task stack
8779        tr.updateTaskDescription();
8780
8781        // Compose the recent task info
8782        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8783        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8784        rti.persistentId = tr.taskId;
8785        rti.baseIntent = new Intent(tr.getBaseIntent());
8786        rti.origActivity = tr.origActivity;
8787        rti.realActivity = tr.realActivity;
8788        rti.description = tr.lastDescription;
8789        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8790        rti.userId = tr.userId;
8791        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8792        rti.firstActiveTime = tr.firstActiveTime;
8793        rti.lastActiveTime = tr.lastActiveTime;
8794        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8795        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8796        rti.numActivities = 0;
8797        if (tr.mBounds != null) {
8798            rti.bounds = new Rect(tr.mBounds);
8799        }
8800
8801        ActivityRecord base = null;
8802        ActivityRecord top = null;
8803        ActivityRecord tmp;
8804
8805        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8806            tmp = tr.mActivities.get(i);
8807            if (tmp.finishing) {
8808                continue;
8809            }
8810            base = tmp;
8811            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8812                top = base;
8813            }
8814            rti.numActivities++;
8815        }
8816
8817        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8818        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8819
8820        return rti;
8821    }
8822
8823    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8824        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8825                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8826        if (!allowed) {
8827            if (checkPermission(android.Manifest.permission.GET_TASKS,
8828                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8829                // Temporary compatibility: some existing apps on the system image may
8830                // still be requesting the old permission and not switched to the new
8831                // one; if so, we'll still allow them full access.  This means we need
8832                // to see if they are holding the old permission and are a system app.
8833                try {
8834                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8835                        allowed = true;
8836                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8837                                + " is using old GET_TASKS but privileged; allowing");
8838                    }
8839                } catch (RemoteException e) {
8840                }
8841            }
8842        }
8843        if (!allowed) {
8844            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8845                    + " does not hold REAL_GET_TASKS; limiting output");
8846        }
8847        return allowed;
8848    }
8849
8850    @Override
8851    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8852        final int callingUid = Binder.getCallingUid();
8853        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8854                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8855
8856        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8857        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8858        synchronized (this) {
8859            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8860                    callingUid);
8861            final boolean detailed = checkCallingPermission(
8862                    android.Manifest.permission.GET_DETAILED_TASKS)
8863                    == PackageManager.PERMISSION_GRANTED;
8864
8865            mRecentTasks.loadUserRecentsLocked(userId);
8866
8867            final int recentsCount = mRecentTasks.size();
8868            ArrayList<ActivityManager.RecentTaskInfo> res =
8869                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8870
8871            final Set<Integer> includedUsers;
8872            if (includeProfiles) {
8873                includedUsers = mUserController.getProfileIds(userId);
8874            } else {
8875                includedUsers = new HashSet<>();
8876            }
8877            includedUsers.add(Integer.valueOf(userId));
8878
8879            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8880                TaskRecord tr = mRecentTasks.get(i);
8881                // Only add calling user or related users recent tasks
8882                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8883                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8884                    continue;
8885                }
8886
8887                // Return the entry if desired by the caller.  We always return
8888                // the first entry, because callers always expect this to be the
8889                // foreground app.  We may filter others if the caller has
8890                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8891                // we should exclude the entry.
8892
8893                if (i == 0
8894                        || withExcluded
8895                        || (tr.intent == null)
8896                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8897                                == 0)) {
8898                    if (!allowed) {
8899                        // If the caller doesn't have the GET_TASKS permission, then only
8900                        // allow them to see a small subset of tasks -- their own and home.
8901                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8902                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8903                            continue;
8904                        }
8905                    }
8906                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8907                        if (tr.stack != null && tr.stack.isHomeStack()) {
8908                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8909                                    "Skipping, home stack task: " + tr);
8910                            continue;
8911                        }
8912                    }
8913                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8914                        if (tr.stack != null && tr.stack.isDockedStack()) {
8915                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8916                                    "Skipping, docked stack task: " + tr);
8917                            continue;
8918                        }
8919                    }
8920                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8921                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8922                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8923                                    "Skipping, pinned stack task: " + tr);
8924                            continue;
8925                        }
8926                    }
8927                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8928                        // Don't include auto remove tasks that are finished or finishing.
8929                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8930                                "Skipping, auto-remove without activity: " + tr);
8931                        continue;
8932                    }
8933                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8934                            && !tr.isAvailable) {
8935                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8936                                "Skipping, unavail real act: " + tr);
8937                        continue;
8938                    }
8939
8940                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8941                    if (!detailed) {
8942                        rti.baseIntent.replaceExtras((Bundle)null);
8943                    }
8944
8945                    res.add(rti);
8946                    maxNum--;
8947                }
8948            }
8949            return res;
8950        }
8951    }
8952
8953    @Override
8954    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8955        synchronized (this) {
8956            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8957                    "getTaskThumbnail()");
8958            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8959                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8960            if (tr != null) {
8961                return tr.getTaskThumbnailLocked();
8962            }
8963        }
8964        return null;
8965    }
8966
8967    @Override
8968    public int addAppTask(IBinder activityToken, Intent intent,
8969            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8970        final int callingUid = Binder.getCallingUid();
8971        final long callingIdent = Binder.clearCallingIdentity();
8972
8973        try {
8974            synchronized (this) {
8975                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8976                if (r == null) {
8977                    throw new IllegalArgumentException("Activity does not exist; token="
8978                            + activityToken);
8979                }
8980                ComponentName comp = intent.getComponent();
8981                if (comp == null) {
8982                    throw new IllegalArgumentException("Intent " + intent
8983                            + " must specify explicit component");
8984                }
8985                if (thumbnail.getWidth() != mThumbnailWidth
8986                        || thumbnail.getHeight() != mThumbnailHeight) {
8987                    throw new IllegalArgumentException("Bad thumbnail size: got "
8988                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8989                            + mThumbnailWidth + "x" + mThumbnailHeight);
8990                }
8991                if (intent.getSelector() != null) {
8992                    intent.setSelector(null);
8993                }
8994                if (intent.getSourceBounds() != null) {
8995                    intent.setSourceBounds(null);
8996                }
8997                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8998                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8999                        // The caller has added this as an auto-remove task...  that makes no
9000                        // sense, so turn off auto-remove.
9001                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9002                    }
9003                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9004                    // Must be a new task.
9005                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9006                }
9007                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9008                    mLastAddedTaskActivity = null;
9009                }
9010                ActivityInfo ainfo = mLastAddedTaskActivity;
9011                if (ainfo == null) {
9012                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9013                            comp, 0, UserHandle.getUserId(callingUid));
9014                    if (ainfo.applicationInfo.uid != callingUid) {
9015                        throw new SecurityException(
9016                                "Can't add task for another application: target uid="
9017                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9018                    }
9019                }
9020
9021                // Use the full screen as the context for the task thumbnail
9022                final Point displaySize = new Point();
9023                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9024                r.task.stack.getDisplaySize(displaySize);
9025                thumbnailInfo.taskWidth = displaySize.x;
9026                thumbnailInfo.taskHeight = displaySize.y;
9027                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9028
9029                TaskRecord task = new TaskRecord(this,
9030                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9031                        ainfo, intent, description, thumbnailInfo);
9032
9033                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9034                if (trimIdx >= 0) {
9035                    // If this would have caused a trim, then we'll abort because that
9036                    // means it would be added at the end of the list but then just removed.
9037                    return INVALID_TASK_ID;
9038                }
9039
9040                final int N = mRecentTasks.size();
9041                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9042                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9043                    tr.removedFromRecents();
9044                }
9045
9046                task.inRecents = true;
9047                mRecentTasks.add(task);
9048                r.task.stack.addTask(task, false, "addAppTask");
9049
9050                task.setLastThumbnailLocked(thumbnail);
9051                task.freeLastThumbnail();
9052
9053                return task.taskId;
9054            }
9055        } finally {
9056            Binder.restoreCallingIdentity(callingIdent);
9057        }
9058    }
9059
9060    @Override
9061    public Point getAppTaskThumbnailSize() {
9062        synchronized (this) {
9063            return new Point(mThumbnailWidth,  mThumbnailHeight);
9064        }
9065    }
9066
9067    @Override
9068    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9069        synchronized (this) {
9070            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9071            if (r != null) {
9072                r.setTaskDescription(td);
9073                r.task.updateTaskDescription();
9074            }
9075        }
9076    }
9077
9078    @Override
9079    public void setTaskResizeable(int taskId, boolean resizeable) {
9080        synchronized (this) {
9081            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9082                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9083            if (task == null) {
9084                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9085                return;
9086            }
9087            if (task.mResizeable != resizeable) {
9088                task.mResizeable = resizeable;
9089                mWindowManager.setTaskResizeable(taskId, resizeable);
9090                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9091                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9092            }
9093        }
9094    }
9095
9096    @Override
9097    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9098        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9099        long ident = Binder.clearCallingIdentity();
9100        try {
9101            synchronized (this) {
9102                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9103                if (task == null) {
9104                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9105                    return;
9106                }
9107                int stackId = task.stack.mStackId;
9108                // First, check if this is a non-resizeble task in docked stack or if the task size
9109                // is affected by the docked stack changing size. If so, instead of resizing, we
9110                // can only scroll the task. No need to update configuration.
9111                if (bounds != null && !task.mResizeable
9112                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9113                    mWindowManager.scrollTask(task.taskId, bounds);
9114                    return;
9115                }
9116
9117                // Place the task in the right stack if it isn't there already based on
9118                // the requested bounds.
9119                // The stack transition logic is:
9120                // - a null bounds on a freeform task moves that task to fullscreen
9121                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9122                //   that task to freeform
9123                // - otherwise the task is not moved
9124                if (!StackId.isTaskResizeAllowed(stackId)) {
9125                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9126                }
9127                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9128                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9129                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9130                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9131                }
9132                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9133                if (stackId != task.stack.mStackId) {
9134                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9135                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9136                    preserveWindow = false;
9137                }
9138
9139                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9140            }
9141        } finally {
9142            Binder.restoreCallingIdentity(ident);
9143        }
9144    }
9145
9146    @Override
9147    public Rect getTaskBounds(int taskId) {
9148        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9149        long ident = Binder.clearCallingIdentity();
9150        Rect rect = new Rect();
9151        try {
9152            synchronized (this) {
9153                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9154                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9155                if (task == null) {
9156                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9157                    return rect;
9158                }
9159                if (task.stack != null) {
9160                    // Return the bounds from window manager since it will be adjusted for various
9161                    // things like the presense of a docked stack for tasks that aren't resizeable.
9162                    mWindowManager.getTaskBounds(task.taskId, rect);
9163                } else {
9164                    // Task isn't in window manager yet since it isn't associated with a stack.
9165                    // Return the persist value from activity manager
9166                    if (task.mBounds != null) {
9167                        rect.set(task.mBounds);
9168                    } else if (task.mLastNonFullscreenBounds != null) {
9169                        rect.set(task.mLastNonFullscreenBounds);
9170                    }
9171                }
9172            }
9173        } finally {
9174            Binder.restoreCallingIdentity(ident);
9175        }
9176        return rect;
9177    }
9178
9179    @Override
9180    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9181        if (userId != UserHandle.getCallingUserId()) {
9182            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9183                    "getTaskDescriptionIcon");
9184        }
9185        final File passedIconFile = new File(filePath);
9186        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9187                passedIconFile.getName());
9188        if (!legitIconFile.getPath().equals(filePath)
9189                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9190            throw new IllegalArgumentException("Bad file path: " + filePath
9191                    + " passed for userId " + userId);
9192        }
9193        return mRecentTasks.getTaskDescriptionIcon(filePath);
9194    }
9195
9196    @Override
9197    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9198            throws RemoteException {
9199        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9200                opts.getCustomInPlaceResId() == 0) {
9201            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9202                    "with valid animation");
9203        }
9204        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9205        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9206                opts.getCustomInPlaceResId());
9207        mWindowManager.executeAppTransition();
9208    }
9209
9210    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9211            boolean removeFromRecents) {
9212        if (removeFromRecents) {
9213            mRecentTasks.remove(tr);
9214            tr.removedFromRecents();
9215        }
9216        ComponentName component = tr.getBaseIntent().getComponent();
9217        if (component == null) {
9218            Slog.w(TAG, "No component for base intent of task: " + tr);
9219            return;
9220        }
9221
9222        // Find any running services associated with this app and stop if needed.
9223        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9224
9225        if (!killProcess) {
9226            return;
9227        }
9228
9229        // Determine if the process(es) for this task should be killed.
9230        final String pkg = component.getPackageName();
9231        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9232        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9233        for (int i = 0; i < pmap.size(); i++) {
9234
9235            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9236            for (int j = 0; j < uids.size(); j++) {
9237                ProcessRecord proc = uids.valueAt(j);
9238                if (proc.userId != tr.userId) {
9239                    // Don't kill process for a different user.
9240                    continue;
9241                }
9242                if (proc == mHomeProcess) {
9243                    // Don't kill the home process along with tasks from the same package.
9244                    continue;
9245                }
9246                if (!proc.pkgList.containsKey(pkg)) {
9247                    // Don't kill process that is not associated with this task.
9248                    continue;
9249                }
9250
9251                for (int k = 0; k < proc.activities.size(); k++) {
9252                    TaskRecord otherTask = proc.activities.get(k).task;
9253                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9254                        // Don't kill process(es) that has an activity in a different task that is
9255                        // also in recents.
9256                        return;
9257                    }
9258                }
9259
9260                if (proc.foregroundServices) {
9261                    // Don't kill process(es) with foreground service.
9262                    return;
9263                }
9264
9265                // Add process to kill list.
9266                procsToKill.add(proc);
9267            }
9268        }
9269
9270        // Kill the running processes.
9271        for (int i = 0; i < procsToKill.size(); i++) {
9272            ProcessRecord pr = procsToKill.get(i);
9273            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9274                    && pr.curReceiver == null) {
9275                pr.kill("remove task", true);
9276            } else {
9277                // We delay killing processes that are not in the background or running a receiver.
9278                pr.waitingToKill = "remove task";
9279            }
9280        }
9281    }
9282
9283    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9284        // Remove all tasks with activities in the specified package from the list of recent tasks
9285        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9286            TaskRecord tr = mRecentTasks.get(i);
9287            if (tr.userId != userId) continue;
9288
9289            ComponentName cn = tr.intent.getComponent();
9290            if (cn != null && cn.getPackageName().equals(packageName)) {
9291                // If the package name matches, remove the task.
9292                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9293            }
9294        }
9295    }
9296
9297    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9298            int userId) {
9299
9300        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9301            TaskRecord tr = mRecentTasks.get(i);
9302            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9303                continue;
9304            }
9305
9306            ComponentName cn = tr.intent.getComponent();
9307            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9308                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9309            if (sameComponent) {
9310                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9311            }
9312        }
9313    }
9314
9315    /**
9316     * Removes the task with the specified task id.
9317     *
9318     * @param taskId Identifier of the task to be removed.
9319     * @param killProcess Kill any process associated with the task if possible.
9320     * @param removeFromRecents Whether to also remove the task from recents.
9321     * @return Returns true if the given task was found and removed.
9322     */
9323    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9324            boolean removeFromRecents) {
9325        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9326                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9327        if (tr != null) {
9328            tr.removeTaskActivitiesLocked();
9329            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9330            if (tr.isPersistable) {
9331                notifyTaskPersisterLocked(null, true);
9332            }
9333            return true;
9334        }
9335        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9336        return false;
9337    }
9338
9339    @Override
9340    public boolean removeTask(int taskId) {
9341        synchronized (this) {
9342            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9343                    "removeTask()");
9344            long ident = Binder.clearCallingIdentity();
9345            try {
9346                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9347            } finally {
9348                Binder.restoreCallingIdentity(ident);
9349            }
9350        }
9351    }
9352
9353    /**
9354     * TODO: Add mController hook
9355     */
9356    @Override
9357    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9358        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9359
9360        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9361        synchronized(this) {
9362            moveTaskToFrontLocked(taskId, flags, bOptions);
9363        }
9364    }
9365
9366    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9367        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9368
9369        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9370                Binder.getCallingUid(), -1, -1, "Task to front")) {
9371            ActivityOptions.abort(options);
9372            return;
9373        }
9374        final long origId = Binder.clearCallingIdentity();
9375        try {
9376            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9377            if (task == null) {
9378                Slog.d(TAG, "Could not find task for id: "+ taskId);
9379                return;
9380            }
9381            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9382                mStackSupervisor.showLockTaskToast();
9383                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9384                return;
9385            }
9386            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9387            if (prev != null && prev.isRecentsActivity()) {
9388                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9389            }
9390            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9391        } finally {
9392            Binder.restoreCallingIdentity(origId);
9393        }
9394        ActivityOptions.abort(options);
9395    }
9396
9397    /**
9398     * Moves an activity, and all of the other activities within the same task, to the bottom
9399     * of the history stack.  The activity's order within the task is unchanged.
9400     *
9401     * @param token A reference to the activity we wish to move
9402     * @param nonRoot If false then this only works if the activity is the root
9403     *                of a task; if true it will work for any activity in a task.
9404     * @return Returns true if the move completed, false if not.
9405     */
9406    @Override
9407    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9408        enforceNotIsolatedCaller("moveActivityTaskToBack");
9409        synchronized(this) {
9410            final long origId = Binder.clearCallingIdentity();
9411            try {
9412                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9413                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9414                if (task != null) {
9415                    if (mStackSupervisor.isLockedTask(task)) {
9416                        mStackSupervisor.showLockTaskToast();
9417                        return false;
9418                    }
9419                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9420                }
9421            } finally {
9422                Binder.restoreCallingIdentity(origId);
9423            }
9424        }
9425        return false;
9426    }
9427
9428    @Override
9429    public void moveTaskBackwards(int task) {
9430        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9431                "moveTaskBackwards()");
9432
9433        synchronized(this) {
9434            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9435                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9436                return;
9437            }
9438            final long origId = Binder.clearCallingIdentity();
9439            moveTaskBackwardsLocked(task);
9440            Binder.restoreCallingIdentity(origId);
9441        }
9442    }
9443
9444    private final void moveTaskBackwardsLocked(int task) {
9445        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9446    }
9447
9448    @Override
9449    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9450            IActivityContainerCallback callback) throws RemoteException {
9451        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9452        synchronized (this) {
9453            if (parentActivityToken == null) {
9454                throw new IllegalArgumentException("parent token must not be null");
9455            }
9456            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9457            if (r == null) {
9458                return null;
9459            }
9460            if (callback == null) {
9461                throw new IllegalArgumentException("callback must not be null");
9462            }
9463            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9464        }
9465    }
9466
9467    @Override
9468    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9469        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9470        synchronized (this) {
9471            mStackSupervisor.deleteActivityContainer(container);
9472        }
9473    }
9474
9475    @Override
9476    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9477        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9478        synchronized (this) {
9479            final int stackId = mStackSupervisor.getNextStackId();
9480            final ActivityStack stack =
9481                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9482            if (stack == null) {
9483                return null;
9484            }
9485            return stack.mActivityContainer;
9486        }
9487    }
9488
9489    @Override
9490    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9491        synchronized (this) {
9492            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9493            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9494                return stack.mActivityContainer.getDisplayId();
9495            }
9496            return Display.DEFAULT_DISPLAY;
9497        }
9498    }
9499
9500    @Override
9501    public int getActivityStackId(IBinder token) throws RemoteException {
9502        synchronized (this) {
9503            ActivityStack stack = ActivityRecord.getStackLocked(token);
9504            if (stack == null) {
9505                return INVALID_STACK_ID;
9506            }
9507            return stack.mStackId;
9508        }
9509    }
9510
9511    @Override
9512    public void exitFreeformMode(IBinder token) throws RemoteException {
9513        synchronized (this) {
9514            long ident = Binder.clearCallingIdentity();
9515            try {
9516                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9517                if (r == null) {
9518                    throw new IllegalArgumentException(
9519                            "exitFreeformMode: No activity record matching token=" + token);
9520                }
9521                final ActivityStack stack = r.getStackLocked(token);
9522                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9523                    throw new IllegalStateException(
9524                            "exitFreeformMode: You can only go fullscreen from freeform.");
9525                }
9526                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9527                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9528                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9529            } finally {
9530                Binder.restoreCallingIdentity(ident);
9531            }
9532        }
9533    }
9534
9535    @Override
9536    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9538        if (stackId == HOME_STACK_ID) {
9539            throw new IllegalArgumentException(
9540                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9541        }
9542        synchronized (this) {
9543            long ident = Binder.clearCallingIdentity();
9544            try {
9545                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9546                        + " to stackId=" + stackId + " toTop=" + toTop);
9547                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9548                        "moveTaskToStack", ANIMATE);
9549            } finally {
9550                Binder.restoreCallingIdentity(ident);
9551            }
9552        }
9553    }
9554
9555    /**
9556     * Moves the input task to the docked stack.
9557     *
9558     * @param taskId Id of task to move.
9559     * @param createMode The mode the docked stack should be created in if it doesn't exist
9560     *                   already. See
9561     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9562     *                   and
9563     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9564     * @param toTop If the task and stack should be moved to the top.
9565     * @param animate Whether we should play an animation for the moving the task
9566     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9567     *                      docked stack. Pass {@code null} to use default bounds.
9568     */
9569    @Override
9570    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9571            Rect initialBounds) {
9572        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9573        synchronized (this) {
9574            long ident = Binder.clearCallingIdentity();
9575            try {
9576                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9577                        + " to createMode=" + createMode + " toTop=" + toTop);
9578                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9579                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9580                        "moveTaskToDockedStack", animate);
9581            } finally {
9582                Binder.restoreCallingIdentity(ident);
9583            }
9584        }
9585    }
9586
9587    /**
9588     * Moves the top activity in the input stackId to the pinned stack.
9589     *
9590     * @param stackId Id of stack to move the top activity to pinned stack.
9591     * @param bounds Bounds to use for pinned stack.
9592     *
9593     * @return True if the top activity of the input stack was successfully moved to the pinned
9594     *          stack.
9595     */
9596    @Override
9597    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9598        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9599        synchronized (this) {
9600            if (!mSupportsPictureInPicture) {
9601                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9602                        + "Device doesn't support picture-in-pciture mode");
9603            }
9604
9605            long ident = Binder.clearCallingIdentity();
9606            try {
9607                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9608            } finally {
9609                Binder.restoreCallingIdentity(ident);
9610            }
9611        }
9612    }
9613
9614    @Override
9615    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9616        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9617        long ident = Binder.clearCallingIdentity();
9618        try {
9619            synchronized (this) {
9620                mStackSupervisor.resizeStackLocked(
9621                        stackId, bounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
9622                        !PRESERVE_WINDOWS, allowResizeInDockedMode);
9623            }
9624        } finally {
9625            Binder.restoreCallingIdentity(ident);
9626        }
9627    }
9628
9629    @Override
9630    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9631            Rect tempDockedTaskInsetBounds,
9632            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9634                "resizeDockedStack()");
9635        long ident = Binder.clearCallingIdentity();
9636        try {
9637            synchronized (this) {
9638                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9639                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9640                        PRESERVE_WINDOWS);
9641            }
9642        } finally {
9643            Binder.restoreCallingIdentity(ident);
9644        }
9645    }
9646
9647    @Override
9648    public void positionTaskInStack(int taskId, int stackId, int position) {
9649        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9650        if (stackId == HOME_STACK_ID) {
9651            throw new IllegalArgumentException(
9652                    "positionTaskInStack: Attempt to change the position of task "
9653                    + taskId + " in/to home stack");
9654        }
9655        synchronized (this) {
9656            long ident = Binder.clearCallingIdentity();
9657            try {
9658                if (DEBUG_STACK) Slog.d(TAG_STACK,
9659                        "positionTaskInStack: positioning task=" + taskId
9660                        + " in stackId=" + stackId + " at position=" + position);
9661                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9662            } finally {
9663                Binder.restoreCallingIdentity(ident);
9664            }
9665        }
9666    }
9667
9668    @Override
9669    public List<StackInfo> getAllStackInfos() {
9670        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9671        long ident = Binder.clearCallingIdentity();
9672        try {
9673            synchronized (this) {
9674                return mStackSupervisor.getAllStackInfosLocked();
9675            }
9676        } finally {
9677            Binder.restoreCallingIdentity(ident);
9678        }
9679    }
9680
9681    @Override
9682    public StackInfo getStackInfo(int stackId) {
9683        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9684        long ident = Binder.clearCallingIdentity();
9685        try {
9686            synchronized (this) {
9687                return mStackSupervisor.getStackInfoLocked(stackId);
9688            }
9689        } finally {
9690            Binder.restoreCallingIdentity(ident);
9691        }
9692    }
9693
9694    @Override
9695    public boolean isInHomeStack(int taskId) {
9696        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9697        long ident = Binder.clearCallingIdentity();
9698        try {
9699            synchronized (this) {
9700                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9701                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9702                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9703            }
9704        } finally {
9705            Binder.restoreCallingIdentity(ident);
9706        }
9707    }
9708
9709    @Override
9710    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9711        synchronized(this) {
9712            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9713        }
9714    }
9715
9716    @Override
9717    public void updateDeviceOwner(String packageName) {
9718        final int callingUid = Binder.getCallingUid();
9719        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9720            throw new SecurityException("updateDeviceOwner called from non-system process");
9721        }
9722        synchronized (this) {
9723            mDeviceOwnerName = packageName;
9724        }
9725    }
9726
9727    @Override
9728    public void updateLockTaskPackages(int userId, String[] packages) {
9729        final int callingUid = Binder.getCallingUid();
9730        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9731            throw new SecurityException("updateLockTaskPackage called from non-system process");
9732        }
9733        synchronized (this) {
9734            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9735                    Arrays.toString(packages));
9736            mLockTaskPackages.put(userId, packages);
9737            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9738        }
9739    }
9740
9741
9742    void startLockTaskModeLocked(TaskRecord task) {
9743        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9744        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9745            return;
9746        }
9747
9748        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9749        // is initiated by system after the pinning request was shown and locked mode is initiated
9750        // by an authorized app directly
9751        final int callingUid = Binder.getCallingUid();
9752        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9753        long ident = Binder.clearCallingIdentity();
9754        try {
9755            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9756            if (!isSystemInitiated) {
9757                task.mLockTaskUid = callingUid;
9758                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9759                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9760                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9761                    StatusBarManagerInternal statusBarManager =
9762                            LocalServices.getService(StatusBarManagerInternal.class);
9763                    if (statusBarManager != null) {
9764                        statusBarManager.showScreenPinningRequest();
9765                    }
9766                    return;
9767                }
9768
9769                if (stack == null || task != stack.topTask()) {
9770                    throw new IllegalArgumentException("Invalid task, not in foreground");
9771                }
9772            }
9773            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9774                    "Locking fully");
9775            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9776                    ActivityManager.LOCK_TASK_MODE_PINNED :
9777                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9778                    "startLockTask", true);
9779        } finally {
9780            Binder.restoreCallingIdentity(ident);
9781        }
9782    }
9783
9784    @Override
9785    public void startLockTaskMode(int taskId) {
9786        synchronized (this) {
9787            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9788            if (task != null) {
9789                startLockTaskModeLocked(task);
9790            }
9791        }
9792    }
9793
9794    @Override
9795    public void startLockTaskMode(IBinder token) {
9796        synchronized (this) {
9797            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9798            if (r == null) {
9799                return;
9800            }
9801            final TaskRecord task = r.task;
9802            if (task != null) {
9803                startLockTaskModeLocked(task);
9804            }
9805        }
9806    }
9807
9808    @Override
9809    public void startLockTaskModeOnCurrent() throws RemoteException {
9810        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9811        long ident = Binder.clearCallingIdentity();
9812        try {
9813            synchronized (this) {
9814                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9815                if (r != null) {
9816                    startLockTaskModeLocked(r.task);
9817                }
9818            }
9819        } finally {
9820            Binder.restoreCallingIdentity(ident);
9821        }
9822    }
9823
9824    @Override
9825    public void stopLockTaskMode() {
9826        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9827        if (lockTask == null) {
9828            // Our work here is done.
9829            return;
9830        }
9831
9832        final int callingUid = Binder.getCallingUid();
9833        final int lockTaskUid = lockTask.mLockTaskUid;
9834        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9835        // It is possible lockTaskMode was started by the system process because
9836        // android:lockTaskMode is set to a locking value in the application manifest instead of
9837        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9838        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9839        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9840                callingUid != lockTaskUid
9841                && (lockTaskUid != 0
9842                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9843            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9844                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9845        }
9846
9847        long ident = Binder.clearCallingIdentity();
9848        try {
9849            Log.d(TAG, "stopLockTaskMode");
9850            // Stop lock task
9851            synchronized (this) {
9852                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9853                        "stopLockTask", true);
9854            }
9855        } finally {
9856            Binder.restoreCallingIdentity(ident);
9857        }
9858    }
9859
9860    @Override
9861    public void stopLockTaskModeOnCurrent() throws RemoteException {
9862        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9863        long ident = Binder.clearCallingIdentity();
9864        try {
9865            stopLockTaskMode();
9866        } finally {
9867            Binder.restoreCallingIdentity(ident);
9868        }
9869    }
9870
9871    @Override
9872    public boolean isInLockTaskMode() {
9873        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9874    }
9875
9876    @Override
9877    public int getLockTaskModeState() {
9878        synchronized (this) {
9879            return mStackSupervisor.getLockTaskModeState();
9880        }
9881    }
9882
9883    @Override
9884    public void showLockTaskEscapeMessage(IBinder token) {
9885        synchronized (this) {
9886            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9887            if (r == null) {
9888                return;
9889            }
9890            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9891        }
9892    }
9893
9894    // =========================================================
9895    // CONTENT PROVIDERS
9896    // =========================================================
9897
9898    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9899        List<ProviderInfo> providers = null;
9900        try {
9901            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9902                    .queryContentProviders(app.processName, app.uid,
9903                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9904                                    | MATCH_DEBUG_TRIAGED_MISSING);
9905            providers = slice != null ? slice.getList() : null;
9906        } catch (RemoteException ex) {
9907        }
9908        if (DEBUG_MU) Slog.v(TAG_MU,
9909                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9910        int userId = app.userId;
9911        if (providers != null) {
9912            int N = providers.size();
9913            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9914            for (int i=0; i<N; i++) {
9915                ProviderInfo cpi =
9916                    (ProviderInfo)providers.get(i);
9917                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9918                        cpi.name, cpi.flags);
9919                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9920                    // This is a singleton provider, but a user besides the
9921                    // default user is asking to initialize a process it runs
9922                    // in...  well, no, it doesn't actually run in this process,
9923                    // it runs in the process of the default user.  Get rid of it.
9924                    providers.remove(i);
9925                    N--;
9926                    i--;
9927                    continue;
9928                }
9929
9930                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9931                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9932                if (cpr == null) {
9933                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9934                    mProviderMap.putProviderByClass(comp, cpr);
9935                }
9936                if (DEBUG_MU) Slog.v(TAG_MU,
9937                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9938                app.pubProviders.put(cpi.name, cpr);
9939                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9940                    // Don't add this if it is a platform component that is marked
9941                    // to run in multiple processes, because this is actually
9942                    // part of the framework so doesn't make sense to track as a
9943                    // separate apk in the process.
9944                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9945                            mProcessStats);
9946                }
9947                notifyPackageUse(cpi.applicationInfo.packageName);
9948            }
9949        }
9950        return providers;
9951    }
9952
9953    /**
9954     * Check if {@link ProcessRecord} has a possible chance at accessing the
9955     * given {@link ProviderInfo}. Final permission checking is always done
9956     * in {@link ContentProvider}.
9957     */
9958    private final String checkContentProviderPermissionLocked(
9959            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9960        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9961        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9962        boolean checkedGrants = false;
9963        if (checkUser) {
9964            // Looking for cross-user grants before enforcing the typical cross-users permissions
9965            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9966            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9967                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9968                    return null;
9969                }
9970                checkedGrants = true;
9971            }
9972            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9973                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9974            if (userId != tmpTargetUserId) {
9975                // When we actually went to determine the final targer user ID, this ended
9976                // up different than our initial check for the authority.  This is because
9977                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9978                // SELF.  So we need to re-check the grants again.
9979                checkedGrants = false;
9980            }
9981        }
9982        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9983                cpi.applicationInfo.uid, cpi.exported)
9984                == PackageManager.PERMISSION_GRANTED) {
9985            return null;
9986        }
9987        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9988                cpi.applicationInfo.uid, cpi.exported)
9989                == PackageManager.PERMISSION_GRANTED) {
9990            return null;
9991        }
9992
9993        PathPermission[] pps = cpi.pathPermissions;
9994        if (pps != null) {
9995            int i = pps.length;
9996            while (i > 0) {
9997                i--;
9998                PathPermission pp = pps[i];
9999                String pprperm = pp.getReadPermission();
10000                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10001                        cpi.applicationInfo.uid, cpi.exported)
10002                        == PackageManager.PERMISSION_GRANTED) {
10003                    return null;
10004                }
10005                String ppwperm = pp.getWritePermission();
10006                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10007                        cpi.applicationInfo.uid, cpi.exported)
10008                        == PackageManager.PERMISSION_GRANTED) {
10009                    return null;
10010                }
10011            }
10012        }
10013        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10014            return null;
10015        }
10016
10017        String msg;
10018        if (!cpi.exported) {
10019            msg = "Permission Denial: opening provider " + cpi.name
10020                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10021                    + ", uid=" + callingUid + ") that is not exported from uid "
10022                    + cpi.applicationInfo.uid;
10023        } else {
10024            msg = "Permission Denial: opening provider " + cpi.name
10025                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10026                    + ", uid=" + callingUid + ") requires "
10027                    + cpi.readPermission + " or " + cpi.writePermission;
10028        }
10029        Slog.w(TAG, msg);
10030        return msg;
10031    }
10032
10033    /**
10034     * Returns if the ContentProvider has granted a uri to callingUid
10035     */
10036    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10037        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10038        if (perms != null) {
10039            for (int i=perms.size()-1; i>=0; i--) {
10040                GrantUri grantUri = perms.keyAt(i);
10041                if (grantUri.sourceUserId == userId || !checkUser) {
10042                    if (matchesProvider(grantUri.uri, cpi)) {
10043                        return true;
10044                    }
10045                }
10046            }
10047        }
10048        return false;
10049    }
10050
10051    /**
10052     * Returns true if the uri authority is one of the authorities specified in the provider.
10053     */
10054    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10055        String uriAuth = uri.getAuthority();
10056        String cpiAuth = cpi.authority;
10057        if (cpiAuth.indexOf(';') == -1) {
10058            return cpiAuth.equals(uriAuth);
10059        }
10060        String[] cpiAuths = cpiAuth.split(";");
10061        int length = cpiAuths.length;
10062        for (int i = 0; i < length; i++) {
10063            if (cpiAuths[i].equals(uriAuth)) return true;
10064        }
10065        return false;
10066    }
10067
10068    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10069            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10070        if (r != null) {
10071            for (int i=0; i<r.conProviders.size(); i++) {
10072                ContentProviderConnection conn = r.conProviders.get(i);
10073                if (conn.provider == cpr) {
10074                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10075                            "Adding provider requested by "
10076                            + r.processName + " from process "
10077                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10078                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10079                    if (stable) {
10080                        conn.stableCount++;
10081                        conn.numStableIncs++;
10082                    } else {
10083                        conn.unstableCount++;
10084                        conn.numUnstableIncs++;
10085                    }
10086                    return conn;
10087                }
10088            }
10089            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10090            if (stable) {
10091                conn.stableCount = 1;
10092                conn.numStableIncs = 1;
10093            } else {
10094                conn.unstableCount = 1;
10095                conn.numUnstableIncs = 1;
10096            }
10097            cpr.connections.add(conn);
10098            r.conProviders.add(conn);
10099            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10100            return conn;
10101        }
10102        cpr.addExternalProcessHandleLocked(externalProcessToken);
10103        return null;
10104    }
10105
10106    boolean decProviderCountLocked(ContentProviderConnection conn,
10107            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10108        if (conn != null) {
10109            cpr = conn.provider;
10110            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10111                    "Removing provider requested by "
10112                    + conn.client.processName + " from process "
10113                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10114                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10115            if (stable) {
10116                conn.stableCount--;
10117            } else {
10118                conn.unstableCount--;
10119            }
10120            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10121                cpr.connections.remove(conn);
10122                conn.client.conProviders.remove(conn);
10123                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10124                    // The client is more important than last activity -- note the time this
10125                    // is happening, so we keep the old provider process around a bit as last
10126                    // activity to avoid thrashing it.
10127                    if (cpr.proc != null) {
10128                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10129                    }
10130                }
10131                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10132                return true;
10133            }
10134            return false;
10135        }
10136        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10137        return false;
10138    }
10139
10140    private void checkTime(long startTime, String where) {
10141        long now = SystemClock.elapsedRealtime();
10142        if ((now-startTime) > 1000) {
10143            // If we are taking more than a second, log about it.
10144            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10145        }
10146    }
10147
10148    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10149            String name, IBinder token, boolean stable, int userId) {
10150        ContentProviderRecord cpr;
10151        ContentProviderConnection conn = null;
10152        ProviderInfo cpi = null;
10153
10154        synchronized(this) {
10155            long startTime = SystemClock.elapsedRealtime();
10156
10157            ProcessRecord r = null;
10158            if (caller != null) {
10159                r = getRecordForAppLocked(caller);
10160                if (r == null) {
10161                    throw new SecurityException(
10162                            "Unable to find app for caller " + caller
10163                          + " (pid=" + Binder.getCallingPid()
10164                          + ") when getting content provider " + name);
10165                }
10166            }
10167
10168            boolean checkCrossUser = true;
10169
10170            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10171
10172            // First check if this content provider has been published...
10173            cpr = mProviderMap.getProviderByName(name, userId);
10174            // If that didn't work, check if it exists for user 0 and then
10175            // verify that it's a singleton provider before using it.
10176            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10177                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10178                if (cpr != null) {
10179                    cpi = cpr.info;
10180                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10181                            cpi.name, cpi.flags)
10182                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10183                        userId = UserHandle.USER_SYSTEM;
10184                        checkCrossUser = false;
10185                    } else {
10186                        cpr = null;
10187                        cpi = null;
10188                    }
10189                }
10190            }
10191
10192            boolean providerRunning = cpr != null;
10193            if (providerRunning) {
10194                cpi = cpr.info;
10195                String msg;
10196                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10197                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10198                        != null) {
10199                    throw new SecurityException(msg);
10200                }
10201                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10202
10203                if (r != null && cpr.canRunHere(r)) {
10204                    // This provider has been published or is in the process
10205                    // of being published...  but it is also allowed to run
10206                    // in the caller's process, so don't make a connection
10207                    // and just let the caller instantiate its own instance.
10208                    ContentProviderHolder holder = cpr.newHolder(null);
10209                    // don't give caller the provider object, it needs
10210                    // to make its own.
10211                    holder.provider = null;
10212                    return holder;
10213                }
10214
10215                final long origId = Binder.clearCallingIdentity();
10216
10217                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10218
10219                // In this case the provider instance already exists, so we can
10220                // return it right away.
10221                conn = incProviderCountLocked(r, cpr, token, stable);
10222                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10223                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10224                        // If this is a perceptible app accessing the provider,
10225                        // make sure to count it as being accessed and thus
10226                        // back up on the LRU list.  This is good because
10227                        // content providers are often expensive to start.
10228                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10229                        updateLruProcessLocked(cpr.proc, false, null);
10230                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10231                    }
10232                }
10233
10234                if (cpr.proc != null) {
10235                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10236                    boolean success = updateOomAdjLocked(cpr.proc);
10237                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10238                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10239                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10240                    // NOTE: there is still a race here where a signal could be
10241                    // pending on the process even though we managed to update its
10242                    // adj level.  Not sure what to do about this, but at least
10243                    // the race is now smaller.
10244                    if (!success) {
10245                        // Uh oh...  it looks like the provider's process
10246                        // has been killed on us.  We need to wait for a new
10247                        // process to be started, and make sure its death
10248                        // doesn't kill our process.
10249                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10250                                + " is crashing; detaching " + r);
10251                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10252                        checkTime(startTime, "getContentProviderImpl: before appDied");
10253                        appDiedLocked(cpr.proc);
10254                        checkTime(startTime, "getContentProviderImpl: after appDied");
10255                        if (!lastRef) {
10256                            // This wasn't the last ref our process had on
10257                            // the provider...  we have now been killed, bail.
10258                            return null;
10259                        }
10260                        providerRunning = false;
10261                        conn = null;
10262                    }
10263                }
10264
10265                Binder.restoreCallingIdentity(origId);
10266            }
10267
10268            if (!providerRunning) {
10269                try {
10270                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10271                    cpi = AppGlobals.getPackageManager().
10272                        resolveContentProvider(name,
10273                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10274                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10275                } catch (RemoteException ex) {
10276                }
10277                if (cpi == null) {
10278                    return null;
10279                }
10280                // If the provider is a singleton AND
10281                // (it's a call within the same user || the provider is a
10282                // privileged app)
10283                // Then allow connecting to the singleton provider
10284                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10285                        cpi.name, cpi.flags)
10286                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10287                if (singleton) {
10288                    userId = UserHandle.USER_SYSTEM;
10289                }
10290                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10291                checkTime(startTime, "getContentProviderImpl: got app info for user");
10292
10293                String msg;
10294                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10295                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10296                        != null) {
10297                    throw new SecurityException(msg);
10298                }
10299                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10300
10301                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10302                        && !cpi.processName.equals("system")) {
10303                    // If this content provider does not run in the system
10304                    // process, and the system is not yet ready to run other
10305                    // processes, then fail fast instead of hanging.
10306                    throw new IllegalArgumentException(
10307                            "Attempt to launch content provider before system ready");
10308                }
10309
10310                // Make sure that the user who owns this provider is running.  If not,
10311                // we don't want to allow it to run.
10312                if (!mUserController.isUserRunningLocked(userId, 0)) {
10313                    Slog.w(TAG, "Unable to launch app "
10314                            + cpi.applicationInfo.packageName + "/"
10315                            + cpi.applicationInfo.uid + " for provider "
10316                            + name + ": user " + userId + " is stopped");
10317                    return null;
10318                }
10319
10320                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10321                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10322                cpr = mProviderMap.getProviderByClass(comp, userId);
10323                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10324                final boolean firstClass = cpr == null;
10325                if (firstClass) {
10326                    final long ident = Binder.clearCallingIdentity();
10327
10328                    // If permissions need a review before any of the app components can run,
10329                    // we return no provider and launch a review activity if the calling app
10330                    // is in the foreground.
10331                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10332                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10333                            return null;
10334                        }
10335                    }
10336
10337                    try {
10338                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10339                        ApplicationInfo ai =
10340                            AppGlobals.getPackageManager().
10341                                getApplicationInfo(
10342                                        cpi.applicationInfo.packageName,
10343                                        STOCK_PM_FLAGS, userId);
10344                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10345                        if (ai == null) {
10346                            Slog.w(TAG, "No package info for content provider "
10347                                    + cpi.name);
10348                            return null;
10349                        }
10350                        ai = getAppInfoForUser(ai, userId);
10351                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10352                    } catch (RemoteException ex) {
10353                        // pm is in same process, this will never happen.
10354                    } finally {
10355                        Binder.restoreCallingIdentity(ident);
10356                    }
10357                }
10358
10359                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10360
10361                if (r != null && cpr.canRunHere(r)) {
10362                    // If this is a multiprocess provider, then just return its
10363                    // info and allow the caller to instantiate it.  Only do
10364                    // this if the provider is the same user as the caller's
10365                    // process, or can run as root (so can be in any process).
10366                    return cpr.newHolder(null);
10367                }
10368
10369                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10370                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10371                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10372
10373                // This is single process, and our app is now connecting to it.
10374                // See if we are already in the process of launching this
10375                // provider.
10376                final int N = mLaunchingProviders.size();
10377                int i;
10378                for (i = 0; i < N; i++) {
10379                    if (mLaunchingProviders.get(i) == cpr) {
10380                        break;
10381                    }
10382                }
10383
10384                // If the provider is not already being launched, then get it
10385                // started.
10386                if (i >= N) {
10387                    final long origId = Binder.clearCallingIdentity();
10388
10389                    try {
10390                        // Content provider is now in use, its package can't be stopped.
10391                        try {
10392                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10393                            AppGlobals.getPackageManager().setPackageStoppedState(
10394                                    cpr.appInfo.packageName, false, userId);
10395                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10396                        } catch (RemoteException e) {
10397                        } catch (IllegalArgumentException e) {
10398                            Slog.w(TAG, "Failed trying to unstop package "
10399                                    + cpr.appInfo.packageName + ": " + e);
10400                        }
10401
10402                        // Use existing process if already started
10403                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10404                        ProcessRecord proc = getProcessRecordLocked(
10405                                cpi.processName, cpr.appInfo.uid, false);
10406                        if (proc != null && proc.thread != null) {
10407                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10408                                    "Installing in existing process " + proc);
10409                            if (!proc.pubProviders.containsKey(cpi.name)) {
10410                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10411                                proc.pubProviders.put(cpi.name, cpr);
10412                                try {
10413                                    proc.thread.scheduleInstallProvider(cpi);
10414                                } catch (RemoteException e) {
10415                                }
10416                            }
10417                        } else {
10418                            checkTime(startTime, "getContentProviderImpl: before start process");
10419                            proc = startProcessLocked(cpi.processName,
10420                                    cpr.appInfo, false, 0, "content provider",
10421                                    new ComponentName(cpi.applicationInfo.packageName,
10422                                            cpi.name), false, false, false);
10423                            checkTime(startTime, "getContentProviderImpl: after start process");
10424                            if (proc == null) {
10425                                Slog.w(TAG, "Unable to launch app "
10426                                        + cpi.applicationInfo.packageName + "/"
10427                                        + cpi.applicationInfo.uid + " for provider "
10428                                        + name + ": process is bad");
10429                                return null;
10430                            }
10431                        }
10432                        cpr.launchingApp = proc;
10433                        mLaunchingProviders.add(cpr);
10434                    } finally {
10435                        Binder.restoreCallingIdentity(origId);
10436                    }
10437                }
10438
10439                checkTime(startTime, "getContentProviderImpl: updating data structures");
10440
10441                // Make sure the provider is published (the same provider class
10442                // may be published under multiple names).
10443                if (firstClass) {
10444                    mProviderMap.putProviderByClass(comp, cpr);
10445                }
10446
10447                mProviderMap.putProviderByName(name, cpr);
10448                conn = incProviderCountLocked(r, cpr, token, stable);
10449                if (conn != null) {
10450                    conn.waiting = true;
10451                }
10452            }
10453            checkTime(startTime, "getContentProviderImpl: done!");
10454        }
10455
10456        // Wait for the provider to be published...
10457        synchronized (cpr) {
10458            while (cpr.provider == null) {
10459                if (cpr.launchingApp == null) {
10460                    Slog.w(TAG, "Unable to launch app "
10461                            + cpi.applicationInfo.packageName + "/"
10462                            + cpi.applicationInfo.uid + " for provider "
10463                            + name + ": launching app became null");
10464                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10465                            UserHandle.getUserId(cpi.applicationInfo.uid),
10466                            cpi.applicationInfo.packageName,
10467                            cpi.applicationInfo.uid, name);
10468                    return null;
10469                }
10470                try {
10471                    if (DEBUG_MU) Slog.v(TAG_MU,
10472                            "Waiting to start provider " + cpr
10473                            + " launchingApp=" + cpr.launchingApp);
10474                    if (conn != null) {
10475                        conn.waiting = true;
10476                    }
10477                    cpr.wait();
10478                } catch (InterruptedException ex) {
10479                } finally {
10480                    if (conn != null) {
10481                        conn.waiting = false;
10482                    }
10483                }
10484            }
10485        }
10486        return cpr != null ? cpr.newHolder(conn) : null;
10487    }
10488
10489    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10490            ProcessRecord r, final int userId) {
10491        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10492                cpi.packageName, r.userId)) {
10493
10494            final boolean callerForeground = r != null ? r.setSchedGroup
10495                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10496
10497            // Show a permission review UI only for starting from a foreground app
10498            if (!callerForeground) {
10499                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10500                        + cpi.packageName + " requires a permissions review");
10501                return false;
10502            }
10503
10504            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10505            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10506                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10507            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10508
10509            if (DEBUG_PERMISSIONS_REVIEW) {
10510                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10511                        + "for package " + cpi.packageName);
10512            }
10513
10514            final UserHandle userHandle = new UserHandle(userId);
10515            mHandler.post(new Runnable() {
10516                @Override
10517                public void run() {
10518                    mContext.startActivityAsUser(intent, userHandle);
10519                }
10520            });
10521
10522            return false;
10523        }
10524
10525        return true;
10526    }
10527
10528    PackageManagerInternal getPackageManagerInternalLocked() {
10529        if (mPackageManagerInt == null) {
10530            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10531        }
10532        return mPackageManagerInt;
10533    }
10534
10535    @Override
10536    public final ContentProviderHolder getContentProvider(
10537            IApplicationThread caller, String name, int userId, boolean stable) {
10538        enforceNotIsolatedCaller("getContentProvider");
10539        if (caller == null) {
10540            String msg = "null IApplicationThread when getting content provider "
10541                    + name;
10542            Slog.w(TAG, msg);
10543            throw new SecurityException(msg);
10544        }
10545        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10546        // with cross-user grant.
10547        return getContentProviderImpl(caller, name, null, stable, userId);
10548    }
10549
10550    public ContentProviderHolder getContentProviderExternal(
10551            String name, int userId, IBinder token) {
10552        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10553            "Do not have permission in call getContentProviderExternal()");
10554        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10555                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10556        return getContentProviderExternalUnchecked(name, token, userId);
10557    }
10558
10559    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10560            IBinder token, int userId) {
10561        return getContentProviderImpl(null, name, token, true, userId);
10562    }
10563
10564    /**
10565     * Drop a content provider from a ProcessRecord's bookkeeping
10566     */
10567    public void removeContentProvider(IBinder connection, boolean stable) {
10568        enforceNotIsolatedCaller("removeContentProvider");
10569        long ident = Binder.clearCallingIdentity();
10570        try {
10571            synchronized (this) {
10572                ContentProviderConnection conn;
10573                try {
10574                    conn = (ContentProviderConnection)connection;
10575                } catch (ClassCastException e) {
10576                    String msg ="removeContentProvider: " + connection
10577                            + " not a ContentProviderConnection";
10578                    Slog.w(TAG, msg);
10579                    throw new IllegalArgumentException(msg);
10580                }
10581                if (conn == null) {
10582                    throw new NullPointerException("connection is null");
10583                }
10584                if (decProviderCountLocked(conn, null, null, stable)) {
10585                    updateOomAdjLocked();
10586                }
10587            }
10588        } finally {
10589            Binder.restoreCallingIdentity(ident);
10590        }
10591    }
10592
10593    public void removeContentProviderExternal(String name, IBinder token) {
10594        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10595            "Do not have permission in call removeContentProviderExternal()");
10596        int userId = UserHandle.getCallingUserId();
10597        long ident = Binder.clearCallingIdentity();
10598        try {
10599            removeContentProviderExternalUnchecked(name, token, userId);
10600        } finally {
10601            Binder.restoreCallingIdentity(ident);
10602        }
10603    }
10604
10605    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10606        synchronized (this) {
10607            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10608            if(cpr == null) {
10609                //remove from mProvidersByClass
10610                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10611                return;
10612            }
10613
10614            //update content provider record entry info
10615            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10616            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10617            if (localCpr.hasExternalProcessHandles()) {
10618                if (localCpr.removeExternalProcessHandleLocked(token)) {
10619                    updateOomAdjLocked();
10620                } else {
10621                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10622                            + " with no external reference for token: "
10623                            + token + ".");
10624                }
10625            } else {
10626                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10627                        + " with no external references.");
10628            }
10629        }
10630    }
10631
10632    public final void publishContentProviders(IApplicationThread caller,
10633            List<ContentProviderHolder> providers) {
10634        if (providers == null) {
10635            return;
10636        }
10637
10638        enforceNotIsolatedCaller("publishContentProviders");
10639        synchronized (this) {
10640            final ProcessRecord r = getRecordForAppLocked(caller);
10641            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10642            if (r == null) {
10643                throw new SecurityException(
10644                        "Unable to find app for caller " + caller
10645                      + " (pid=" + Binder.getCallingPid()
10646                      + ") when publishing content providers");
10647            }
10648
10649            final long origId = Binder.clearCallingIdentity();
10650
10651            final int N = providers.size();
10652            for (int i = 0; i < N; i++) {
10653                ContentProviderHolder src = providers.get(i);
10654                if (src == null || src.info == null || src.provider == null) {
10655                    continue;
10656                }
10657                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10658                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10659                if (dst != null) {
10660                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10661                    mProviderMap.putProviderByClass(comp, dst);
10662                    String names[] = dst.info.authority.split(";");
10663                    for (int j = 0; j < names.length; j++) {
10664                        mProviderMap.putProviderByName(names[j], dst);
10665                    }
10666
10667                    int launchingCount = mLaunchingProviders.size();
10668                    int j;
10669                    boolean wasInLaunchingProviders = false;
10670                    for (j = 0; j < launchingCount; j++) {
10671                        if (mLaunchingProviders.get(j) == dst) {
10672                            mLaunchingProviders.remove(j);
10673                            wasInLaunchingProviders = true;
10674                            j--;
10675                            launchingCount--;
10676                        }
10677                    }
10678                    if (wasInLaunchingProviders) {
10679                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10680                    }
10681                    synchronized (dst) {
10682                        dst.provider = src.provider;
10683                        dst.proc = r;
10684                        dst.notifyAll();
10685                    }
10686                    updateOomAdjLocked(r);
10687                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10688                            src.info.authority);
10689                }
10690            }
10691
10692            Binder.restoreCallingIdentity(origId);
10693        }
10694    }
10695
10696    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10697        ContentProviderConnection conn;
10698        try {
10699            conn = (ContentProviderConnection)connection;
10700        } catch (ClassCastException e) {
10701            String msg ="refContentProvider: " + connection
10702                    + " not a ContentProviderConnection";
10703            Slog.w(TAG, msg);
10704            throw new IllegalArgumentException(msg);
10705        }
10706        if (conn == null) {
10707            throw new NullPointerException("connection is null");
10708        }
10709
10710        synchronized (this) {
10711            if (stable > 0) {
10712                conn.numStableIncs += stable;
10713            }
10714            stable = conn.stableCount + stable;
10715            if (stable < 0) {
10716                throw new IllegalStateException("stableCount < 0: " + stable);
10717            }
10718
10719            if (unstable > 0) {
10720                conn.numUnstableIncs += unstable;
10721            }
10722            unstable = conn.unstableCount + unstable;
10723            if (unstable < 0) {
10724                throw new IllegalStateException("unstableCount < 0: " + unstable);
10725            }
10726
10727            if ((stable+unstable) <= 0) {
10728                throw new IllegalStateException("ref counts can't go to zero here: stable="
10729                        + stable + " unstable=" + unstable);
10730            }
10731            conn.stableCount = stable;
10732            conn.unstableCount = unstable;
10733            return !conn.dead;
10734        }
10735    }
10736
10737    public void unstableProviderDied(IBinder connection) {
10738        ContentProviderConnection conn;
10739        try {
10740            conn = (ContentProviderConnection)connection;
10741        } catch (ClassCastException e) {
10742            String msg ="refContentProvider: " + connection
10743                    + " not a ContentProviderConnection";
10744            Slog.w(TAG, msg);
10745            throw new IllegalArgumentException(msg);
10746        }
10747        if (conn == null) {
10748            throw new NullPointerException("connection is null");
10749        }
10750
10751        // Safely retrieve the content provider associated with the connection.
10752        IContentProvider provider;
10753        synchronized (this) {
10754            provider = conn.provider.provider;
10755        }
10756
10757        if (provider == null) {
10758            // Um, yeah, we're way ahead of you.
10759            return;
10760        }
10761
10762        // Make sure the caller is being honest with us.
10763        if (provider.asBinder().pingBinder()) {
10764            // Er, no, still looks good to us.
10765            synchronized (this) {
10766                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10767                        + " says " + conn + " died, but we don't agree");
10768                return;
10769            }
10770        }
10771
10772        // Well look at that!  It's dead!
10773        synchronized (this) {
10774            if (conn.provider.provider != provider) {
10775                // But something changed...  good enough.
10776                return;
10777            }
10778
10779            ProcessRecord proc = conn.provider.proc;
10780            if (proc == null || proc.thread == null) {
10781                // Seems like the process is already cleaned up.
10782                return;
10783            }
10784
10785            // As far as we're concerned, this is just like receiving a
10786            // death notification...  just a bit prematurely.
10787            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10788                    + ") early provider death");
10789            final long ident = Binder.clearCallingIdentity();
10790            try {
10791                appDiedLocked(proc);
10792            } finally {
10793                Binder.restoreCallingIdentity(ident);
10794            }
10795        }
10796    }
10797
10798    @Override
10799    public void appNotRespondingViaProvider(IBinder connection) {
10800        enforceCallingPermission(
10801                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10802
10803        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10804        if (conn == null) {
10805            Slog.w(TAG, "ContentProviderConnection is null");
10806            return;
10807        }
10808
10809        final ProcessRecord host = conn.provider.proc;
10810        if (host == null) {
10811            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10812            return;
10813        }
10814
10815        final long token = Binder.clearCallingIdentity();
10816        try {
10817            appNotResponding(host, null, null, false, "ContentProvider not responding");
10818        } finally {
10819            Binder.restoreCallingIdentity(token);
10820        }
10821    }
10822
10823    public final void installSystemProviders() {
10824        List<ProviderInfo> providers;
10825        synchronized (this) {
10826            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10827            providers = generateApplicationProvidersLocked(app);
10828            if (providers != null) {
10829                for (int i=providers.size()-1; i>=0; i--) {
10830                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10831                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10832                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10833                                + ": not system .apk");
10834                        providers.remove(i);
10835                    }
10836                }
10837            }
10838        }
10839        if (providers != null) {
10840            mSystemThread.installSystemProviders(providers);
10841        }
10842
10843        mCoreSettingsObserver = new CoreSettingsObserver(this);
10844
10845        //mUsageStatsService.monitorPackages();
10846    }
10847
10848    /**
10849     * When a user is unlocked, we need to install encryption-unaware providers
10850     * belonging to any running apps.
10851     */
10852    private void installEncryptionUnawareProviders(int userId) {
10853        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10854            // TODO: eventually pivot this back to look at current user state,
10855            // similar to the comment in UserManager.isUserUnlocked(), but for
10856            // now, if we started apps when "unlocked" then unaware providers
10857            // have already been spun up.
10858            return;
10859        }
10860
10861        synchronized (this) {
10862            final int NP = mProcessNames.getMap().size();
10863            for (int ip = 0; ip < NP; ip++) {
10864                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10865                final int NA = apps.size();
10866                for (int ia = 0; ia < NA; ia++) {
10867                    final ProcessRecord app = apps.valueAt(ia);
10868                    if (app.userId != userId || app.thread == null) continue;
10869
10870                    final int NG = app.pkgList.size();
10871                    for (int ig = 0; ig < NG; ig++) {
10872                        try {
10873                            final String pkgName = app.pkgList.keyAt(ig);
10874                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10875                                    .getPackageInfo(pkgName,
10876                                            GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE, userId);
10877                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10878                                for (ProviderInfo provInfo : pkgInfo.providers) {
10879                                    Log.v(TAG, "Installing " + provInfo);
10880                                    app.thread.scheduleInstallProvider(provInfo);
10881                                }
10882                            }
10883                        } catch (RemoteException ignored) {
10884                        }
10885                    }
10886                }
10887            }
10888        }
10889    }
10890
10891    /**
10892     * Allows apps to retrieve the MIME type of a URI.
10893     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10894     * users, then it does not need permission to access the ContentProvider.
10895     * Either, it needs cross-user uri grants.
10896     *
10897     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10898     *
10899     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10900     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10901     */
10902    public String getProviderMimeType(Uri uri, int userId) {
10903        enforceNotIsolatedCaller("getProviderMimeType");
10904        final String name = uri.getAuthority();
10905        int callingUid = Binder.getCallingUid();
10906        int callingPid = Binder.getCallingPid();
10907        long ident = 0;
10908        boolean clearedIdentity = false;
10909        synchronized (this) {
10910            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10911        }
10912        if (canClearIdentity(callingPid, callingUid, userId)) {
10913            clearedIdentity = true;
10914            ident = Binder.clearCallingIdentity();
10915        }
10916        ContentProviderHolder holder = null;
10917        try {
10918            holder = getContentProviderExternalUnchecked(name, null, userId);
10919            if (holder != null) {
10920                return holder.provider.getType(uri);
10921            }
10922        } catch (RemoteException e) {
10923            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10924            return null;
10925        } finally {
10926            // We need to clear the identity to call removeContentProviderExternalUnchecked
10927            if (!clearedIdentity) {
10928                ident = Binder.clearCallingIdentity();
10929            }
10930            try {
10931                if (holder != null) {
10932                    removeContentProviderExternalUnchecked(name, null, userId);
10933                }
10934            } finally {
10935                Binder.restoreCallingIdentity(ident);
10936            }
10937        }
10938
10939        return null;
10940    }
10941
10942    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10943        if (UserHandle.getUserId(callingUid) == userId) {
10944            return true;
10945        }
10946        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10947                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10948                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10949                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10950                return true;
10951        }
10952        return false;
10953    }
10954
10955    // =========================================================
10956    // GLOBAL MANAGEMENT
10957    // =========================================================
10958
10959    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10960            boolean isolated, int isolatedUid) {
10961        String proc = customProcess != null ? customProcess : info.processName;
10962        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10963        final int userId = UserHandle.getUserId(info.uid);
10964        int uid = info.uid;
10965        if (isolated) {
10966            if (isolatedUid == 0) {
10967                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10968                while (true) {
10969                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10970                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10971                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10972                    }
10973                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10974                    mNextIsolatedProcessUid++;
10975                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10976                        // No process for this uid, use it.
10977                        break;
10978                    }
10979                    stepsLeft--;
10980                    if (stepsLeft <= 0) {
10981                        return null;
10982                    }
10983                }
10984            } else {
10985                // Special case for startIsolatedProcess (internal only), where
10986                // the uid of the isolated process is specified by the caller.
10987                uid = isolatedUid;
10988            }
10989        }
10990        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10991        if (!mBooted && !mBooting
10992                && userId == UserHandle.USER_SYSTEM
10993                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10994            r.persistent = true;
10995        }
10996        addProcessNameLocked(r);
10997        return r;
10998    }
10999
11000    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11001            String abiOverride) {
11002        ProcessRecord app;
11003        if (!isolated) {
11004            app = getProcessRecordLocked(info.processName, info.uid, true);
11005        } else {
11006            app = null;
11007        }
11008
11009        if (app == null) {
11010            app = newProcessRecordLocked(info, null, isolated, 0);
11011            updateLruProcessLocked(app, false, null);
11012            updateOomAdjLocked();
11013        }
11014
11015        // This package really, really can not be stopped.
11016        try {
11017            AppGlobals.getPackageManager().setPackageStoppedState(
11018                    info.packageName, false, UserHandle.getUserId(app.uid));
11019        } catch (RemoteException e) {
11020        } catch (IllegalArgumentException e) {
11021            Slog.w(TAG, "Failed trying to unstop package "
11022                    + info.packageName + ": " + e);
11023        }
11024
11025        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11026            app.persistent = true;
11027            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11028        }
11029        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11030            mPersistentStartingProcesses.add(app);
11031            startProcessLocked(app, "added application", app.processName, abiOverride,
11032                    null /* entryPoint */, null /* entryPointArgs */);
11033        }
11034
11035        return app;
11036    }
11037
11038    public void unhandledBack() {
11039        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11040                "unhandledBack()");
11041
11042        synchronized(this) {
11043            final long origId = Binder.clearCallingIdentity();
11044            try {
11045                getFocusedStack().unhandledBackLocked();
11046            } finally {
11047                Binder.restoreCallingIdentity(origId);
11048            }
11049        }
11050    }
11051
11052    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11053        enforceNotIsolatedCaller("openContentUri");
11054        final int userId = UserHandle.getCallingUserId();
11055        String name = uri.getAuthority();
11056        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11057        ParcelFileDescriptor pfd = null;
11058        if (cph != null) {
11059            // We record the binder invoker's uid in thread-local storage before
11060            // going to the content provider to open the file.  Later, in the code
11061            // that handles all permissions checks, we look for this uid and use
11062            // that rather than the Activity Manager's own uid.  The effect is that
11063            // we do the check against the caller's permissions even though it looks
11064            // to the content provider like the Activity Manager itself is making
11065            // the request.
11066            Binder token = new Binder();
11067            sCallerIdentity.set(new Identity(
11068                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11069            try {
11070                pfd = cph.provider.openFile(null, uri, "r", null, token);
11071            } catch (FileNotFoundException e) {
11072                // do nothing; pfd will be returned null
11073            } finally {
11074                // Ensure that whatever happens, we clean up the identity state
11075                sCallerIdentity.remove();
11076                // Ensure we're done with the provider.
11077                removeContentProviderExternalUnchecked(name, null, userId);
11078            }
11079        } else {
11080            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11081        }
11082        return pfd;
11083    }
11084
11085    // Actually is sleeping or shutting down or whatever else in the future
11086    // is an inactive state.
11087    public boolean isSleepingOrShuttingDown() {
11088        return isSleeping() || mShuttingDown;
11089    }
11090
11091    public boolean isSleeping() {
11092        return mSleeping;
11093    }
11094
11095    void onWakefulnessChanged(int wakefulness) {
11096        synchronized(this) {
11097            mWakefulness = wakefulness;
11098            updateSleepIfNeededLocked();
11099        }
11100    }
11101
11102    void finishRunningVoiceLocked() {
11103        if (mRunningVoice != null) {
11104            mRunningVoice = null;
11105            mVoiceWakeLock.release();
11106            updateSleepIfNeededLocked();
11107        }
11108    }
11109
11110    void startTimeTrackingFocusedActivityLocked() {
11111        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11112            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11113        }
11114    }
11115
11116    void updateSleepIfNeededLocked() {
11117        if (mSleeping && !shouldSleepLocked()) {
11118            mSleeping = false;
11119            startTimeTrackingFocusedActivityLocked();
11120            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11121            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11122            updateOomAdjLocked();
11123        } else if (!mSleeping && shouldSleepLocked()) {
11124            mSleeping = true;
11125            if (mCurAppTimeTracker != null) {
11126                mCurAppTimeTracker.stop();
11127            }
11128            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11129            mStackSupervisor.goingToSleepLocked();
11130            updateOomAdjLocked();
11131
11132            // Initialize the wake times of all processes.
11133            checkExcessivePowerUsageLocked(false);
11134            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11135            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11136            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11137        }
11138    }
11139
11140    private boolean shouldSleepLocked() {
11141        // Resume applications while running a voice interactor.
11142        if (mRunningVoice != null) {
11143            return false;
11144        }
11145
11146        // TODO: Transform the lock screen state into a sleep token instead.
11147        switch (mWakefulness) {
11148            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11149            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11150            case PowerManagerInternal.WAKEFULNESS_DOZING:
11151                // Pause applications whenever the lock screen is shown or any sleep
11152                // tokens have been acquired.
11153                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11154            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11155            default:
11156                // If we're asleep then pause applications unconditionally.
11157                return true;
11158        }
11159    }
11160
11161    /** Pokes the task persister. */
11162    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11163        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11164    }
11165
11166    /** Notifies all listeners when the task stack has changed. */
11167    void notifyTaskStackChangedLocked() {
11168        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11169        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11170        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11171        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11172    }
11173
11174    /** Notifies all listeners when an Activity is pinned. */
11175    void notifyActivityPinnedLocked() {
11176        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11177        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11178    }
11179
11180    @Override
11181    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11182        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11183    }
11184
11185    @Override
11186    public boolean shutdown(int timeout) {
11187        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11188                != PackageManager.PERMISSION_GRANTED) {
11189            throw new SecurityException("Requires permission "
11190                    + android.Manifest.permission.SHUTDOWN);
11191        }
11192
11193        boolean timedout = false;
11194
11195        synchronized(this) {
11196            mShuttingDown = true;
11197            updateEventDispatchingLocked();
11198            timedout = mStackSupervisor.shutdownLocked(timeout);
11199        }
11200
11201        mAppOpsService.shutdown();
11202        if (mUsageStatsService != null) {
11203            mUsageStatsService.prepareShutdown();
11204        }
11205        mBatteryStatsService.shutdown();
11206        synchronized (this) {
11207            mProcessStats.shutdownLocked();
11208            notifyTaskPersisterLocked(null, true);
11209        }
11210
11211        return timedout;
11212    }
11213
11214    public final void activitySlept(IBinder token) {
11215        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11216
11217        final long origId = Binder.clearCallingIdentity();
11218
11219        synchronized (this) {
11220            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11221            if (r != null) {
11222                mStackSupervisor.activitySleptLocked(r);
11223            }
11224        }
11225
11226        Binder.restoreCallingIdentity(origId);
11227    }
11228
11229    private String lockScreenShownToString() {
11230        switch (mLockScreenShown) {
11231            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11232            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11233            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11234            default: return "Unknown=" + mLockScreenShown;
11235        }
11236    }
11237
11238    void logLockScreen(String msg) {
11239        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11240                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11241                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11242                + " mSleeping=" + mSleeping);
11243    }
11244
11245    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11246        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11247        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11248            boolean wasRunningVoice = mRunningVoice != null;
11249            mRunningVoice = session;
11250            if (!wasRunningVoice) {
11251                mVoiceWakeLock.acquire();
11252                updateSleepIfNeededLocked();
11253            }
11254        }
11255    }
11256
11257    private void updateEventDispatchingLocked() {
11258        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11259    }
11260
11261    public void setLockScreenShown(boolean shown) {
11262        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11263                != PackageManager.PERMISSION_GRANTED) {
11264            throw new SecurityException("Requires permission "
11265                    + android.Manifest.permission.DEVICE_POWER);
11266        }
11267
11268        final int user = UserHandle.myUserId();
11269        synchronized(this) {
11270            long ident = Binder.clearCallingIdentity();
11271            try {
11272                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11273                    startHomeActivityLocked(user, "setLockScreenShown");
11274                }
11275                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11276                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11277                updateSleepIfNeededLocked();
11278            } finally {
11279                Binder.restoreCallingIdentity(ident);
11280            }
11281        }
11282    }
11283
11284    @Override
11285    public void stopAppSwitches() {
11286        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11287                != PackageManager.PERMISSION_GRANTED) {
11288            throw new SecurityException("viewquires permission "
11289                    + android.Manifest.permission.STOP_APP_SWITCHES);
11290        }
11291
11292        synchronized(this) {
11293            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11294                    + APP_SWITCH_DELAY_TIME;
11295            mDidAppSwitch = false;
11296            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11297            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11298            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11299        }
11300    }
11301
11302    public void resumeAppSwitches() {
11303        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11304                != PackageManager.PERMISSION_GRANTED) {
11305            throw new SecurityException("Requires permission "
11306                    + android.Manifest.permission.STOP_APP_SWITCHES);
11307        }
11308
11309        synchronized(this) {
11310            // Note that we don't execute any pending app switches... we will
11311            // let those wait until either the timeout, or the next start
11312            // activity request.
11313            mAppSwitchesAllowedTime = 0;
11314        }
11315    }
11316
11317    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11318            int callingPid, int callingUid, String name) {
11319        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11320            return true;
11321        }
11322
11323        int perm = checkComponentPermission(
11324                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11325                sourceUid, -1, true);
11326        if (perm == PackageManager.PERMISSION_GRANTED) {
11327            return true;
11328        }
11329
11330        // If the actual IPC caller is different from the logical source, then
11331        // also see if they are allowed to control app switches.
11332        if (callingUid != -1 && callingUid != sourceUid) {
11333            perm = checkComponentPermission(
11334                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11335                    callingUid, -1, true);
11336            if (perm == PackageManager.PERMISSION_GRANTED) {
11337                return true;
11338            }
11339        }
11340
11341        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11342        return false;
11343    }
11344
11345    public void setDebugApp(String packageName, boolean waitForDebugger,
11346            boolean persistent) {
11347        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11348                "setDebugApp()");
11349
11350        long ident = Binder.clearCallingIdentity();
11351        try {
11352            // Note that this is not really thread safe if there are multiple
11353            // callers into it at the same time, but that's not a situation we
11354            // care about.
11355            if (persistent) {
11356                final ContentResolver resolver = mContext.getContentResolver();
11357                Settings.Global.putString(
11358                    resolver, Settings.Global.DEBUG_APP,
11359                    packageName);
11360                Settings.Global.putInt(
11361                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11362                    waitForDebugger ? 1 : 0);
11363            }
11364
11365            synchronized (this) {
11366                if (!persistent) {
11367                    mOrigDebugApp = mDebugApp;
11368                    mOrigWaitForDebugger = mWaitForDebugger;
11369                }
11370                mDebugApp = packageName;
11371                mWaitForDebugger = waitForDebugger;
11372                mDebugTransient = !persistent;
11373                if (packageName != null) {
11374                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11375                            false, UserHandle.USER_ALL, "set debug app");
11376                }
11377            }
11378        } finally {
11379            Binder.restoreCallingIdentity(ident);
11380        }
11381    }
11382
11383    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11384        synchronized (this) {
11385            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11386            if (!isDebuggable) {
11387                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11388                    throw new SecurityException("Process not debuggable: " + app.packageName);
11389                }
11390            }
11391
11392            mTrackAllocationApp = processName;
11393        }
11394    }
11395
11396    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11397        synchronized (this) {
11398            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11399            if (!isDebuggable) {
11400                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11401                    throw new SecurityException("Process not debuggable: " + app.packageName);
11402                }
11403            }
11404            mProfileApp = processName;
11405            mProfileFile = profilerInfo.profileFile;
11406            if (mProfileFd != null) {
11407                try {
11408                    mProfileFd.close();
11409                } catch (IOException e) {
11410                }
11411                mProfileFd = null;
11412            }
11413            mProfileFd = profilerInfo.profileFd;
11414            mSamplingInterval = profilerInfo.samplingInterval;
11415            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11416            mProfileType = 0;
11417        }
11418    }
11419
11420    @Override
11421    public void setAlwaysFinish(boolean enabled) {
11422        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11423                "setAlwaysFinish()");
11424
11425        Settings.Global.putInt(
11426                mContext.getContentResolver(),
11427                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11428
11429        synchronized (this) {
11430            mAlwaysFinishActivities = enabled;
11431        }
11432    }
11433
11434    @Override
11435    public void setActivityController(IActivityController controller) {
11436        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11437                "setActivityController()");
11438        synchronized (this) {
11439            mController = controller;
11440            Watchdog.getInstance().setActivityController(controller);
11441        }
11442    }
11443
11444    @Override
11445    public void setUserIsMonkey(boolean userIsMonkey) {
11446        synchronized (this) {
11447            synchronized (mPidsSelfLocked) {
11448                final int callingPid = Binder.getCallingPid();
11449                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11450                if (precessRecord == null) {
11451                    throw new SecurityException("Unknown process: " + callingPid);
11452                }
11453                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11454                    throw new SecurityException("Only an instrumentation process "
11455                            + "with a UiAutomation can call setUserIsMonkey");
11456                }
11457            }
11458            mUserIsMonkey = userIsMonkey;
11459        }
11460    }
11461
11462    @Override
11463    public boolean isUserAMonkey() {
11464        synchronized (this) {
11465            // If there is a controller also implies the user is a monkey.
11466            return (mUserIsMonkey || mController != null);
11467        }
11468    }
11469
11470    public void requestBugReport(int bugreportType) {
11471        String service = null;
11472        switch (bugreportType) {
11473            case ActivityManager.BUGREPORT_OPTION_FULL:
11474                service = "bugreport";
11475                break;
11476            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11477                service = "bugreportplus";
11478                break;
11479            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11480                service = "bugreportremote";
11481                break;
11482        }
11483        if (service == null) {
11484            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11485                    + bugreportType);
11486        }
11487        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11488        SystemProperties.set("ctl.start", service);
11489    }
11490
11491    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11492        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11493    }
11494
11495    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11496        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11497            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11498        }
11499        return KEY_DISPATCHING_TIMEOUT;
11500    }
11501
11502    @Override
11503    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11504        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11505                != PackageManager.PERMISSION_GRANTED) {
11506            throw new SecurityException("Requires permission "
11507                    + android.Manifest.permission.FILTER_EVENTS);
11508        }
11509        ProcessRecord proc;
11510        long timeout;
11511        synchronized (this) {
11512            synchronized (mPidsSelfLocked) {
11513                proc = mPidsSelfLocked.get(pid);
11514            }
11515            timeout = getInputDispatchingTimeoutLocked(proc);
11516        }
11517
11518        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11519            return -1;
11520        }
11521
11522        return timeout;
11523    }
11524
11525    /**
11526     * Handle input dispatching timeouts.
11527     * Returns whether input dispatching should be aborted or not.
11528     */
11529    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11530            final ActivityRecord activity, final ActivityRecord parent,
11531            final boolean aboveSystem, String reason) {
11532        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11533                != PackageManager.PERMISSION_GRANTED) {
11534            throw new SecurityException("Requires permission "
11535                    + android.Manifest.permission.FILTER_EVENTS);
11536        }
11537
11538        final String annotation;
11539        if (reason == null) {
11540            annotation = "Input dispatching timed out";
11541        } else {
11542            annotation = "Input dispatching timed out (" + reason + ")";
11543        }
11544
11545        if (proc != null) {
11546            synchronized (this) {
11547                if (proc.debugging) {
11548                    return false;
11549                }
11550
11551                if (mDidDexOpt) {
11552                    // Give more time since we were dexopting.
11553                    mDidDexOpt = false;
11554                    return false;
11555                }
11556
11557                if (proc.instrumentationClass != null) {
11558                    Bundle info = new Bundle();
11559                    info.putString("shortMsg", "keyDispatchingTimedOut");
11560                    info.putString("longMsg", annotation);
11561                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11562                    return true;
11563                }
11564            }
11565            mHandler.post(new Runnable() {
11566                @Override
11567                public void run() {
11568                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11569                }
11570            });
11571        }
11572
11573        return true;
11574    }
11575
11576    @Override
11577    public Bundle getAssistContextExtras(int requestType) {
11578        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11579                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11580        if (pae == null) {
11581            return null;
11582        }
11583        synchronized (pae) {
11584            while (!pae.haveResult) {
11585                try {
11586                    pae.wait();
11587                } catch (InterruptedException e) {
11588                }
11589            }
11590        }
11591        synchronized (this) {
11592            buildAssistBundleLocked(pae, pae.result);
11593            mPendingAssistExtras.remove(pae);
11594            mUiHandler.removeCallbacks(pae);
11595        }
11596        return pae.extras;
11597    }
11598
11599    @Override
11600    public boolean isAssistDataAllowedOnCurrentActivity() {
11601        int userId;
11602        synchronized (this) {
11603            userId = mUserController.getCurrentUserIdLocked();
11604            ActivityRecord activity = getFocusedStack().topActivity();
11605            if (activity == null) {
11606                return false;
11607            }
11608            userId = activity.userId;
11609        }
11610        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11611                Context.DEVICE_POLICY_SERVICE);
11612        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11613    }
11614
11615    @Override
11616    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11617        long ident = Binder.clearCallingIdentity();
11618        try {
11619            synchronized (this) {
11620                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11621                ActivityRecord top = getFocusedStack().topActivity();
11622                if (top != caller) {
11623                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11624                            + " is not current top " + top);
11625                    return false;
11626                }
11627                if (!top.nowVisible) {
11628                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11629                            + " is not visible");
11630                    return false;
11631                }
11632            }
11633            AssistUtils utils = new AssistUtils(mContext);
11634            return utils.showSessionForActiveService(args,
11635                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11636        } finally {
11637            Binder.restoreCallingIdentity(ident);
11638        }
11639    }
11640
11641    @Override
11642    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11643            IBinder activityToken) {
11644        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11645                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11646    }
11647
11648    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11649            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11650            long timeout) {
11651        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11652                "enqueueAssistContext()");
11653        synchronized (this) {
11654            ActivityRecord activity = getFocusedStack().topActivity();
11655            if (activity == null) {
11656                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11657                return null;
11658            }
11659            if (activity.app == null || activity.app.thread == null) {
11660                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11661                return null;
11662            }
11663            if (activityToken != null) {
11664                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11665                if (activity != caller) {
11666                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11667                            + " is not current top " + activity);
11668                    return null;
11669                }
11670            }
11671            PendingAssistExtras pae;
11672            Bundle extras = new Bundle();
11673            if (args != null) {
11674                extras.putAll(args);
11675            }
11676            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11677            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11678            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11679            try {
11680                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11681                        requestType);
11682                mPendingAssistExtras.add(pae);
11683                mUiHandler.postDelayed(pae, timeout);
11684            } catch (RemoteException e) {
11685                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11686                return null;
11687            }
11688            return pae;
11689        }
11690    }
11691
11692    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11693        IResultReceiver receiver;
11694        synchronized (this) {
11695            mPendingAssistExtras.remove(pae);
11696            receiver = pae.receiver;
11697        }
11698        if (receiver != null) {
11699            // Caller wants result sent back to them.
11700            try {
11701                pae.receiver.send(0, null);
11702            } catch (RemoteException e) {
11703            }
11704        }
11705    }
11706
11707    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11708        if (result != null) {
11709            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11710        }
11711        if (pae.hint != null) {
11712            pae.extras.putBoolean(pae.hint, true);
11713        }
11714    }
11715
11716    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11717            AssistContent content, Uri referrer) {
11718        PendingAssistExtras pae = (PendingAssistExtras)token;
11719        synchronized (pae) {
11720            pae.result = extras;
11721            pae.structure = structure;
11722            pae.content = content;
11723            if (referrer != null) {
11724                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11725            }
11726            pae.haveResult = true;
11727            pae.notifyAll();
11728            if (pae.intent == null && pae.receiver == null) {
11729                // Caller is just waiting for the result.
11730                return;
11731            }
11732        }
11733
11734        // We are now ready to launch the assist activity.
11735        IResultReceiver sendReceiver = null;
11736        Bundle sendBundle = null;
11737        synchronized (this) {
11738            buildAssistBundleLocked(pae, extras);
11739            boolean exists = mPendingAssistExtras.remove(pae);
11740            mUiHandler.removeCallbacks(pae);
11741            if (!exists) {
11742                // Timed out.
11743                return;
11744            }
11745            if ((sendReceiver=pae.receiver) != null) {
11746                // Caller wants result sent back to them.
11747                sendBundle = new Bundle();
11748                sendBundle.putBundle("data", pae.extras);
11749                sendBundle.putParcelable("structure", pae.structure);
11750                sendBundle.putParcelable("content", pae.content);
11751            }
11752        }
11753        if (sendReceiver != null) {
11754            try {
11755                sendReceiver.send(0, sendBundle);
11756            } catch (RemoteException e) {
11757            }
11758            return;
11759        }
11760
11761        long ident = Binder.clearCallingIdentity();
11762        try {
11763            pae.intent.replaceExtras(pae.extras);
11764            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11765                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11766                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11767            closeSystemDialogs("assist");
11768            try {
11769                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11770            } catch (ActivityNotFoundException e) {
11771                Slog.w(TAG, "No activity to handle assist action.", e);
11772            }
11773        } finally {
11774            Binder.restoreCallingIdentity(ident);
11775        }
11776    }
11777
11778    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11779            Bundle args) {
11780        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11781                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11782    }
11783
11784    public void registerProcessObserver(IProcessObserver observer) {
11785        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11786                "registerProcessObserver()");
11787        synchronized (this) {
11788            mProcessObservers.register(observer);
11789        }
11790    }
11791
11792    @Override
11793    public void unregisterProcessObserver(IProcessObserver observer) {
11794        synchronized (this) {
11795            mProcessObservers.unregister(observer);
11796        }
11797    }
11798
11799    @Override
11800    public void registerUidObserver(IUidObserver observer, int which) {
11801        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11802                "registerUidObserver()");
11803        synchronized (this) {
11804            mUidObservers.register(observer, which);
11805        }
11806    }
11807
11808    @Override
11809    public void unregisterUidObserver(IUidObserver observer) {
11810        synchronized (this) {
11811            mUidObservers.unregister(observer);
11812        }
11813    }
11814
11815    @Override
11816    public boolean convertFromTranslucent(IBinder token) {
11817        final long origId = Binder.clearCallingIdentity();
11818        try {
11819            synchronized (this) {
11820                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11821                if (r == null) {
11822                    return false;
11823                }
11824                final boolean translucentChanged = r.changeWindowTranslucency(true);
11825                if (translucentChanged) {
11826                    r.task.stack.releaseBackgroundResources(r);
11827                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11828                }
11829                mWindowManager.setAppFullscreen(token, true);
11830                return translucentChanged;
11831            }
11832        } finally {
11833            Binder.restoreCallingIdentity(origId);
11834        }
11835    }
11836
11837    @Override
11838    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11839        final long origId = Binder.clearCallingIdentity();
11840        try {
11841            synchronized (this) {
11842                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11843                if (r == null) {
11844                    return false;
11845                }
11846                int index = r.task.mActivities.lastIndexOf(r);
11847                if (index > 0) {
11848                    ActivityRecord under = r.task.mActivities.get(index - 1);
11849                    under.returningOptions = options;
11850                }
11851                final boolean translucentChanged = r.changeWindowTranslucency(false);
11852                if (translucentChanged) {
11853                    r.task.stack.convertActivityToTranslucent(r);
11854                }
11855                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11856                mWindowManager.setAppFullscreen(token, false);
11857                return translucentChanged;
11858            }
11859        } finally {
11860            Binder.restoreCallingIdentity(origId);
11861        }
11862    }
11863
11864    @Override
11865    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11866        final long origId = Binder.clearCallingIdentity();
11867        try {
11868            synchronized (this) {
11869                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11870                if (r != null) {
11871                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11872                }
11873            }
11874            return false;
11875        } finally {
11876            Binder.restoreCallingIdentity(origId);
11877        }
11878    }
11879
11880    @Override
11881    public boolean isBackgroundVisibleBehind(IBinder token) {
11882        final long origId = Binder.clearCallingIdentity();
11883        try {
11884            synchronized (this) {
11885                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11886                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11887                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11888                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11889                return visible;
11890            }
11891        } finally {
11892            Binder.restoreCallingIdentity(origId);
11893        }
11894    }
11895
11896    @Override
11897    public ActivityOptions getActivityOptions(IBinder token) {
11898        final long origId = Binder.clearCallingIdentity();
11899        try {
11900            synchronized (this) {
11901                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11902                if (r != null) {
11903                    final ActivityOptions activityOptions = r.pendingOptions;
11904                    r.pendingOptions = null;
11905                    return activityOptions;
11906                }
11907                return null;
11908            }
11909        } finally {
11910            Binder.restoreCallingIdentity(origId);
11911        }
11912    }
11913
11914    @Override
11915    public void setImmersive(IBinder token, boolean immersive) {
11916        synchronized(this) {
11917            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11918            if (r == null) {
11919                throw new IllegalArgumentException();
11920            }
11921            r.immersive = immersive;
11922
11923            // update associated state if we're frontmost
11924            if (r == mFocusedActivity) {
11925                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11926                applyUpdateLockStateLocked(r);
11927            }
11928        }
11929    }
11930
11931    @Override
11932    public boolean isImmersive(IBinder token) {
11933        synchronized (this) {
11934            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11935            if (r == null) {
11936                throw new IllegalArgumentException();
11937            }
11938            return r.immersive;
11939        }
11940    }
11941
11942    @Override
11943    public void setVrMode(IBinder token, boolean enabled) {
11944        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11945            throw new UnsupportedOperationException("VR mode not supported on this device!");
11946        }
11947
11948        synchronized(this) {
11949            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11950            if (r == null) {
11951                throw new IllegalArgumentException();
11952            }
11953            r.isVrActivity = enabled;
11954
11955            // Update associated state if this activity is currently focused
11956            if (r == mFocusedActivity) {
11957                applyUpdateVrModeLocked(r);
11958            }
11959        }
11960    }
11961
11962    public boolean isTopActivityImmersive() {
11963        enforceNotIsolatedCaller("startActivity");
11964        synchronized (this) {
11965            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11966            return (r != null) ? r.immersive : false;
11967        }
11968    }
11969
11970    @Override
11971    public boolean isTopOfTask(IBinder token) {
11972        synchronized (this) {
11973            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11974            if (r == null) {
11975                throw new IllegalArgumentException();
11976            }
11977            return r.task.getTopActivity() == r;
11978        }
11979    }
11980
11981    public final void enterSafeMode() {
11982        synchronized(this) {
11983            // It only makes sense to do this before the system is ready
11984            // and started launching other packages.
11985            if (!mSystemReady) {
11986                try {
11987                    AppGlobals.getPackageManager().enterSafeMode();
11988                } catch (RemoteException e) {
11989                }
11990            }
11991
11992            mSafeMode = true;
11993        }
11994    }
11995
11996    public final void showSafeModeOverlay() {
11997        View v = LayoutInflater.from(mContext).inflate(
11998                com.android.internal.R.layout.safe_mode, null);
11999        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12000        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12001        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12002        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12003        lp.gravity = Gravity.BOTTOM | Gravity.START;
12004        lp.format = v.getBackground().getOpacity();
12005        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12006                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12007        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12008        ((WindowManager)mContext.getSystemService(
12009                Context.WINDOW_SERVICE)).addView(v, lp);
12010    }
12011
12012    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12013        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12014            return;
12015        }
12016        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12017        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12018        synchronized (stats) {
12019            if (mBatteryStatsService.isOnBattery()) {
12020                mBatteryStatsService.enforceCallingPermission();
12021                int MY_UID = Binder.getCallingUid();
12022                final int uid;
12023                if (sender == null) {
12024                    uid = sourceUid;
12025                } else {
12026                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12027                }
12028                BatteryStatsImpl.Uid.Pkg pkg =
12029                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12030                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12031                pkg.noteWakeupAlarmLocked(tag);
12032            }
12033        }
12034    }
12035
12036    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12037        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12038            return;
12039        }
12040        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12041        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12042        synchronized (stats) {
12043            mBatteryStatsService.enforceCallingPermission();
12044            int MY_UID = Binder.getCallingUid();
12045            final int uid;
12046            if (sender == null) {
12047                uid = sourceUid;
12048            } else {
12049                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12050            }
12051            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12052        }
12053    }
12054
12055    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12056        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12057            return;
12058        }
12059        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12060        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12061        synchronized (stats) {
12062            mBatteryStatsService.enforceCallingPermission();
12063            int MY_UID = Binder.getCallingUid();
12064            final int uid;
12065            if (sender == null) {
12066                uid = sourceUid;
12067            } else {
12068                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12069            }
12070            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12071        }
12072    }
12073
12074    public boolean killPids(int[] pids, String pReason, boolean secure) {
12075        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12076            throw new SecurityException("killPids only available to the system");
12077        }
12078        String reason = (pReason == null) ? "Unknown" : pReason;
12079        // XXX Note: don't acquire main activity lock here, because the window
12080        // manager calls in with its locks held.
12081
12082        boolean killed = false;
12083        synchronized (mPidsSelfLocked) {
12084            int worstType = 0;
12085            for (int i=0; i<pids.length; i++) {
12086                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12087                if (proc != null) {
12088                    int type = proc.setAdj;
12089                    if (type > worstType) {
12090                        worstType = type;
12091                    }
12092                }
12093            }
12094
12095            // If the worst oom_adj is somewhere in the cached proc LRU range,
12096            // then constrain it so we will kill all cached procs.
12097            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12098                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12099                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12100            }
12101
12102            // If this is not a secure call, don't let it kill processes that
12103            // are important.
12104            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12105                worstType = ProcessList.SERVICE_ADJ;
12106            }
12107
12108            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12109            for (int i=0; i<pids.length; i++) {
12110                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12111                if (proc == null) {
12112                    continue;
12113                }
12114                int adj = proc.setAdj;
12115                if (adj >= worstType && !proc.killedByAm) {
12116                    proc.kill(reason, true);
12117                    killed = true;
12118                }
12119            }
12120        }
12121        return killed;
12122    }
12123
12124    @Override
12125    public void killUid(int appId, int userId, String reason) {
12126        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12127        synchronized (this) {
12128            final long identity = Binder.clearCallingIdentity();
12129            try {
12130                killPackageProcessesLocked(null, appId, userId,
12131                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12132                        reason != null ? reason : "kill uid");
12133            } finally {
12134                Binder.restoreCallingIdentity(identity);
12135            }
12136        }
12137    }
12138
12139    @Override
12140    public boolean killProcessesBelowForeground(String reason) {
12141        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12142            throw new SecurityException("killProcessesBelowForeground() only available to system");
12143        }
12144
12145        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12146    }
12147
12148    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12149        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12150            throw new SecurityException("killProcessesBelowAdj() only available to system");
12151        }
12152
12153        boolean killed = false;
12154        synchronized (mPidsSelfLocked) {
12155            final int size = mPidsSelfLocked.size();
12156            for (int i = 0; i < size; i++) {
12157                final int pid = mPidsSelfLocked.keyAt(i);
12158                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12159                if (proc == null) continue;
12160
12161                final int adj = proc.setAdj;
12162                if (adj > belowAdj && !proc.killedByAm) {
12163                    proc.kill(reason, true);
12164                    killed = true;
12165                }
12166            }
12167        }
12168        return killed;
12169    }
12170
12171    @Override
12172    public void hang(final IBinder who, boolean allowRestart) {
12173        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12174                != PackageManager.PERMISSION_GRANTED) {
12175            throw new SecurityException("Requires permission "
12176                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12177        }
12178
12179        final IBinder.DeathRecipient death = new DeathRecipient() {
12180            @Override
12181            public void binderDied() {
12182                synchronized (this) {
12183                    notifyAll();
12184                }
12185            }
12186        };
12187
12188        try {
12189            who.linkToDeath(death, 0);
12190        } catch (RemoteException e) {
12191            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12192            return;
12193        }
12194
12195        synchronized (this) {
12196            Watchdog.getInstance().setAllowRestart(allowRestart);
12197            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12198            synchronized (death) {
12199                while (who.isBinderAlive()) {
12200                    try {
12201                        death.wait();
12202                    } catch (InterruptedException e) {
12203                    }
12204                }
12205            }
12206            Watchdog.getInstance().setAllowRestart(true);
12207        }
12208    }
12209
12210    @Override
12211    public void restart() {
12212        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12213                != PackageManager.PERMISSION_GRANTED) {
12214            throw new SecurityException("Requires permission "
12215                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12216        }
12217
12218        Log.i(TAG, "Sending shutdown broadcast...");
12219
12220        BroadcastReceiver br = new BroadcastReceiver() {
12221            @Override public void onReceive(Context context, Intent intent) {
12222                // Now the broadcast is done, finish up the low-level shutdown.
12223                Log.i(TAG, "Shutting down activity manager...");
12224                shutdown(10000);
12225                Log.i(TAG, "Shutdown complete, restarting!");
12226                Process.killProcess(Process.myPid());
12227                System.exit(10);
12228            }
12229        };
12230
12231        // First send the high-level shut down broadcast.
12232        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12233        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12234        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12235        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12236        mContext.sendOrderedBroadcastAsUser(intent,
12237                UserHandle.ALL, null, br, mHandler, 0, null, null);
12238        */
12239        br.onReceive(mContext, intent);
12240    }
12241
12242    private long getLowRamTimeSinceIdle(long now) {
12243        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12244    }
12245
12246    @Override
12247    public void performIdleMaintenance() {
12248        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12249                != PackageManager.PERMISSION_GRANTED) {
12250            throw new SecurityException("Requires permission "
12251                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12252        }
12253
12254        synchronized (this) {
12255            final long now = SystemClock.uptimeMillis();
12256            final long timeSinceLastIdle = now - mLastIdleTime;
12257            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12258            mLastIdleTime = now;
12259            mLowRamTimeSinceLastIdle = 0;
12260            if (mLowRamStartTime != 0) {
12261                mLowRamStartTime = now;
12262            }
12263
12264            StringBuilder sb = new StringBuilder(128);
12265            sb.append("Idle maintenance over ");
12266            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12267            sb.append(" low RAM for ");
12268            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12269            Slog.i(TAG, sb.toString());
12270
12271            // If at least 1/3 of our time since the last idle period has been spent
12272            // with RAM low, then we want to kill processes.
12273            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12274
12275            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12276                ProcessRecord proc = mLruProcesses.get(i);
12277                if (proc.notCachedSinceIdle) {
12278                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12279                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12280                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12281                        if (doKilling && proc.initialIdlePss != 0
12282                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12283                            sb = new StringBuilder(128);
12284                            sb.append("Kill");
12285                            sb.append(proc.processName);
12286                            sb.append(" in idle maint: pss=");
12287                            sb.append(proc.lastPss);
12288                            sb.append(", swapPss=");
12289                            sb.append(proc.lastSwapPss);
12290                            sb.append(", initialPss=");
12291                            sb.append(proc.initialIdlePss);
12292                            sb.append(", period=");
12293                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12294                            sb.append(", lowRamPeriod=");
12295                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12296                            Slog.wtfQuiet(TAG, sb.toString());
12297                            proc.kill("idle maint (pss " + proc.lastPss
12298                                    + " from " + proc.initialIdlePss + ")", true);
12299                        }
12300                    }
12301                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12302                    proc.notCachedSinceIdle = true;
12303                    proc.initialIdlePss = 0;
12304                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12305                            mTestPssMode, isSleeping(), now);
12306                }
12307            }
12308
12309            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12310            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12311        }
12312    }
12313
12314    private void retrieveSettings() {
12315        final ContentResolver resolver = mContext.getContentResolver();
12316        final boolean freeformWindowManagement =
12317                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12318                        || Settings.Global.getInt(
12319                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12320        final boolean supportsPictureInPicture =
12321                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12322
12323        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12324        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12325        final boolean alwaysFinishActivities =
12326                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12327        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12328        final boolean forceResizable = Settings.Global.getInt(
12329                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12330        // Transfer any global setting for forcing RTL layout, into a System Property
12331        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12332
12333        final Configuration configuration = new Configuration();
12334        Settings.System.getConfiguration(resolver, configuration);
12335        if (forceRtl) {
12336            // This will take care of setting the correct layout direction flags
12337            configuration.setLayoutDirection(configuration.locale);
12338        }
12339
12340        synchronized (this) {
12341            mDebugApp = mOrigDebugApp = debugApp;
12342            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12343            mAlwaysFinishActivities = alwaysFinishActivities;
12344            mForceResizableActivities = forceResizable;
12345            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12346            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12347            // This happens before any activities are started, so we can
12348            // change mConfiguration in-place.
12349            updateConfigurationLocked(configuration, null, true);
12350            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12351                    "Initial config: " + mConfiguration);
12352
12353            // Load resources only after the current configuration has been set.
12354            final Resources res = mContext.getResources();
12355            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12356            mThumbnailWidth = res.getDimensionPixelSize(
12357                    com.android.internal.R.dimen.thumbnail_width);
12358            mThumbnailHeight = res.getDimensionPixelSize(
12359                    com.android.internal.R.dimen.thumbnail_height);
12360            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12361                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12362            final String appsNotReportingCrashes = res.getString(
12363                    com.android.internal.R.string.config_appsNotReportingCrashes);
12364            if (appsNotReportingCrashes != null) {
12365                final String[] split = appsNotReportingCrashes.split(",");
12366                if (split.length > 0) {
12367                    mAppsNotReportingCrashes = new ArraySet<>();
12368                    for (int i = 0; i < split.length; i++) {
12369                        mAppsNotReportingCrashes.add(split[i]);
12370                    }
12371                }
12372            }
12373        }
12374    }
12375
12376    public boolean testIsSystemReady() {
12377        // no need to synchronize(this) just to read & return the value
12378        return mSystemReady;
12379    }
12380
12381    private static File getCalledPreBootReceiversFile() {
12382        File dataDir = Environment.getDataDirectory();
12383        File systemDir = new File(dataDir, "system");
12384        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12385        return fname;
12386    }
12387
12388    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12389        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12390        File file = getCalledPreBootReceiversFile();
12391        FileInputStream fis = null;
12392        try {
12393            fis = new FileInputStream(file);
12394            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12395            int fvers = dis.readInt();
12396            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12397                String vers = dis.readUTF();
12398                String codename = dis.readUTF();
12399                String build = dis.readUTF();
12400                if (android.os.Build.VERSION.RELEASE.equals(vers)
12401                        && android.os.Build.VERSION.CODENAME.equals(codename)
12402                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12403                    int num = dis.readInt();
12404                    while (num > 0) {
12405                        num--;
12406                        String pkg = dis.readUTF();
12407                        String cls = dis.readUTF();
12408                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12409                    }
12410                }
12411            }
12412        } catch (FileNotFoundException e) {
12413        } catch (IOException e) {
12414            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12415        } finally {
12416            if (fis != null) {
12417                try {
12418                    fis.close();
12419                } catch (IOException e) {
12420                }
12421            }
12422        }
12423        return lastDoneReceivers;
12424    }
12425
12426    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12427        File file = getCalledPreBootReceiversFile();
12428        FileOutputStream fos = null;
12429        DataOutputStream dos = null;
12430        try {
12431            fos = new FileOutputStream(file);
12432            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12433            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12434            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12435            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12436            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12437            dos.writeInt(list.size());
12438            for (int i=0; i<list.size(); i++) {
12439                dos.writeUTF(list.get(i).getPackageName());
12440                dos.writeUTF(list.get(i).getClassName());
12441            }
12442        } catch (IOException e) {
12443            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12444            file.delete();
12445        } finally {
12446            FileUtils.sync(fos);
12447            if (dos != null) {
12448                try {
12449                    dos.close();
12450                } catch (IOException e) {
12451                    // TODO Auto-generated catch block
12452                    e.printStackTrace();
12453                }
12454            }
12455        }
12456    }
12457
12458    final class PreBootContinuation extends IIntentReceiver.Stub {
12459        final Intent intent;
12460        final Runnable onFinishCallback;
12461        final ArrayList<ComponentName> doneReceivers;
12462        final List<ResolveInfo> ris;
12463        final int[] users;
12464        int lastRi = -1;
12465        int curRi = 0;
12466        int curUser = 0;
12467
12468        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12469                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12470            intent = _intent;
12471            onFinishCallback = _onFinishCallback;
12472            doneReceivers = _doneReceivers;
12473            ris = _ris;
12474            users = _users;
12475        }
12476
12477        void go() {
12478            if (lastRi != curRi) {
12479                ActivityInfo ai = ris.get(curRi).activityInfo;
12480                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12481                intent.setComponent(comp);
12482                doneReceivers.add(comp);
12483                lastRi = curRi;
12484                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12485                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12486            }
12487            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12488                    + " for user " + users[curUser]);
12489            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12490            broadcastIntentLocked(null, null, intent, null, this,
12491                    0, null, null, null, AppOpsManager.OP_NONE,
12492                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12493        }
12494
12495        public void performReceive(Intent intent, int resultCode,
12496                String data, Bundle extras, boolean ordered,
12497                boolean sticky, int sendingUser) {
12498            curUser++;
12499            if (curUser >= users.length) {
12500                curUser = 0;
12501                curRi++;
12502                if (curRi >= ris.size()) {
12503                    // All done sending broadcasts!
12504                    if (onFinishCallback != null) {
12505                        // The raw IIntentReceiver interface is called
12506                        // with the AM lock held, so redispatch to
12507                        // execute our code without the lock.
12508                        mHandler.post(onFinishCallback);
12509                    }
12510                    return;
12511                }
12512            }
12513            go();
12514        }
12515    }
12516
12517    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12518            ArrayList<ComponentName> doneReceivers) {
12519        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12520        List<ResolveInfo> ris = null;
12521        try {
12522            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12523                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12524        } catch (RemoteException e) {
12525        }
12526        if (ris == null) {
12527            return false;
12528        }
12529        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12530
12531        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12532        for (int i=0; i<ris.size(); i++) {
12533            ActivityInfo ai = ris.get(i).activityInfo;
12534            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12535            if (lastDoneReceivers.contains(comp)) {
12536                // We already did the pre boot receiver for this app with the current
12537                // platform version, so don't do it again...
12538                ris.remove(i);
12539                i--;
12540                // ...however, do keep it as one that has been done, so we don't
12541                // forget about it when rewriting the file of last done receivers.
12542                doneReceivers.add(comp);
12543            }
12544        }
12545
12546        if (ris.size() <= 0) {
12547            return false;
12548        }
12549
12550        // TODO: can we still do this with per user encryption?
12551        final int[] users = mUserController.getUsers();
12552        if (users.length <= 0) {
12553            return false;
12554        }
12555
12556        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12557                ris, users);
12558        cont.go();
12559        return true;
12560    }
12561
12562    public void systemReady(final Runnable goingCallback) {
12563        synchronized(this) {
12564            if (mSystemReady) {
12565                // If we're done calling all the receivers, run the next "boot phase" passed in
12566                // by the SystemServer
12567                if (goingCallback != null) {
12568                    goingCallback.run();
12569                }
12570                return;
12571            }
12572
12573            mLocalDeviceIdleController
12574                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12575
12576            // Make sure we have the current profile info, since it is needed for
12577            // security checks.
12578            mUserController.updateCurrentProfileIdsLocked();
12579
12580            mRecentTasks.onSystemReady();
12581            // Check to see if there are any update receivers to run.
12582            if (!mDidUpdate) {
12583                if (mWaitingUpdate) {
12584                    return;
12585                }
12586                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12587                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12588                    public void run() {
12589                        synchronized (ActivityManagerService.this) {
12590                            mDidUpdate = true;
12591                        }
12592                        showBootMessage(mContext.getText(
12593                                R.string.android_upgrading_complete),
12594                                false);
12595                        writeLastDonePreBootReceivers(doneReceivers);
12596                        systemReady(goingCallback);
12597                    }
12598                }, doneReceivers);
12599
12600                if (mWaitingUpdate) {
12601                    return;
12602                }
12603                mDidUpdate = true;
12604            }
12605
12606            mAppOpsService.systemReady();
12607            mSystemReady = true;
12608        }
12609
12610        ArrayList<ProcessRecord> procsToKill = null;
12611        synchronized(mPidsSelfLocked) {
12612            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12613                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12614                if (!isAllowedWhileBooting(proc.info)){
12615                    if (procsToKill == null) {
12616                        procsToKill = new ArrayList<ProcessRecord>();
12617                    }
12618                    procsToKill.add(proc);
12619                }
12620            }
12621        }
12622
12623        synchronized(this) {
12624            if (procsToKill != null) {
12625                for (int i=procsToKill.size()-1; i>=0; i--) {
12626                    ProcessRecord proc = procsToKill.get(i);
12627                    Slog.i(TAG, "Removing system update proc: " + proc);
12628                    removeProcessLocked(proc, true, false, "system update done");
12629                }
12630            }
12631
12632            // Now that we have cleaned up any update processes, we
12633            // are ready to start launching real processes and know that
12634            // we won't trample on them any more.
12635            mProcessesReady = true;
12636        }
12637
12638        Slog.i(TAG, "System now ready");
12639        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12640            SystemClock.uptimeMillis());
12641
12642        synchronized(this) {
12643            // Make sure we have no pre-ready processes sitting around.
12644
12645            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12646                ResolveInfo ri = mContext.getPackageManager()
12647                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12648                                STOCK_PM_FLAGS);
12649                CharSequence errorMsg = null;
12650                if (ri != null) {
12651                    ActivityInfo ai = ri.activityInfo;
12652                    ApplicationInfo app = ai.applicationInfo;
12653                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12654                        mTopAction = Intent.ACTION_FACTORY_TEST;
12655                        mTopData = null;
12656                        mTopComponent = new ComponentName(app.packageName,
12657                                ai.name);
12658                    } else {
12659                        errorMsg = mContext.getResources().getText(
12660                                com.android.internal.R.string.factorytest_not_system);
12661                    }
12662                } else {
12663                    errorMsg = mContext.getResources().getText(
12664                            com.android.internal.R.string.factorytest_no_action);
12665                }
12666                if (errorMsg != null) {
12667                    mTopAction = null;
12668                    mTopData = null;
12669                    mTopComponent = null;
12670                    Message msg = Message.obtain();
12671                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12672                    msg.getData().putCharSequence("msg", errorMsg);
12673                    mUiHandler.sendMessage(msg);
12674                }
12675            }
12676        }
12677
12678        retrieveSettings();
12679        final int currentUserId;
12680        synchronized (this) {
12681            currentUserId = mUserController.getCurrentUserIdLocked();
12682            readGrantedUriPermissionsLocked();
12683        }
12684
12685        if (goingCallback != null) goingCallback.run();
12686
12687        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12688                Integer.toString(currentUserId), currentUserId);
12689        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12690                Integer.toString(currentUserId), currentUserId);
12691        mSystemServiceManager.startUser(currentUserId);
12692
12693        synchronized (this) {
12694            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12695                try {
12696                    List apps = AppGlobals.getPackageManager().
12697                        getPersistentApplications(STOCK_PM_FLAGS);
12698                    if (apps != null) {
12699                        int N = apps.size();
12700                        int i;
12701                        for (i=0; i<N; i++) {
12702                            ApplicationInfo info
12703                                = (ApplicationInfo)apps.get(i);
12704                            if (info != null &&
12705                                    !info.packageName.equals("android")) {
12706                                addAppLocked(info, false, null /* ABI override */);
12707                            }
12708                        }
12709                    }
12710                } catch (RemoteException ex) {
12711                    // pm is in same process, this will never happen.
12712                }
12713            }
12714
12715            // Start up initial activity.
12716            mBooting = true;
12717            // Enable home activity for system user, so that the system can always boot
12718            if (UserManager.isSplitSystemUser()) {
12719                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12720                try {
12721                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12722                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12723                            UserHandle.USER_SYSTEM);
12724                } catch (RemoteException e) {
12725                    e.rethrowAsRuntimeException();
12726                }
12727            }
12728            startHomeActivityLocked(currentUserId, "systemReady");
12729
12730            try {
12731                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12732                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12733                            + " data partition or your device will be unstable.");
12734                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12735                }
12736            } catch (RemoteException e) {
12737            }
12738
12739            if (!Build.isBuildConsistent()) {
12740                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12741                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12742            }
12743
12744            long ident = Binder.clearCallingIdentity();
12745            try {
12746                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12747                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12748                        | Intent.FLAG_RECEIVER_FOREGROUND);
12749                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12750                broadcastIntentLocked(null, null, intent,
12751                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12752                        null, false, false, MY_PID, Process.SYSTEM_UID,
12753                        currentUserId);
12754                intent = new Intent(Intent.ACTION_USER_STARTING);
12755                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12756                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12757                broadcastIntentLocked(null, null, intent,
12758                        null, new IIntentReceiver.Stub() {
12759                            @Override
12760                            public void performReceive(Intent intent, int resultCode, String data,
12761                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12762                                    throws RemoteException {
12763                            }
12764                        }, 0, null, null,
12765                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12766                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12767            } catch (Throwable t) {
12768                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12769            } finally {
12770                Binder.restoreCallingIdentity(ident);
12771            }
12772            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12773            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12774        }
12775    }
12776
12777    private boolean makeAppCrashingLocked(ProcessRecord app,
12778            String shortMsg, String longMsg, String stackTrace) {
12779        app.crashing = true;
12780        app.crashingReport = generateProcessError(app,
12781                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12782        startAppProblemLocked(app);
12783        app.stopFreezingAllLocked();
12784        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12785    }
12786
12787    private void makeAppNotRespondingLocked(ProcessRecord app,
12788            String activity, String shortMsg, String longMsg) {
12789        app.notResponding = true;
12790        app.notRespondingReport = generateProcessError(app,
12791                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12792                activity, shortMsg, longMsg, null);
12793        startAppProblemLocked(app);
12794        app.stopFreezingAllLocked();
12795    }
12796
12797    /**
12798     * Generate a process error record, suitable for attachment to a ProcessRecord.
12799     *
12800     * @param app The ProcessRecord in which the error occurred.
12801     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12802     *                      ActivityManager.AppErrorStateInfo
12803     * @param activity The activity associated with the crash, if known.
12804     * @param shortMsg Short message describing the crash.
12805     * @param longMsg Long message describing the crash.
12806     * @param stackTrace Full crash stack trace, may be null.
12807     *
12808     * @return Returns a fully-formed AppErrorStateInfo record.
12809     */
12810    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12811            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12812        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12813
12814        report.condition = condition;
12815        report.processName = app.processName;
12816        report.pid = app.pid;
12817        report.uid = app.info.uid;
12818        report.tag = activity;
12819        report.shortMsg = shortMsg;
12820        report.longMsg = longMsg;
12821        report.stackTrace = stackTrace;
12822
12823        return report;
12824    }
12825
12826    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12827        synchronized (this) {
12828            app.crashing = false;
12829            app.crashingReport = null;
12830            app.notResponding = false;
12831            app.notRespondingReport = null;
12832            if (app.anrDialog == fromDialog) {
12833                app.anrDialog = null;
12834            }
12835            if (app.waitDialog == fromDialog) {
12836                app.waitDialog = null;
12837            }
12838            if (app.pid > 0 && app.pid != MY_PID) {
12839                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12840                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12841                app.kill("user request after error", true);
12842            }
12843        }
12844    }
12845
12846    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12847            String shortMsg, String longMsg, String stackTrace) {
12848        long now = SystemClock.uptimeMillis();
12849
12850        Long crashTime;
12851        if (!app.isolated) {
12852            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12853        } else {
12854            crashTime = null;
12855        }
12856        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12857            // This process loses!
12858            Slog.w(TAG, "Process " + app.info.processName
12859                    + " has crashed too many times: killing!");
12860            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12861                    app.userId, app.info.processName, app.uid);
12862            mStackSupervisor.handleAppCrashLocked(app);
12863            if (!app.persistent) {
12864                // We don't want to start this process again until the user
12865                // explicitly does so...  but for persistent process, we really
12866                // need to keep it running.  If a persistent process is actually
12867                // repeatedly crashing, then badness for everyone.
12868                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12869                        app.info.processName);
12870                if (!app.isolated) {
12871                    // XXX We don't have a way to mark isolated processes
12872                    // as bad, since they don't have a peristent identity.
12873                    mBadProcesses.put(app.info.processName, app.uid,
12874                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12875                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12876                }
12877                app.bad = true;
12878                app.removed = true;
12879                // Don't let services in this process be restarted and potentially
12880                // annoy the user repeatedly.  Unless it is persistent, since those
12881                // processes run critical code.
12882                removeProcessLocked(app, false, false, "crash");
12883                mStackSupervisor.resumeFocusedStackTopActivityLocked();
12884                return false;
12885            }
12886            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12887        } else {
12888            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12889        }
12890
12891        // Bump up the crash count of any services currently running in the proc.
12892        for (int i=app.services.size()-1; i>=0; i--) {
12893            // Any services running in the application need to be placed
12894            // back in the pending list.
12895            ServiceRecord sr = app.services.valueAt(i);
12896            sr.crashCount++;
12897        }
12898
12899        // If the crashing process is what we consider to be the "home process" and it has been
12900        // replaced by a third-party app, clear the package preferred activities from packages
12901        // with a home activity running in the process to prevent a repeatedly crashing app
12902        // from blocking the user to manually clear the list.
12903        final ArrayList<ActivityRecord> activities = app.activities;
12904        if (app == mHomeProcess && activities.size() > 0
12905                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12906            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12907                final ActivityRecord r = activities.get(activityNdx);
12908                if (r.isHomeActivity()) {
12909                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12910                    try {
12911                        ActivityThread.getPackageManager()
12912                                .clearPackagePreferredActivities(r.packageName);
12913                    } catch (RemoteException c) {
12914                        // pm is in same process, this will never happen.
12915                    }
12916                }
12917            }
12918        }
12919
12920        if (!app.isolated) {
12921            // XXX Can't keep track of crash times for isolated processes,
12922            // because they don't have a perisistent identity.
12923            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12924        }
12925
12926        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12927        return true;
12928    }
12929
12930    void startAppProblemLocked(ProcessRecord app) {
12931        // If this app is not running under the current user, then we
12932        // can't give it a report button because that would require
12933        // launching the report UI under a different user.
12934        app.errorReportReceiver = null;
12935
12936        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12937            if (app.userId == userId) {
12938                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12939                        mContext, app.info.packageName, app.info.flags);
12940            }
12941        }
12942        skipCurrentReceiverLocked(app);
12943    }
12944
12945    void skipCurrentReceiverLocked(ProcessRecord app) {
12946        for (BroadcastQueue queue : mBroadcastQueues) {
12947            queue.skipCurrentReceiverLocked(app);
12948        }
12949    }
12950
12951    /**
12952     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12953     * The application process will exit immediately after this call returns.
12954     * @param app object of the crashing app, null for the system server
12955     * @param crashInfo describing the exception
12956     */
12957    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12958        ProcessRecord r = findAppProcess(app, "Crash");
12959        final String processName = app == null ? "system_server"
12960                : (r == null ? "unknown" : r.processName);
12961
12962        handleApplicationCrashInner("crash", r, processName, crashInfo);
12963    }
12964
12965    /* Native crash reporting uses this inner version because it needs to be somewhat
12966     * decoupled from the AM-managed cleanup lifecycle
12967     */
12968    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12969            ApplicationErrorReport.CrashInfo crashInfo) {
12970        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12971                UserHandle.getUserId(Binder.getCallingUid()), processName,
12972                r == null ? -1 : r.info.flags,
12973                crashInfo.exceptionClassName,
12974                crashInfo.exceptionMessage,
12975                crashInfo.throwFileName,
12976                crashInfo.throwLineNumber);
12977
12978        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12979
12980        crashApplication(r, crashInfo);
12981    }
12982
12983    public void handleApplicationStrictModeViolation(
12984            IBinder app,
12985            int violationMask,
12986            StrictMode.ViolationInfo info) {
12987        ProcessRecord r = findAppProcess(app, "StrictMode");
12988        if (r == null) {
12989            return;
12990        }
12991
12992        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12993            Integer stackFingerprint = info.hashCode();
12994            boolean logIt = true;
12995            synchronized (mAlreadyLoggedViolatedStacks) {
12996                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12997                    logIt = false;
12998                    // TODO: sub-sample into EventLog for these, with
12999                    // the info.durationMillis?  Then we'd get
13000                    // the relative pain numbers, without logging all
13001                    // the stack traces repeatedly.  We'd want to do
13002                    // likewise in the client code, which also does
13003                    // dup suppression, before the Binder call.
13004                } else {
13005                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13006                        mAlreadyLoggedViolatedStacks.clear();
13007                    }
13008                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13009                }
13010            }
13011            if (logIt) {
13012                logStrictModeViolationToDropBox(r, info);
13013            }
13014        }
13015
13016        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13017            AppErrorResult result = new AppErrorResult();
13018            synchronized (this) {
13019                final long origId = Binder.clearCallingIdentity();
13020
13021                Message msg = Message.obtain();
13022                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13023                HashMap<String, Object> data = new HashMap<String, Object>();
13024                data.put("result", result);
13025                data.put("app", r);
13026                data.put("violationMask", violationMask);
13027                data.put("info", info);
13028                msg.obj = data;
13029                mUiHandler.sendMessage(msg);
13030
13031                Binder.restoreCallingIdentity(origId);
13032            }
13033            int res = result.get();
13034            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13035        }
13036    }
13037
13038    // Depending on the policy in effect, there could be a bunch of
13039    // these in quick succession so we try to batch these together to
13040    // minimize disk writes, number of dropbox entries, and maximize
13041    // compression, by having more fewer, larger records.
13042    private void logStrictModeViolationToDropBox(
13043            ProcessRecord process,
13044            StrictMode.ViolationInfo info) {
13045        if (info == null) {
13046            return;
13047        }
13048        final boolean isSystemApp = process == null ||
13049                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13050                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13051        final String processName = process == null ? "unknown" : process.processName;
13052        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13053        final DropBoxManager dbox = (DropBoxManager)
13054                mContext.getSystemService(Context.DROPBOX_SERVICE);
13055
13056        // Exit early if the dropbox isn't configured to accept this report type.
13057        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13058
13059        boolean bufferWasEmpty;
13060        boolean needsFlush;
13061        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13062        synchronized (sb) {
13063            bufferWasEmpty = sb.length() == 0;
13064            appendDropBoxProcessHeaders(process, processName, sb);
13065            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13066            sb.append("System-App: ").append(isSystemApp).append("\n");
13067            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13068            if (info.violationNumThisLoop != 0) {
13069                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13070            }
13071            if (info.numAnimationsRunning != 0) {
13072                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13073            }
13074            if (info.broadcastIntentAction != null) {
13075                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13076            }
13077            if (info.durationMillis != -1) {
13078                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13079            }
13080            if (info.numInstances != -1) {
13081                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13082            }
13083            if (info.tags != null) {
13084                for (String tag : info.tags) {
13085                    sb.append("Span-Tag: ").append(tag).append("\n");
13086                }
13087            }
13088            sb.append("\n");
13089            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13090                sb.append(info.crashInfo.stackTrace);
13091                sb.append("\n");
13092            }
13093            if (info.message != null) {
13094                sb.append(info.message);
13095                sb.append("\n");
13096            }
13097
13098            // Only buffer up to ~64k.  Various logging bits truncate
13099            // things at 128k.
13100            needsFlush = (sb.length() > 64 * 1024);
13101        }
13102
13103        // Flush immediately if the buffer's grown too large, or this
13104        // is a non-system app.  Non-system apps are isolated with a
13105        // different tag & policy and not batched.
13106        //
13107        // Batching is useful during internal testing with
13108        // StrictMode settings turned up high.  Without batching,
13109        // thousands of separate files could be created on boot.
13110        if (!isSystemApp || needsFlush) {
13111            new Thread("Error dump: " + dropboxTag) {
13112                @Override
13113                public void run() {
13114                    String report;
13115                    synchronized (sb) {
13116                        report = sb.toString();
13117                        sb.delete(0, sb.length());
13118                        sb.trimToSize();
13119                    }
13120                    if (report.length() != 0) {
13121                        dbox.addText(dropboxTag, report);
13122                    }
13123                }
13124            }.start();
13125            return;
13126        }
13127
13128        // System app batching:
13129        if (!bufferWasEmpty) {
13130            // An existing dropbox-writing thread is outstanding, so
13131            // we don't need to start it up.  The existing thread will
13132            // catch the buffer appends we just did.
13133            return;
13134        }
13135
13136        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13137        // (After this point, we shouldn't access AMS internal data structures.)
13138        new Thread("Error dump: " + dropboxTag) {
13139            @Override
13140            public void run() {
13141                // 5 second sleep to let stacks arrive and be batched together
13142                try {
13143                    Thread.sleep(5000);  // 5 seconds
13144                } catch (InterruptedException e) {}
13145
13146                String errorReport;
13147                synchronized (mStrictModeBuffer) {
13148                    errorReport = mStrictModeBuffer.toString();
13149                    if (errorReport.length() == 0) {
13150                        return;
13151                    }
13152                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13153                    mStrictModeBuffer.trimToSize();
13154                }
13155                dbox.addText(dropboxTag, errorReport);
13156            }
13157        }.start();
13158    }
13159
13160    /**
13161     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13162     * @param app object of the crashing app, null for the system server
13163     * @param tag reported by the caller
13164     * @param system whether this wtf is coming from the system
13165     * @param crashInfo describing the context of the error
13166     * @return true if the process should exit immediately (WTF is fatal)
13167     */
13168    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13169            final ApplicationErrorReport.CrashInfo crashInfo) {
13170        final int callingUid = Binder.getCallingUid();
13171        final int callingPid = Binder.getCallingPid();
13172
13173        if (system) {
13174            // If this is coming from the system, we could very well have low-level
13175            // system locks held, so we want to do this all asynchronously.  And we
13176            // never want this to become fatal, so there is that too.
13177            mHandler.post(new Runnable() {
13178                @Override public void run() {
13179                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13180                }
13181            });
13182            return false;
13183        }
13184
13185        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13186                crashInfo);
13187
13188        if (r != null && r.pid != Process.myPid() &&
13189                Settings.Global.getInt(mContext.getContentResolver(),
13190                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13191            crashApplication(r, crashInfo);
13192            return true;
13193        } else {
13194            return false;
13195        }
13196    }
13197
13198    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13199            final ApplicationErrorReport.CrashInfo crashInfo) {
13200        final ProcessRecord r = findAppProcess(app, "WTF");
13201        final String processName = app == null ? "system_server"
13202                : (r == null ? "unknown" : r.processName);
13203
13204        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13205                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13206
13207        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13208
13209        return r;
13210    }
13211
13212    /**
13213     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13214     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13215     */
13216    private ProcessRecord findAppProcess(IBinder app, String reason) {
13217        if (app == null) {
13218            return null;
13219        }
13220
13221        synchronized (this) {
13222            final int NP = mProcessNames.getMap().size();
13223            for (int ip=0; ip<NP; ip++) {
13224                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13225                final int NA = apps.size();
13226                for (int ia=0; ia<NA; ia++) {
13227                    ProcessRecord p = apps.valueAt(ia);
13228                    if (p.thread != null && p.thread.asBinder() == app) {
13229                        return p;
13230                    }
13231                }
13232            }
13233
13234            Slog.w(TAG, "Can't find mystery application for " + reason
13235                    + " from pid=" + Binder.getCallingPid()
13236                    + " uid=" + Binder.getCallingUid() + ": " + app);
13237            return null;
13238        }
13239    }
13240
13241    /**
13242     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13243     * to append various headers to the dropbox log text.
13244     */
13245    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13246            StringBuilder sb) {
13247        // Watchdog thread ends up invoking this function (with
13248        // a null ProcessRecord) to add the stack file to dropbox.
13249        // Do not acquire a lock on this (am) in such cases, as it
13250        // could cause a potential deadlock, if and when watchdog
13251        // is invoked due to unavailability of lock on am and it
13252        // would prevent watchdog from killing system_server.
13253        if (process == null) {
13254            sb.append("Process: ").append(processName).append("\n");
13255            return;
13256        }
13257        // Note: ProcessRecord 'process' is guarded by the service
13258        // instance.  (notably process.pkgList, which could otherwise change
13259        // concurrently during execution of this method)
13260        synchronized (this) {
13261            sb.append("Process: ").append(processName).append("\n");
13262            int flags = process.info.flags;
13263            IPackageManager pm = AppGlobals.getPackageManager();
13264            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13265            for (int ip=0; ip<process.pkgList.size(); ip++) {
13266                String pkg = process.pkgList.keyAt(ip);
13267                sb.append("Package: ").append(pkg);
13268                try {
13269                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13270                    if (pi != null) {
13271                        sb.append(" v").append(pi.versionCode);
13272                        if (pi.versionName != null) {
13273                            sb.append(" (").append(pi.versionName).append(")");
13274                        }
13275                    }
13276                } catch (RemoteException e) {
13277                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13278                }
13279                sb.append("\n");
13280            }
13281        }
13282    }
13283
13284    private static String processClass(ProcessRecord process) {
13285        if (process == null || process.pid == MY_PID) {
13286            return "system_server";
13287        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13288            return "system_app";
13289        } else {
13290            return "data_app";
13291        }
13292    }
13293
13294    /**
13295     * Write a description of an error (crash, WTF, ANR) to the drop box.
13296     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13297     * @param process which caused the error, null means the system server
13298     * @param activity which triggered the error, null if unknown
13299     * @param parent activity related to the error, null if unknown
13300     * @param subject line related to the error, null if absent
13301     * @param report in long form describing the error, null if absent
13302     * @param logFile to include in the report, null if none
13303     * @param crashInfo giving an application stack trace, null if absent
13304     */
13305    public void addErrorToDropBox(String eventType,
13306            ProcessRecord process, String processName, ActivityRecord activity,
13307            ActivityRecord parent, String subject,
13308            final String report, final File logFile,
13309            final ApplicationErrorReport.CrashInfo crashInfo) {
13310        // NOTE -- this must never acquire the ActivityManagerService lock,
13311        // otherwise the watchdog may be prevented from resetting the system.
13312
13313        final String dropboxTag = processClass(process) + "_" + eventType;
13314        final DropBoxManager dbox = (DropBoxManager)
13315                mContext.getSystemService(Context.DROPBOX_SERVICE);
13316
13317        // Exit early if the dropbox isn't configured to accept this report type.
13318        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13319
13320        final StringBuilder sb = new StringBuilder(1024);
13321        appendDropBoxProcessHeaders(process, processName, sb);
13322        if (activity != null) {
13323            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13324        }
13325        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13326            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13327        }
13328        if (parent != null && parent != activity) {
13329            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13330        }
13331        if (subject != null) {
13332            sb.append("Subject: ").append(subject).append("\n");
13333        }
13334        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13335        if (Debug.isDebuggerConnected()) {
13336            sb.append("Debugger: Connected\n");
13337        }
13338        sb.append("\n");
13339
13340        // Do the rest in a worker thread to avoid blocking the caller on I/O
13341        // (After this point, we shouldn't access AMS internal data structures.)
13342        Thread worker = new Thread("Error dump: " + dropboxTag) {
13343            @Override
13344            public void run() {
13345                if (report != null) {
13346                    sb.append(report);
13347                }
13348                if (logFile != null) {
13349                    try {
13350                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13351                                    "\n\n[[TRUNCATED]]"));
13352                    } catch (IOException e) {
13353                        Slog.e(TAG, "Error reading " + logFile, e);
13354                    }
13355                }
13356                if (crashInfo != null && crashInfo.stackTrace != null) {
13357                    sb.append(crashInfo.stackTrace);
13358                }
13359
13360                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13361                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13362                if (lines > 0) {
13363                    sb.append("\n");
13364
13365                    // Merge several logcat streams, and take the last N lines
13366                    InputStreamReader input = null;
13367                    try {
13368                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13369                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13370                                "-b", "crash",
13371                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13372
13373                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13374                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13375                        input = new InputStreamReader(logcat.getInputStream());
13376
13377                        int num;
13378                        char[] buf = new char[8192];
13379                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13380                    } catch (IOException e) {
13381                        Slog.e(TAG, "Error running logcat", e);
13382                    } finally {
13383                        if (input != null) try { input.close(); } catch (IOException e) {}
13384                    }
13385                }
13386
13387                dbox.addText(dropboxTag, sb.toString());
13388            }
13389        };
13390
13391        if (process == null) {
13392            // If process is null, we are being called from some internal code
13393            // and may be about to die -- run this synchronously.
13394            worker.run();
13395        } else {
13396            worker.start();
13397        }
13398    }
13399
13400    /**
13401     * Bring up the "unexpected error" dialog box for a crashing app.
13402     * Deal with edge cases (intercepts from instrumented applications,
13403     * ActivityController, error intent receivers, that sort of thing).
13404     * @param r the application crashing
13405     * @param crashInfo describing the failure
13406     */
13407    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13408        long timeMillis = System.currentTimeMillis();
13409        String shortMsg = crashInfo.exceptionClassName;
13410        String longMsg = crashInfo.exceptionMessage;
13411        String stackTrace = crashInfo.stackTrace;
13412        if (shortMsg != null && longMsg != null) {
13413            longMsg = shortMsg + ": " + longMsg;
13414        } else if (shortMsg != null) {
13415            longMsg = shortMsg;
13416        }
13417
13418        AppErrorResult result = new AppErrorResult();
13419        synchronized (this) {
13420            if (mController != null) {
13421                try {
13422                    String name = r != null ? r.processName : null;
13423                    int pid = r != null ? r.pid : Binder.getCallingPid();
13424                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13425                    if (!mController.appCrashed(name, pid,
13426                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13427                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13428                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13429                            Slog.w(TAG, "Skip killing native crashed app " + name
13430                                    + "(" + pid + ") during testing");
13431                        } else {
13432                            Slog.w(TAG, "Force-killing crashed app " + name
13433                                    + " at watcher's request");
13434                            if (r != null) {
13435                                r.kill("crash", true);
13436                            } else {
13437                                // Huh.
13438                                Process.killProcess(pid);
13439                                killProcessGroup(uid, pid);
13440                            }
13441                        }
13442                        return;
13443                    }
13444                } catch (RemoteException e) {
13445                    mController = null;
13446                    Watchdog.getInstance().setActivityController(null);
13447                }
13448            }
13449
13450            final long origId = Binder.clearCallingIdentity();
13451
13452            // If this process is running instrumentation, finish it.
13453            if (r != null && r.instrumentationClass != null) {
13454                Slog.w(TAG, "Error in app " + r.processName
13455                      + " running instrumentation " + r.instrumentationClass + ":");
13456                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13457                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13458                Bundle info = new Bundle();
13459                info.putString("shortMsg", shortMsg);
13460                info.putString("longMsg", longMsg);
13461                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13462                Binder.restoreCallingIdentity(origId);
13463                return;
13464            }
13465
13466            // Log crash in battery stats.
13467            if (r != null) {
13468                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13469            }
13470
13471            // If we can't identify the process or it's already exceeded its crash quota,
13472            // quit right away without showing a crash dialog.
13473            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13474                Binder.restoreCallingIdentity(origId);
13475                return;
13476            }
13477
13478            Message msg = Message.obtain();
13479            msg.what = SHOW_ERROR_UI_MSG;
13480            HashMap data = new HashMap();
13481            data.put("result", result);
13482            data.put("app", r);
13483            msg.obj = data;
13484            mUiHandler.sendMessage(msg);
13485
13486            Binder.restoreCallingIdentity(origId);
13487        }
13488
13489        int res = result.get();
13490
13491        Intent appErrorIntent = null;
13492        synchronized (this) {
13493            if (r != null && !r.isolated) {
13494                // XXX Can't keep track of crash time for isolated processes,
13495                // since they don't have a persistent identity.
13496                mProcessCrashTimes.put(r.info.processName, r.uid,
13497                        SystemClock.uptimeMillis());
13498            }
13499            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13500                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13501            }
13502        }
13503
13504        if (appErrorIntent != null) {
13505            try {
13506                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13507            } catch (ActivityNotFoundException e) {
13508                Slog.w(TAG, "bug report receiver dissappeared", e);
13509            }
13510        }
13511    }
13512
13513    Intent createAppErrorIntentLocked(ProcessRecord r,
13514            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13515        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13516        if (report == null) {
13517            return null;
13518        }
13519        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13520        result.setComponent(r.errorReportReceiver);
13521        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13522        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13523        return result;
13524    }
13525
13526    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13527            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13528        if (r.errorReportReceiver == null) {
13529            return null;
13530        }
13531
13532        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13533            return null;
13534        }
13535
13536        ApplicationErrorReport report = new ApplicationErrorReport();
13537        report.packageName = r.info.packageName;
13538        report.installerPackageName = r.errorReportReceiver.getPackageName();
13539        report.processName = r.processName;
13540        report.time = timeMillis;
13541        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13542
13543        if (r.crashing || r.forceCrashReport) {
13544            report.type = ApplicationErrorReport.TYPE_CRASH;
13545            report.crashInfo = crashInfo;
13546        } else if (r.notResponding) {
13547            report.type = ApplicationErrorReport.TYPE_ANR;
13548            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13549
13550            report.anrInfo.activity = r.notRespondingReport.tag;
13551            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13552            report.anrInfo.info = r.notRespondingReport.longMsg;
13553        }
13554
13555        return report;
13556    }
13557
13558    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13559        enforceNotIsolatedCaller("getProcessesInErrorState");
13560        // assume our apps are happy - lazy create the list
13561        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13562
13563        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13564                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13565        int userId = UserHandle.getUserId(Binder.getCallingUid());
13566
13567        synchronized (this) {
13568
13569            // iterate across all processes
13570            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13571                ProcessRecord app = mLruProcesses.get(i);
13572                if (!allUsers && app.userId != userId) {
13573                    continue;
13574                }
13575                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13576                    // This one's in trouble, so we'll generate a report for it
13577                    // crashes are higher priority (in case there's a crash *and* an anr)
13578                    ActivityManager.ProcessErrorStateInfo report = null;
13579                    if (app.crashing) {
13580                        report = app.crashingReport;
13581                    } else if (app.notResponding) {
13582                        report = app.notRespondingReport;
13583                    }
13584
13585                    if (report != null) {
13586                        if (errList == null) {
13587                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13588                        }
13589                        errList.add(report);
13590                    } else {
13591                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13592                                " crashing = " + app.crashing +
13593                                " notResponding = " + app.notResponding);
13594                    }
13595                }
13596            }
13597        }
13598
13599        return errList;
13600    }
13601
13602    static int procStateToImportance(int procState, int memAdj,
13603            ActivityManager.RunningAppProcessInfo currApp) {
13604        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13605        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13606            currApp.lru = memAdj;
13607        } else {
13608            currApp.lru = 0;
13609        }
13610        return imp;
13611    }
13612
13613    private void fillInProcMemInfo(ProcessRecord app,
13614            ActivityManager.RunningAppProcessInfo outInfo) {
13615        outInfo.pid = app.pid;
13616        outInfo.uid = app.info.uid;
13617        if (mHeavyWeightProcess == app) {
13618            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13619        }
13620        if (app.persistent) {
13621            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13622        }
13623        if (app.activities.size() > 0) {
13624            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13625        }
13626        outInfo.lastTrimLevel = app.trimMemoryLevel;
13627        int adj = app.curAdj;
13628        int procState = app.curProcState;
13629        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13630        outInfo.importanceReasonCode = app.adjTypeCode;
13631        outInfo.processState = app.curProcState;
13632    }
13633
13634    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13635        enforceNotIsolatedCaller("getRunningAppProcesses");
13636
13637        final int callingUid = Binder.getCallingUid();
13638
13639        // Lazy instantiation of list
13640        List<ActivityManager.RunningAppProcessInfo> runList = null;
13641        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13642                callingUid) == PackageManager.PERMISSION_GRANTED;
13643        final int userId = UserHandle.getUserId(callingUid);
13644        final boolean allUids = isGetTasksAllowed(
13645                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13646
13647        synchronized (this) {
13648            // Iterate across all processes
13649            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13650                ProcessRecord app = mLruProcesses.get(i);
13651                if ((!allUsers && app.userId != userId)
13652                        || (!allUids && app.uid != callingUid)) {
13653                    continue;
13654                }
13655                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13656                    // Generate process state info for running application
13657                    ActivityManager.RunningAppProcessInfo currApp =
13658                        new ActivityManager.RunningAppProcessInfo(app.processName,
13659                                app.pid, app.getPackageList());
13660                    fillInProcMemInfo(app, currApp);
13661                    if (app.adjSource instanceof ProcessRecord) {
13662                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13663                        currApp.importanceReasonImportance =
13664                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13665                                        app.adjSourceProcState);
13666                    } else if (app.adjSource instanceof ActivityRecord) {
13667                        ActivityRecord r = (ActivityRecord)app.adjSource;
13668                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13669                    }
13670                    if (app.adjTarget instanceof ComponentName) {
13671                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13672                    }
13673                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13674                    //        + " lru=" + currApp.lru);
13675                    if (runList == null) {
13676                        runList = new ArrayList<>();
13677                    }
13678                    runList.add(currApp);
13679                }
13680            }
13681        }
13682        return runList;
13683    }
13684
13685    public List<ApplicationInfo> getRunningExternalApplications() {
13686        enforceNotIsolatedCaller("getRunningExternalApplications");
13687        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13688        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13689        if (runningApps != null && runningApps.size() > 0) {
13690            Set<String> extList = new HashSet<String>();
13691            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13692                if (app.pkgList != null) {
13693                    for (String pkg : app.pkgList) {
13694                        extList.add(pkg);
13695                    }
13696                }
13697            }
13698            IPackageManager pm = AppGlobals.getPackageManager();
13699            for (String pkg : extList) {
13700                try {
13701                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13702                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13703                        retList.add(info);
13704                    }
13705                } catch (RemoteException e) {
13706                }
13707            }
13708        }
13709        return retList;
13710    }
13711
13712    @Override
13713    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13714        enforceNotIsolatedCaller("getMyMemoryState");
13715        synchronized (this) {
13716            ProcessRecord proc;
13717            synchronized (mPidsSelfLocked) {
13718                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13719            }
13720            fillInProcMemInfo(proc, outInfo);
13721        }
13722    }
13723
13724    @Override
13725    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13726            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13727        (new ActivityManagerShellCommand(this, false)).exec(
13728                this, in, out, err, args, resultReceiver);
13729    }
13730
13731    @Override
13732    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13733        if (checkCallingPermission(android.Manifest.permission.DUMP)
13734                != PackageManager.PERMISSION_GRANTED) {
13735            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13736                    + Binder.getCallingPid()
13737                    + ", uid=" + Binder.getCallingUid()
13738                    + " without permission "
13739                    + android.Manifest.permission.DUMP);
13740            return;
13741        }
13742
13743        boolean dumpAll = false;
13744        boolean dumpClient = false;
13745        String dumpPackage = null;
13746
13747        int opti = 0;
13748        while (opti < args.length) {
13749            String opt = args[opti];
13750            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13751                break;
13752            }
13753            opti++;
13754            if ("-a".equals(opt)) {
13755                dumpAll = true;
13756            } else if ("-c".equals(opt)) {
13757                dumpClient = true;
13758            } else if ("-p".equals(opt)) {
13759                if (opti < args.length) {
13760                    dumpPackage = args[opti];
13761                    opti++;
13762                } else {
13763                    pw.println("Error: -p option requires package argument");
13764                    return;
13765                }
13766                dumpClient = true;
13767            } else if ("-h".equals(opt)) {
13768                ActivityManagerShellCommand.dumpHelp(pw, true);
13769                return;
13770            } else {
13771                pw.println("Unknown argument: " + opt + "; use -h for help");
13772            }
13773        }
13774
13775        long origId = Binder.clearCallingIdentity();
13776        boolean more = false;
13777        // Is the caller requesting to dump a particular piece of data?
13778        if (opti < args.length) {
13779            String cmd = args[opti];
13780            opti++;
13781            if ("activities".equals(cmd) || "a".equals(cmd)) {
13782                synchronized (this) {
13783                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13784                }
13785            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13786                synchronized (this) {
13787                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13788                }
13789            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13790                String[] newArgs;
13791                String name;
13792                if (opti >= args.length) {
13793                    name = null;
13794                    newArgs = EMPTY_STRING_ARRAY;
13795                } else {
13796                    dumpPackage = args[opti];
13797                    opti++;
13798                    newArgs = new String[args.length - opti];
13799                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13800                            args.length - opti);
13801                }
13802                synchronized (this) {
13803                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13804                }
13805            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13806                String[] newArgs;
13807                String name;
13808                if (opti >= args.length) {
13809                    name = null;
13810                    newArgs = EMPTY_STRING_ARRAY;
13811                } else {
13812                    dumpPackage = args[opti];
13813                    opti++;
13814                    newArgs = new String[args.length - opti];
13815                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13816                            args.length - opti);
13817                }
13818                synchronized (this) {
13819                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13820                }
13821            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13822                String[] newArgs;
13823                String name;
13824                if (opti >= args.length) {
13825                    name = null;
13826                    newArgs = EMPTY_STRING_ARRAY;
13827                } else {
13828                    dumpPackage = args[opti];
13829                    opti++;
13830                    newArgs = new String[args.length - opti];
13831                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13832                            args.length - opti);
13833                }
13834                synchronized (this) {
13835                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13836                }
13837            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13838                synchronized (this) {
13839                    dumpOomLocked(fd, pw, args, opti, true);
13840                }
13841            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13842                synchronized (this) {
13843                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13844                }
13845            } else if ("provider".equals(cmd)) {
13846                String[] newArgs;
13847                String name;
13848                if (opti >= args.length) {
13849                    name = null;
13850                    newArgs = EMPTY_STRING_ARRAY;
13851                } else {
13852                    name = args[opti];
13853                    opti++;
13854                    newArgs = new String[args.length - opti];
13855                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13856                }
13857                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13858                    pw.println("No providers match: " + name);
13859                    pw.println("Use -h for help.");
13860                }
13861            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13862                synchronized (this) {
13863                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13864                }
13865            } else if ("service".equals(cmd)) {
13866                String[] newArgs;
13867                String name;
13868                if (opti >= args.length) {
13869                    name = null;
13870                    newArgs = EMPTY_STRING_ARRAY;
13871                } else {
13872                    name = args[opti];
13873                    opti++;
13874                    newArgs = new String[args.length - opti];
13875                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13876                            args.length - opti);
13877                }
13878                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13879                    pw.println("No services match: " + name);
13880                    pw.println("Use -h for help.");
13881                }
13882            } else if ("package".equals(cmd)) {
13883                String[] newArgs;
13884                if (opti >= args.length) {
13885                    pw.println("package: no package name specified");
13886                    pw.println("Use -h for help.");
13887                } else {
13888                    dumpPackage = args[opti];
13889                    opti++;
13890                    newArgs = new String[args.length - opti];
13891                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13892                            args.length - opti);
13893                    args = newArgs;
13894                    opti = 0;
13895                    more = true;
13896                }
13897            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13898                synchronized (this) {
13899                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13900                }
13901            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13902                synchronized (this) {
13903                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13904                }
13905            } else {
13906                // Dumping a single activity?
13907                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13908                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13909                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13910                    if (res < 0) {
13911                        pw.println("Bad activity command, or no activities match: " + cmd);
13912                        pw.println("Use -h for help.");
13913                    }
13914                }
13915            }
13916            if (!more) {
13917                Binder.restoreCallingIdentity(origId);
13918                return;
13919            }
13920        }
13921
13922        // No piece of data specified, dump everything.
13923        synchronized (this) {
13924            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13925            pw.println();
13926            if (dumpAll) {
13927                pw.println("-------------------------------------------------------------------------------");
13928            }
13929            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13930            pw.println();
13931            if (dumpAll) {
13932                pw.println("-------------------------------------------------------------------------------");
13933            }
13934            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13935            pw.println();
13936            if (dumpAll) {
13937                pw.println("-------------------------------------------------------------------------------");
13938            }
13939            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13940            pw.println();
13941            if (dumpAll) {
13942                pw.println("-------------------------------------------------------------------------------");
13943            }
13944            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13945            pw.println();
13946            if (dumpAll) {
13947                pw.println("-------------------------------------------------------------------------------");
13948            }
13949            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13950            pw.println();
13951            if (dumpAll) {
13952                pw.println("-------------------------------------------------------------------------------");
13953            }
13954            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13955            if (mAssociations.size() > 0) {
13956                pw.println();
13957                if (dumpAll) {
13958                    pw.println("-------------------------------------------------------------------------------");
13959                }
13960                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13961            }
13962            pw.println();
13963            if (dumpAll) {
13964                pw.println("-------------------------------------------------------------------------------");
13965            }
13966            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13967        }
13968        Binder.restoreCallingIdentity(origId);
13969    }
13970
13971    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13972            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13973        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13974
13975        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13976                dumpPackage);
13977        boolean needSep = printedAnything;
13978
13979        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13980                dumpPackage, needSep, "  mFocusedActivity: ");
13981        if (printed) {
13982            printedAnything = true;
13983            needSep = false;
13984        }
13985
13986        if (dumpPackage == null) {
13987            if (needSep) {
13988                pw.println();
13989            }
13990            needSep = true;
13991            printedAnything = true;
13992            mStackSupervisor.dump(pw, "  ");
13993        }
13994
13995        if (!printedAnything) {
13996            pw.println("  (nothing)");
13997        }
13998    }
13999
14000    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14001            int opti, boolean dumpAll, String dumpPackage) {
14002        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14003
14004        boolean printedAnything = false;
14005
14006        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14007            boolean printedHeader = false;
14008
14009            final int N = mRecentTasks.size();
14010            for (int i=0; i<N; i++) {
14011                TaskRecord tr = mRecentTasks.get(i);
14012                if (dumpPackage != null) {
14013                    if (tr.realActivity == null ||
14014                            !dumpPackage.equals(tr.realActivity)) {
14015                        continue;
14016                    }
14017                }
14018                if (!printedHeader) {
14019                    pw.println("  Recent tasks:");
14020                    printedHeader = true;
14021                    printedAnything = true;
14022                }
14023                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14024                        pw.println(tr);
14025                if (dumpAll) {
14026                    mRecentTasks.get(i).dump(pw, "    ");
14027                }
14028            }
14029        }
14030
14031        if (!printedAnything) {
14032            pw.println("  (nothing)");
14033        }
14034    }
14035
14036    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14037            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14038        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14039
14040        int dumpUid = 0;
14041        if (dumpPackage != null) {
14042            IPackageManager pm = AppGlobals.getPackageManager();
14043            try {
14044                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14045            } catch (RemoteException e) {
14046            }
14047        }
14048
14049        boolean printedAnything = false;
14050
14051        final long now = SystemClock.uptimeMillis();
14052
14053        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14054            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14055                    = mAssociations.valueAt(i1);
14056            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14057                SparseArray<ArrayMap<String, Association>> sourceUids
14058                        = targetComponents.valueAt(i2);
14059                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14060                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14061                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14062                        Association ass = sourceProcesses.valueAt(i4);
14063                        if (dumpPackage != null) {
14064                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14065                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14066                                continue;
14067                            }
14068                        }
14069                        printedAnything = true;
14070                        pw.print("  ");
14071                        pw.print(ass.mTargetProcess);
14072                        pw.print("/");
14073                        UserHandle.formatUid(pw, ass.mTargetUid);
14074                        pw.print(" <- ");
14075                        pw.print(ass.mSourceProcess);
14076                        pw.print("/");
14077                        UserHandle.formatUid(pw, ass.mSourceUid);
14078                        pw.println();
14079                        pw.print("    via ");
14080                        pw.print(ass.mTargetComponent.flattenToShortString());
14081                        pw.println();
14082                        pw.print("    ");
14083                        long dur = ass.mTime;
14084                        if (ass.mNesting > 0) {
14085                            dur += now - ass.mStartTime;
14086                        }
14087                        TimeUtils.formatDuration(dur, pw);
14088                        pw.print(" (");
14089                        pw.print(ass.mCount);
14090                        pw.println(" times)");
14091                        if (ass.mNesting > 0) {
14092                            pw.print("    ");
14093                            pw.print(" Currently active: ");
14094                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14095                            pw.println();
14096                        }
14097                    }
14098                }
14099            }
14100
14101        }
14102
14103        if (!printedAnything) {
14104            pw.println("  (nothing)");
14105        }
14106    }
14107
14108    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14109            String header, boolean needSep) {
14110        boolean printed = false;
14111        int whichAppId = -1;
14112        if (dumpPackage != null) {
14113            try {
14114                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14115                        dumpPackage, 0);
14116                whichAppId = UserHandle.getAppId(info.uid);
14117            } catch (NameNotFoundException e) {
14118                e.printStackTrace();
14119            }
14120        }
14121        for (int i=0; i<uids.size(); i++) {
14122            UidRecord uidRec = uids.valueAt(i);
14123            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14124                continue;
14125            }
14126            if (!printed) {
14127                printed = true;
14128                if (needSep) {
14129                    pw.println();
14130                }
14131                pw.print("  ");
14132                pw.println(header);
14133                needSep = true;
14134            }
14135            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14136            pw.print(": "); pw.println(uidRec);
14137        }
14138        return printed;
14139    }
14140
14141    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14142            int opti, boolean dumpAll, String dumpPackage) {
14143        boolean needSep = false;
14144        boolean printedAnything = false;
14145        int numPers = 0;
14146
14147        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14148
14149        if (dumpAll) {
14150            final int NP = mProcessNames.getMap().size();
14151            for (int ip=0; ip<NP; ip++) {
14152                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14153                final int NA = procs.size();
14154                for (int ia=0; ia<NA; ia++) {
14155                    ProcessRecord r = procs.valueAt(ia);
14156                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14157                        continue;
14158                    }
14159                    if (!needSep) {
14160                        pw.println("  All known processes:");
14161                        needSep = true;
14162                        printedAnything = true;
14163                    }
14164                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14165                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14166                        pw.print(" "); pw.println(r);
14167                    r.dump(pw, "    ");
14168                    if (r.persistent) {
14169                        numPers++;
14170                    }
14171                }
14172            }
14173        }
14174
14175        if (mIsolatedProcesses.size() > 0) {
14176            boolean printed = false;
14177            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14178                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14179                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14180                    continue;
14181                }
14182                if (!printed) {
14183                    if (needSep) {
14184                        pw.println();
14185                    }
14186                    pw.println("  Isolated process list (sorted by uid):");
14187                    printedAnything = true;
14188                    printed = true;
14189                    needSep = true;
14190                }
14191                pw.println(String.format("%sIsolated #%2d: %s",
14192                        "    ", i, r.toString()));
14193            }
14194        }
14195
14196        if (mActiveUids.size() > 0) {
14197            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14198                printedAnything = needSep = true;
14199            }
14200        }
14201        if (mValidateUids.size() > 0) {
14202            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14203                printedAnything = needSep = true;
14204            }
14205        }
14206
14207        if (mLruProcesses.size() > 0) {
14208            if (needSep) {
14209                pw.println();
14210            }
14211            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14212                    pw.print(" total, non-act at ");
14213                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14214                    pw.print(", non-svc at ");
14215                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14216                    pw.println("):");
14217            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14218            needSep = true;
14219            printedAnything = true;
14220        }
14221
14222        if (dumpAll || dumpPackage != null) {
14223            synchronized (mPidsSelfLocked) {
14224                boolean printed = false;
14225                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14226                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14227                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14228                        continue;
14229                    }
14230                    if (!printed) {
14231                        if (needSep) pw.println();
14232                        needSep = true;
14233                        pw.println("  PID mappings:");
14234                        printed = true;
14235                        printedAnything = true;
14236                    }
14237                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14238                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14239                }
14240            }
14241        }
14242
14243        if (mForegroundProcesses.size() > 0) {
14244            synchronized (mPidsSelfLocked) {
14245                boolean printed = false;
14246                for (int i=0; i<mForegroundProcesses.size(); i++) {
14247                    ProcessRecord r = mPidsSelfLocked.get(
14248                            mForegroundProcesses.valueAt(i).pid);
14249                    if (dumpPackage != null && (r == null
14250                            || !r.pkgList.containsKey(dumpPackage))) {
14251                        continue;
14252                    }
14253                    if (!printed) {
14254                        if (needSep) pw.println();
14255                        needSep = true;
14256                        pw.println("  Foreground Processes:");
14257                        printed = true;
14258                        printedAnything = true;
14259                    }
14260                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14261                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14262                }
14263            }
14264        }
14265
14266        if (mPersistentStartingProcesses.size() > 0) {
14267            if (needSep) pw.println();
14268            needSep = true;
14269            printedAnything = true;
14270            pw.println("  Persisent processes that are starting:");
14271            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14272                    "Starting Norm", "Restarting PERS", dumpPackage);
14273        }
14274
14275        if (mRemovedProcesses.size() > 0) {
14276            if (needSep) pw.println();
14277            needSep = true;
14278            printedAnything = true;
14279            pw.println("  Processes that are being removed:");
14280            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14281                    "Removed Norm", "Removed PERS", dumpPackage);
14282        }
14283
14284        if (mProcessesOnHold.size() > 0) {
14285            if (needSep) pw.println();
14286            needSep = true;
14287            printedAnything = true;
14288            pw.println("  Processes that are on old until the system is ready:");
14289            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14290                    "OnHold Norm", "OnHold PERS", dumpPackage);
14291        }
14292
14293        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14294
14295        if (mProcessCrashTimes.getMap().size() > 0) {
14296            boolean printed = false;
14297            long now = SystemClock.uptimeMillis();
14298            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14299            final int NP = pmap.size();
14300            for (int ip=0; ip<NP; ip++) {
14301                String pname = pmap.keyAt(ip);
14302                SparseArray<Long> uids = pmap.valueAt(ip);
14303                final int N = uids.size();
14304                for (int i=0; i<N; i++) {
14305                    int puid = uids.keyAt(i);
14306                    ProcessRecord r = mProcessNames.get(pname, puid);
14307                    if (dumpPackage != null && (r == null
14308                            || !r.pkgList.containsKey(dumpPackage))) {
14309                        continue;
14310                    }
14311                    if (!printed) {
14312                        if (needSep) pw.println();
14313                        needSep = true;
14314                        pw.println("  Time since processes crashed:");
14315                        printed = true;
14316                        printedAnything = true;
14317                    }
14318                    pw.print("    Process "); pw.print(pname);
14319                            pw.print(" uid "); pw.print(puid);
14320                            pw.print(": last crashed ");
14321                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14322                            pw.println(" ago");
14323                }
14324            }
14325        }
14326
14327        if (mBadProcesses.getMap().size() > 0) {
14328            boolean printed = false;
14329            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14330            final int NP = pmap.size();
14331            for (int ip=0; ip<NP; ip++) {
14332                String pname = pmap.keyAt(ip);
14333                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14334                final int N = uids.size();
14335                for (int i=0; i<N; i++) {
14336                    int puid = uids.keyAt(i);
14337                    ProcessRecord r = mProcessNames.get(pname, puid);
14338                    if (dumpPackage != null && (r == null
14339                            || !r.pkgList.containsKey(dumpPackage))) {
14340                        continue;
14341                    }
14342                    if (!printed) {
14343                        if (needSep) pw.println();
14344                        needSep = true;
14345                        pw.println("  Bad processes:");
14346                        printedAnything = true;
14347                    }
14348                    BadProcessInfo info = uids.valueAt(i);
14349                    pw.print("    Bad process "); pw.print(pname);
14350                            pw.print(" uid "); pw.print(puid);
14351                            pw.print(": crashed at time "); pw.println(info.time);
14352                    if (info.shortMsg != null) {
14353                        pw.print("      Short msg: "); pw.println(info.shortMsg);
14354                    }
14355                    if (info.longMsg != null) {
14356                        pw.print("      Long msg: "); pw.println(info.longMsg);
14357                    }
14358                    if (info.stack != null) {
14359                        pw.println("      Stack:");
14360                        int lastPos = 0;
14361                        for (int pos=0; pos<info.stack.length(); pos++) {
14362                            if (info.stack.charAt(pos) == '\n') {
14363                                pw.print("        ");
14364                                pw.write(info.stack, lastPos, pos-lastPos);
14365                                pw.println();
14366                                lastPos = pos+1;
14367                            }
14368                        }
14369                        if (lastPos < info.stack.length()) {
14370                            pw.print("        ");
14371                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14372                            pw.println();
14373                        }
14374                    }
14375                }
14376            }
14377        }
14378
14379        if (dumpPackage == null) {
14380            pw.println();
14381            needSep = false;
14382            mUserController.dump(pw, dumpAll);
14383        }
14384        if (mHomeProcess != null && (dumpPackage == null
14385                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14386            if (needSep) {
14387                pw.println();
14388                needSep = false;
14389            }
14390            pw.println("  mHomeProcess: " + mHomeProcess);
14391        }
14392        if (mPreviousProcess != null && (dumpPackage == null
14393                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14394            if (needSep) {
14395                pw.println();
14396                needSep = false;
14397            }
14398            pw.println("  mPreviousProcess: " + mPreviousProcess);
14399        }
14400        if (dumpAll) {
14401            StringBuilder sb = new StringBuilder(128);
14402            sb.append("  mPreviousProcessVisibleTime: ");
14403            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14404            pw.println(sb);
14405        }
14406        if (mHeavyWeightProcess != null && (dumpPackage == null
14407                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14408            if (needSep) {
14409                pw.println();
14410                needSep = false;
14411            }
14412            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14413        }
14414        if (dumpPackage == null) {
14415            pw.println("  mConfiguration: " + mConfiguration);
14416        }
14417        if (dumpAll) {
14418            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14419            if (mCompatModePackages.getPackages().size() > 0) {
14420                boolean printed = false;
14421                for (Map.Entry<String, Integer> entry
14422                        : mCompatModePackages.getPackages().entrySet()) {
14423                    String pkg = entry.getKey();
14424                    int mode = entry.getValue();
14425                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14426                        continue;
14427                    }
14428                    if (!printed) {
14429                        pw.println("  mScreenCompatPackages:");
14430                        printed = true;
14431                    }
14432                    pw.print("    "); pw.print(pkg); pw.print(": ");
14433                            pw.print(mode); pw.println();
14434                }
14435            }
14436        }
14437        if (dumpPackage == null) {
14438            pw.println("  mWakefulness="
14439                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14440            pw.println("  mSleepTokens=" + mSleepTokens);
14441            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14442                    + lockScreenShownToString());
14443            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14444            if (mRunningVoice != null) {
14445                pw.println("  mRunningVoice=" + mRunningVoice);
14446                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14447            }
14448        }
14449        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14450                || mOrigWaitForDebugger) {
14451            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14452                    || dumpPackage.equals(mOrigDebugApp)) {
14453                if (needSep) {
14454                    pw.println();
14455                    needSep = false;
14456                }
14457                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14458                        + " mDebugTransient=" + mDebugTransient
14459                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14460            }
14461        }
14462        if (mCurAppTimeTracker != null) {
14463            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14464        }
14465        if (mMemWatchProcesses.getMap().size() > 0) {
14466            pw.println("  Mem watch processes:");
14467            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14468                    = mMemWatchProcesses.getMap();
14469            for (int i=0; i<procs.size(); i++) {
14470                final String proc = procs.keyAt(i);
14471                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14472                for (int j=0; j<uids.size(); j++) {
14473                    if (needSep) {
14474                        pw.println();
14475                        needSep = false;
14476                    }
14477                    StringBuilder sb = new StringBuilder();
14478                    sb.append("    ").append(proc).append('/');
14479                    UserHandle.formatUid(sb, uids.keyAt(j));
14480                    Pair<Long, String> val = uids.valueAt(j);
14481                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14482                    if (val.second != null) {
14483                        sb.append(", report to ").append(val.second);
14484                    }
14485                    pw.println(sb.toString());
14486                }
14487            }
14488            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14489            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14490            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14491                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14492        }
14493        if (mTrackAllocationApp != null) {
14494            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14495                if (needSep) {
14496                    pw.println();
14497                    needSep = false;
14498                }
14499                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14500            }
14501        }
14502        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14503                || mProfileFd != null) {
14504            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14505                if (needSep) {
14506                    pw.println();
14507                    needSep = false;
14508                }
14509                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14510                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14511                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14512                        + mAutoStopProfiler);
14513                pw.println("  mProfileType=" + mProfileType);
14514            }
14515        }
14516        if (dumpPackage == null) {
14517            if (mAlwaysFinishActivities || mController != null) {
14518                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14519                        + " mController=" + mController);
14520            }
14521            if (dumpAll) {
14522                pw.println("  Total persistent processes: " + numPers);
14523                pw.println("  mProcessesReady=" + mProcessesReady
14524                        + " mSystemReady=" + mSystemReady
14525                        + " mBooted=" + mBooted
14526                        + " mFactoryTest=" + mFactoryTest);
14527                pw.println("  mBooting=" + mBooting
14528                        + " mCallFinishBooting=" + mCallFinishBooting
14529                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14530                pw.print("  mLastPowerCheckRealtime=");
14531                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14532                        pw.println("");
14533                pw.print("  mLastPowerCheckUptime=");
14534                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14535                        pw.println("");
14536                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14537                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14538                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14539                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14540                        + " (" + mLruProcesses.size() + " total)"
14541                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14542                        + " mNumServiceProcs=" + mNumServiceProcs
14543                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14544                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14545                        + " mLastMemoryLevel" + mLastMemoryLevel
14546                        + " mLastNumProcesses" + mLastNumProcesses);
14547                long now = SystemClock.uptimeMillis();
14548                pw.print("  mLastIdleTime=");
14549                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14550                        pw.print(" mLowRamSinceLastIdle=");
14551                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14552                        pw.println();
14553            }
14554        }
14555
14556        if (!printedAnything) {
14557            pw.println("  (nothing)");
14558        }
14559    }
14560
14561    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14562            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14563        if (mProcessesToGc.size() > 0) {
14564            boolean printed = false;
14565            long now = SystemClock.uptimeMillis();
14566            for (int i=0; i<mProcessesToGc.size(); i++) {
14567                ProcessRecord proc = mProcessesToGc.get(i);
14568                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14569                    continue;
14570                }
14571                if (!printed) {
14572                    if (needSep) pw.println();
14573                    needSep = true;
14574                    pw.println("  Processes that are waiting to GC:");
14575                    printed = true;
14576                }
14577                pw.print("    Process "); pw.println(proc);
14578                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14579                        pw.print(", last gced=");
14580                        pw.print(now-proc.lastRequestedGc);
14581                        pw.print(" ms ago, last lowMem=");
14582                        pw.print(now-proc.lastLowMemory);
14583                        pw.println(" ms ago");
14584
14585            }
14586        }
14587        return needSep;
14588    }
14589
14590    void printOomLevel(PrintWriter pw, String name, int adj) {
14591        pw.print("    ");
14592        if (adj >= 0) {
14593            pw.print(' ');
14594            if (adj < 10) pw.print(' ');
14595        } else {
14596            if (adj > -10) pw.print(' ');
14597        }
14598        pw.print(adj);
14599        pw.print(": ");
14600        pw.print(name);
14601        pw.print(" (");
14602        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14603        pw.println(")");
14604    }
14605
14606    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14607            int opti, boolean dumpAll) {
14608        boolean needSep = false;
14609
14610        if (mLruProcesses.size() > 0) {
14611            if (needSep) pw.println();
14612            needSep = true;
14613            pw.println("  OOM levels:");
14614            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14615            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14616            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14617            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14618            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14619            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14620            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14621            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14622            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14623            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14624            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14625            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14626            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14627            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14628
14629            if (needSep) pw.println();
14630            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14631                    pw.print(" total, non-act at ");
14632                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14633                    pw.print(", non-svc at ");
14634                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14635                    pw.println("):");
14636            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14637            needSep = true;
14638        }
14639
14640        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14641
14642        pw.println();
14643        pw.println("  mHomeProcess: " + mHomeProcess);
14644        pw.println("  mPreviousProcess: " + mPreviousProcess);
14645        if (mHeavyWeightProcess != null) {
14646            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14647        }
14648
14649        return true;
14650    }
14651
14652    /**
14653     * There are three ways to call this:
14654     *  - no provider specified: dump all the providers
14655     *  - a flattened component name that matched an existing provider was specified as the
14656     *    first arg: dump that one provider
14657     *  - the first arg isn't the flattened component name of an existing provider:
14658     *    dump all providers whose component contains the first arg as a substring
14659     */
14660    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14661            int opti, boolean dumpAll) {
14662        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14663    }
14664
14665    static class ItemMatcher {
14666        ArrayList<ComponentName> components;
14667        ArrayList<String> strings;
14668        ArrayList<Integer> objects;
14669        boolean all;
14670
14671        ItemMatcher() {
14672            all = true;
14673        }
14674
14675        void build(String name) {
14676            ComponentName componentName = ComponentName.unflattenFromString(name);
14677            if (componentName != null) {
14678                if (components == null) {
14679                    components = new ArrayList<ComponentName>();
14680                }
14681                components.add(componentName);
14682                all = false;
14683            } else {
14684                int objectId = 0;
14685                // Not a '/' separated full component name; maybe an object ID?
14686                try {
14687                    objectId = Integer.parseInt(name, 16);
14688                    if (objects == null) {
14689                        objects = new ArrayList<Integer>();
14690                    }
14691                    objects.add(objectId);
14692                    all = false;
14693                } catch (RuntimeException e) {
14694                    // Not an integer; just do string match.
14695                    if (strings == null) {
14696                        strings = new ArrayList<String>();
14697                    }
14698                    strings.add(name);
14699                    all = false;
14700                }
14701            }
14702        }
14703
14704        int build(String[] args, int opti) {
14705            for (; opti<args.length; opti++) {
14706                String name = args[opti];
14707                if ("--".equals(name)) {
14708                    return opti+1;
14709                }
14710                build(name);
14711            }
14712            return opti;
14713        }
14714
14715        boolean match(Object object, ComponentName comp) {
14716            if (all) {
14717                return true;
14718            }
14719            if (components != null) {
14720                for (int i=0; i<components.size(); i++) {
14721                    if (components.get(i).equals(comp)) {
14722                        return true;
14723                    }
14724                }
14725            }
14726            if (objects != null) {
14727                for (int i=0; i<objects.size(); i++) {
14728                    if (System.identityHashCode(object) == objects.get(i)) {
14729                        return true;
14730                    }
14731                }
14732            }
14733            if (strings != null) {
14734                String flat = comp.flattenToString();
14735                for (int i=0; i<strings.size(); i++) {
14736                    if (flat.contains(strings.get(i))) {
14737                        return true;
14738                    }
14739                }
14740            }
14741            return false;
14742        }
14743    }
14744
14745    /**
14746     * There are three things that cmd can be:
14747     *  - a flattened component name that matches an existing activity
14748     *  - the cmd arg isn't the flattened component name of an existing activity:
14749     *    dump all activity whose component contains the cmd as a substring
14750     *  - A hex number of the ActivityRecord object instance.
14751     */
14752    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14753            int opti, boolean dumpAll) {
14754        ArrayList<ActivityRecord> activities;
14755
14756        synchronized (this) {
14757            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14758        }
14759
14760        if (activities.size() <= 0) {
14761            return false;
14762        }
14763
14764        String[] newArgs = new String[args.length - opti];
14765        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14766
14767        TaskRecord lastTask = null;
14768        boolean needSep = false;
14769        for (int i=activities.size()-1; i>=0; i--) {
14770            ActivityRecord r = activities.get(i);
14771            if (needSep) {
14772                pw.println();
14773            }
14774            needSep = true;
14775            synchronized (this) {
14776                if (lastTask != r.task) {
14777                    lastTask = r.task;
14778                    pw.print("TASK "); pw.print(lastTask.affinity);
14779                            pw.print(" id="); pw.println(lastTask.taskId);
14780                    if (dumpAll) {
14781                        lastTask.dump(pw, "  ");
14782                    }
14783                }
14784            }
14785            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14786        }
14787        return true;
14788    }
14789
14790    /**
14791     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14792     * there is a thread associated with the activity.
14793     */
14794    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14795            final ActivityRecord r, String[] args, boolean dumpAll) {
14796        String innerPrefix = prefix + "  ";
14797        synchronized (this) {
14798            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14799                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14800                    pw.print(" pid=");
14801                    if (r.app != null) pw.println(r.app.pid);
14802                    else pw.println("(not running)");
14803            if (dumpAll) {
14804                r.dump(pw, innerPrefix);
14805            }
14806        }
14807        if (r.app != null && r.app.thread != null) {
14808            // flush anything that is already in the PrintWriter since the thread is going
14809            // to write to the file descriptor directly
14810            pw.flush();
14811            try {
14812                TransferPipe tp = new TransferPipe();
14813                try {
14814                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14815                            r.appToken, innerPrefix, args);
14816                    tp.go(fd);
14817                } finally {
14818                    tp.kill();
14819                }
14820            } catch (IOException e) {
14821                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14822            } catch (RemoteException e) {
14823                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14824            }
14825        }
14826    }
14827
14828    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14829            int opti, boolean dumpAll, String dumpPackage) {
14830        boolean needSep = false;
14831        boolean onlyHistory = false;
14832        boolean printedAnything = false;
14833
14834        if ("history".equals(dumpPackage)) {
14835            if (opti < args.length && "-s".equals(args[opti])) {
14836                dumpAll = false;
14837            }
14838            onlyHistory = true;
14839            dumpPackage = null;
14840        }
14841
14842        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14843        if (!onlyHistory && dumpAll) {
14844            if (mRegisteredReceivers.size() > 0) {
14845                boolean printed = false;
14846                Iterator it = mRegisteredReceivers.values().iterator();
14847                while (it.hasNext()) {
14848                    ReceiverList r = (ReceiverList)it.next();
14849                    if (dumpPackage != null && (r.app == null ||
14850                            !dumpPackage.equals(r.app.info.packageName))) {
14851                        continue;
14852                    }
14853                    if (!printed) {
14854                        pw.println("  Registered Receivers:");
14855                        needSep = true;
14856                        printed = true;
14857                        printedAnything = true;
14858                    }
14859                    pw.print("  * "); pw.println(r);
14860                    r.dump(pw, "    ");
14861                }
14862            }
14863
14864            if (mReceiverResolver.dump(pw, needSep ?
14865                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14866                    "    ", dumpPackage, false, false)) {
14867                needSep = true;
14868                printedAnything = true;
14869            }
14870        }
14871
14872        for (BroadcastQueue q : mBroadcastQueues) {
14873            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14874            printedAnything |= needSep;
14875        }
14876
14877        needSep = true;
14878
14879        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14880            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14881                if (needSep) {
14882                    pw.println();
14883                }
14884                needSep = true;
14885                printedAnything = true;
14886                pw.print("  Sticky broadcasts for user ");
14887                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14888                StringBuilder sb = new StringBuilder(128);
14889                for (Map.Entry<String, ArrayList<Intent>> ent
14890                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14891                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14892                    if (dumpAll) {
14893                        pw.println(":");
14894                        ArrayList<Intent> intents = ent.getValue();
14895                        final int N = intents.size();
14896                        for (int i=0; i<N; i++) {
14897                            sb.setLength(0);
14898                            sb.append("    Intent: ");
14899                            intents.get(i).toShortString(sb, false, true, false, false);
14900                            pw.println(sb.toString());
14901                            Bundle bundle = intents.get(i).getExtras();
14902                            if (bundle != null) {
14903                                pw.print("      ");
14904                                pw.println(bundle.toString());
14905                            }
14906                        }
14907                    } else {
14908                        pw.println("");
14909                    }
14910                }
14911            }
14912        }
14913
14914        if (!onlyHistory && dumpAll) {
14915            pw.println();
14916            for (BroadcastQueue queue : mBroadcastQueues) {
14917                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14918                        + queue.mBroadcastsScheduled);
14919            }
14920            pw.println("  mHandler:");
14921            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14922            needSep = true;
14923            printedAnything = true;
14924        }
14925
14926        if (!printedAnything) {
14927            pw.println("  (nothing)");
14928        }
14929    }
14930
14931    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14932            int opti, boolean dumpAll, String dumpPackage) {
14933        boolean needSep;
14934        boolean printedAnything = false;
14935
14936        ItemMatcher matcher = new ItemMatcher();
14937        matcher.build(args, opti);
14938
14939        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14940
14941        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14942        printedAnything |= needSep;
14943
14944        if (mLaunchingProviders.size() > 0) {
14945            boolean printed = false;
14946            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14947                ContentProviderRecord r = mLaunchingProviders.get(i);
14948                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14949                    continue;
14950                }
14951                if (!printed) {
14952                    if (needSep) pw.println();
14953                    needSep = true;
14954                    pw.println("  Launching content providers:");
14955                    printed = true;
14956                    printedAnything = true;
14957                }
14958                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14959                        pw.println(r);
14960            }
14961        }
14962
14963        if (!printedAnything) {
14964            pw.println("  (nothing)");
14965        }
14966    }
14967
14968    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14969            int opti, boolean dumpAll, String dumpPackage) {
14970        boolean needSep = false;
14971        boolean printedAnything = false;
14972
14973        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14974
14975        if (mGrantedUriPermissions.size() > 0) {
14976            boolean printed = false;
14977            int dumpUid = -2;
14978            if (dumpPackage != null) {
14979                try {
14980                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14981                            MATCH_UNINSTALLED_PACKAGES, 0);
14982                } catch (NameNotFoundException e) {
14983                    dumpUid = -1;
14984                }
14985            }
14986            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14987                int uid = mGrantedUriPermissions.keyAt(i);
14988                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14989                    continue;
14990                }
14991                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14992                if (!printed) {
14993                    if (needSep) pw.println();
14994                    needSep = true;
14995                    pw.println("  Granted Uri Permissions:");
14996                    printed = true;
14997                    printedAnything = true;
14998                }
14999                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15000                for (UriPermission perm : perms.values()) {
15001                    pw.print("    "); pw.println(perm);
15002                    if (dumpAll) {
15003                        perm.dump(pw, "      ");
15004                    }
15005                }
15006            }
15007        }
15008
15009        if (!printedAnything) {
15010            pw.println("  (nothing)");
15011        }
15012    }
15013
15014    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15015            int opti, boolean dumpAll, String dumpPackage) {
15016        boolean printed = false;
15017
15018        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15019
15020        if (mIntentSenderRecords.size() > 0) {
15021            Iterator<WeakReference<PendingIntentRecord>> it
15022                    = mIntentSenderRecords.values().iterator();
15023            while (it.hasNext()) {
15024                WeakReference<PendingIntentRecord> ref = it.next();
15025                PendingIntentRecord rec = ref != null ? ref.get(): null;
15026                if (dumpPackage != null && (rec == null
15027                        || !dumpPackage.equals(rec.key.packageName))) {
15028                    continue;
15029                }
15030                printed = true;
15031                if (rec != null) {
15032                    pw.print("  * "); pw.println(rec);
15033                    if (dumpAll) {
15034                        rec.dump(pw, "    ");
15035                    }
15036                } else {
15037                    pw.print("  * "); pw.println(ref);
15038                }
15039            }
15040        }
15041
15042        if (!printed) {
15043            pw.println("  (nothing)");
15044        }
15045    }
15046
15047    private static final int dumpProcessList(PrintWriter pw,
15048            ActivityManagerService service, List list,
15049            String prefix, String normalLabel, String persistentLabel,
15050            String dumpPackage) {
15051        int numPers = 0;
15052        final int N = list.size()-1;
15053        for (int i=N; i>=0; i--) {
15054            ProcessRecord r = (ProcessRecord)list.get(i);
15055            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15056                continue;
15057            }
15058            pw.println(String.format("%s%s #%2d: %s",
15059                    prefix, (r.persistent ? persistentLabel : normalLabel),
15060                    i, r.toString()));
15061            if (r.persistent) {
15062                numPers++;
15063            }
15064        }
15065        return numPers;
15066    }
15067
15068    private static final boolean dumpProcessOomList(PrintWriter pw,
15069            ActivityManagerService service, List<ProcessRecord> origList,
15070            String prefix, String normalLabel, String persistentLabel,
15071            boolean inclDetails, String dumpPackage) {
15072
15073        ArrayList<Pair<ProcessRecord, Integer>> list
15074                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15075        for (int i=0; i<origList.size(); i++) {
15076            ProcessRecord r = origList.get(i);
15077            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15078                continue;
15079            }
15080            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15081        }
15082
15083        if (list.size() <= 0) {
15084            return false;
15085        }
15086
15087        Comparator<Pair<ProcessRecord, Integer>> comparator
15088                = new Comparator<Pair<ProcessRecord, Integer>>() {
15089            @Override
15090            public int compare(Pair<ProcessRecord, Integer> object1,
15091                    Pair<ProcessRecord, Integer> object2) {
15092                if (object1.first.setAdj != object2.first.setAdj) {
15093                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15094                }
15095                if (object1.first.setProcState != object2.first.setProcState) {
15096                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15097                }
15098                if (object1.second.intValue() != object2.second.intValue()) {
15099                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15100                }
15101                return 0;
15102            }
15103        };
15104
15105        Collections.sort(list, comparator);
15106
15107        final long curRealtime = SystemClock.elapsedRealtime();
15108        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15109        final long curUptime = SystemClock.uptimeMillis();
15110        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15111
15112        for (int i=list.size()-1; i>=0; i--) {
15113            ProcessRecord r = list.get(i).first;
15114            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15115            char schedGroup;
15116            switch (r.setSchedGroup) {
15117                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
15118                    schedGroup = 'B';
15119                    break;
15120                case Process.THREAD_GROUP_DEFAULT:
15121                    schedGroup = 'F';
15122                    break;
15123                default:
15124                    schedGroup = '?';
15125                    break;
15126            }
15127            char foreground;
15128            if (r.foregroundActivities) {
15129                foreground = 'A';
15130            } else if (r.foregroundServices) {
15131                foreground = 'S';
15132            } else {
15133                foreground = ' ';
15134            }
15135            String procState = ProcessList.makeProcStateString(r.curProcState);
15136            pw.print(prefix);
15137            pw.print(r.persistent ? persistentLabel : normalLabel);
15138            pw.print(" #");
15139            int num = (origList.size()-1)-list.get(i).second;
15140            if (num < 10) pw.print(' ');
15141            pw.print(num);
15142            pw.print(": ");
15143            pw.print(oomAdj);
15144            pw.print(' ');
15145            pw.print(schedGroup);
15146            pw.print('/');
15147            pw.print(foreground);
15148            pw.print('/');
15149            pw.print(procState);
15150            pw.print(" trm:");
15151            if (r.trimMemoryLevel < 10) pw.print(' ');
15152            pw.print(r.trimMemoryLevel);
15153            pw.print(' ');
15154            pw.print(r.toShortString());
15155            pw.print(" (");
15156            pw.print(r.adjType);
15157            pw.println(')');
15158            if (r.adjSource != null || r.adjTarget != null) {
15159                pw.print(prefix);
15160                pw.print("    ");
15161                if (r.adjTarget instanceof ComponentName) {
15162                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15163                } else if (r.adjTarget != null) {
15164                    pw.print(r.adjTarget.toString());
15165                } else {
15166                    pw.print("{null}");
15167                }
15168                pw.print("<=");
15169                if (r.adjSource instanceof ProcessRecord) {
15170                    pw.print("Proc{");
15171                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15172                    pw.println("}");
15173                } else if (r.adjSource != null) {
15174                    pw.println(r.adjSource.toString());
15175                } else {
15176                    pw.println("{null}");
15177                }
15178            }
15179            if (inclDetails) {
15180                pw.print(prefix);
15181                pw.print("    ");
15182                pw.print("oom: max="); pw.print(r.maxAdj);
15183                pw.print(" curRaw="); pw.print(r.curRawAdj);
15184                pw.print(" setRaw="); pw.print(r.setRawAdj);
15185                pw.print(" cur="); pw.print(r.curAdj);
15186                pw.print(" set="); pw.println(r.setAdj);
15187                pw.print(prefix);
15188                pw.print("    ");
15189                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15190                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15191                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15192                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15193                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15194                pw.println();
15195                pw.print(prefix);
15196                pw.print("    ");
15197                pw.print("cached="); pw.print(r.cached);
15198                pw.print(" empty="); pw.print(r.empty);
15199                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15200
15201                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15202                    if (r.lastWakeTime != 0) {
15203                        long wtime;
15204                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15205                        synchronized (stats) {
15206                            wtime = stats.getProcessWakeTime(r.info.uid,
15207                                    r.pid, curRealtime);
15208                        }
15209                        long timeUsed = wtime - r.lastWakeTime;
15210                        pw.print(prefix);
15211                        pw.print("    ");
15212                        pw.print("keep awake over ");
15213                        TimeUtils.formatDuration(realtimeSince, pw);
15214                        pw.print(" used ");
15215                        TimeUtils.formatDuration(timeUsed, pw);
15216                        pw.print(" (");
15217                        pw.print((timeUsed*100)/realtimeSince);
15218                        pw.println("%)");
15219                    }
15220                    if (r.lastCpuTime != 0) {
15221                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15222                        pw.print(prefix);
15223                        pw.print("    ");
15224                        pw.print("run cpu over ");
15225                        TimeUtils.formatDuration(uptimeSince, pw);
15226                        pw.print(" used ");
15227                        TimeUtils.formatDuration(timeUsed, pw);
15228                        pw.print(" (");
15229                        pw.print((timeUsed*100)/uptimeSince);
15230                        pw.println("%)");
15231                    }
15232                }
15233            }
15234        }
15235        return true;
15236    }
15237
15238    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15239            String[] args) {
15240        ArrayList<ProcessRecord> procs;
15241        synchronized (this) {
15242            if (args != null && args.length > start
15243                    && args[start].charAt(0) != '-') {
15244                procs = new ArrayList<ProcessRecord>();
15245                int pid = -1;
15246                try {
15247                    pid = Integer.parseInt(args[start]);
15248                } catch (NumberFormatException e) {
15249                }
15250                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15251                    ProcessRecord proc = mLruProcesses.get(i);
15252                    if (proc.pid == pid) {
15253                        procs.add(proc);
15254                    } else if (allPkgs && proc.pkgList != null
15255                            && proc.pkgList.containsKey(args[start])) {
15256                        procs.add(proc);
15257                    } else if (proc.processName.equals(args[start])) {
15258                        procs.add(proc);
15259                    }
15260                }
15261                if (procs.size() <= 0) {
15262                    return null;
15263                }
15264            } else {
15265                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15266            }
15267        }
15268        return procs;
15269    }
15270
15271    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15272            PrintWriter pw, String[] args) {
15273        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15274        if (procs == null) {
15275            pw.println("No process found for: " + args[0]);
15276            return;
15277        }
15278
15279        long uptime = SystemClock.uptimeMillis();
15280        long realtime = SystemClock.elapsedRealtime();
15281        pw.println("Applications Graphics Acceleration Info:");
15282        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15283
15284        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15285            ProcessRecord r = procs.get(i);
15286            if (r.thread != null) {
15287                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15288                pw.flush();
15289                try {
15290                    TransferPipe tp = new TransferPipe();
15291                    try {
15292                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15293                        tp.go(fd);
15294                    } finally {
15295                        tp.kill();
15296                    }
15297                } catch (IOException e) {
15298                    pw.println("Failure while dumping the app: " + r);
15299                    pw.flush();
15300                } catch (RemoteException e) {
15301                    pw.println("Got a RemoteException while dumping the app " + r);
15302                    pw.flush();
15303                }
15304            }
15305        }
15306    }
15307
15308    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15309        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15310        if (procs == null) {
15311            pw.println("No process found for: " + args[0]);
15312            return;
15313        }
15314
15315        pw.println("Applications Database Info:");
15316
15317        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15318            ProcessRecord r = procs.get(i);
15319            if (r.thread != null) {
15320                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15321                pw.flush();
15322                try {
15323                    TransferPipe tp = new TransferPipe();
15324                    try {
15325                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15326                        tp.go(fd);
15327                    } finally {
15328                        tp.kill();
15329                    }
15330                } catch (IOException e) {
15331                    pw.println("Failure while dumping the app: " + r);
15332                    pw.flush();
15333                } catch (RemoteException e) {
15334                    pw.println("Got a RemoteException while dumping the app " + r);
15335                    pw.flush();
15336                }
15337            }
15338        }
15339    }
15340
15341    final static class MemItem {
15342        final boolean isProc;
15343        final String label;
15344        final String shortLabel;
15345        final long pss;
15346        final long swapPss;
15347        final int id;
15348        final boolean hasActivities;
15349        ArrayList<MemItem> subitems;
15350
15351        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15352                boolean _hasActivities) {
15353            isProc = true;
15354            label = _label;
15355            shortLabel = _shortLabel;
15356            pss = _pss;
15357            swapPss = _swapPss;
15358            id = _id;
15359            hasActivities = _hasActivities;
15360        }
15361
15362        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15363            isProc = false;
15364            label = _label;
15365            shortLabel = _shortLabel;
15366            pss = _pss;
15367            swapPss = _swapPss;
15368            id = _id;
15369            hasActivities = false;
15370        }
15371    }
15372
15373    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15374            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15375        if (sort && !isCompact) {
15376            Collections.sort(items, new Comparator<MemItem>() {
15377                @Override
15378                public int compare(MemItem lhs, MemItem rhs) {
15379                    if (lhs.pss < rhs.pss) {
15380                        return 1;
15381                    } else if (lhs.pss > rhs.pss) {
15382                        return -1;
15383                    }
15384                    return 0;
15385                }
15386            });
15387        }
15388
15389        for (int i=0; i<items.size(); i++) {
15390            MemItem mi = items.get(i);
15391            if (!isCompact) {
15392                if (dumpSwapPss) {
15393                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15394                            mi.label, stringifyKBSize(mi.swapPss));
15395                } else {
15396                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15397                }
15398            } else if (mi.isProc) {
15399                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15400                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15401                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15402                pw.println(mi.hasActivities ? ",a" : ",e");
15403            } else {
15404                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15405                pw.println(mi.pss); pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15406            }
15407            if (mi.subitems != null) {
15408                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15409                        true, isCompact, dumpSwapPss);
15410            }
15411        }
15412    }
15413
15414    // These are in KB.
15415    static final long[] DUMP_MEM_BUCKETS = new long[] {
15416        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15417        120*1024, 160*1024, 200*1024,
15418        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15419        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15420    };
15421
15422    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15423            boolean stackLike) {
15424        int start = label.lastIndexOf('.');
15425        if (start >= 0) start++;
15426        else start = 0;
15427        int end = label.length();
15428        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15429            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15430                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15431                out.append(bucket);
15432                out.append(stackLike ? "MB." : "MB ");
15433                out.append(label, start, end);
15434                return;
15435            }
15436        }
15437        out.append(memKB/1024);
15438        out.append(stackLike ? "MB." : "MB ");
15439        out.append(label, start, end);
15440    }
15441
15442    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15443            ProcessList.NATIVE_ADJ,
15444            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15445            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15446            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15447            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15448            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15449            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15450    };
15451    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15452            "Native",
15453            "System", "Persistent", "Persistent Service", "Foreground",
15454            "Visible", "Perceptible",
15455            "Heavy Weight", "Backup",
15456            "A Services", "Home",
15457            "Previous", "B Services", "Cached"
15458    };
15459    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15460            "native",
15461            "sys", "pers", "persvc", "fore",
15462            "vis", "percept",
15463            "heavy", "backup",
15464            "servicea", "home",
15465            "prev", "serviceb", "cached"
15466    };
15467
15468    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15469            long realtime, boolean isCheckinRequest, boolean isCompact) {
15470        if (isCheckinRequest || isCompact) {
15471            // short checkin version
15472            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15473        } else {
15474            pw.println("Applications Memory Usage (in Kilobytes):");
15475            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15476        }
15477    }
15478
15479    private static final int KSM_SHARED = 0;
15480    private static final int KSM_SHARING = 1;
15481    private static final int KSM_UNSHARED = 2;
15482    private static final int KSM_VOLATILE = 3;
15483
15484    private final long[] getKsmInfo() {
15485        long[] longOut = new long[4];
15486        final int[] SINGLE_LONG_FORMAT = new int[] {
15487            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15488        };
15489        long[] longTmp = new long[1];
15490        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15491                SINGLE_LONG_FORMAT, null, longTmp, null);
15492        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15493        longTmp[0] = 0;
15494        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15495                SINGLE_LONG_FORMAT, null, longTmp, null);
15496        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15497        longTmp[0] = 0;
15498        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15499                SINGLE_LONG_FORMAT, null, longTmp, null);
15500        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15501        longTmp[0] = 0;
15502        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15503                SINGLE_LONG_FORMAT, null, longTmp, null);
15504        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15505        return longOut;
15506    }
15507
15508    private static String stringifySize(long size, int order) {
15509        Locale locale = Locale.US;
15510        switch (order) {
15511            case 1:
15512                return String.format(locale, "%,13d", size);
15513            case 1024:
15514                return String.format(locale, "%,9dK", size / 1024);
15515            case 1024 * 1024:
15516                return String.format(locale, "%,5dM", size / 1024 / 1024);
15517            case 1024 * 1024 * 1024:
15518                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15519            default:
15520                throw new IllegalArgumentException("Invalid size order");
15521        }
15522    }
15523
15524    private static String stringifyKBSize(long size) {
15525        return stringifySize(size * 1024, 1024);
15526    }
15527
15528    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15529            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15530        boolean dumpDetails = false;
15531        boolean dumpFullDetails = false;
15532        boolean dumpDalvik = false;
15533        boolean dumpSummaryOnly = false;
15534        boolean oomOnly = false;
15535        boolean isCompact = false;
15536        boolean localOnly = false;
15537        boolean packages = false;
15538        boolean isCheckinRequest = false;
15539        boolean dumpSwapPss = false;
15540
15541        int opti = 0;
15542        while (opti < args.length) {
15543            String opt = args[opti];
15544            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15545                break;
15546            }
15547            opti++;
15548            if ("-a".equals(opt)) {
15549                dumpDetails = true;
15550                dumpFullDetails = true;
15551                dumpDalvik = true;
15552                dumpSwapPss = true;
15553            } else if ("-d".equals(opt)) {
15554                dumpDalvik = true;
15555            } else if ("-c".equals(opt)) {
15556                isCompact = true;
15557            } else if ("-s".equals(opt)) {
15558                dumpDetails = true;
15559                dumpSummaryOnly = true;
15560            } else if ("-S".equals(opt)) {
15561                dumpSwapPss = true;
15562            } else if ("--oom".equals(opt)) {
15563                oomOnly = true;
15564            } else if ("--local".equals(opt)) {
15565                localOnly = true;
15566            } else if ("--package".equals(opt)) {
15567                packages = true;
15568            } else if ("--checkin".equals(opt)) {
15569                isCheckinRequest = true;
15570
15571            } else if ("-h".equals(opt)) {
15572                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15573                pw.println("  -a: include all available information for each process.");
15574                pw.println("  -d: include dalvik details.");
15575                pw.println("  -c: dump in a compact machine-parseable representation.");
15576                pw.println("  -s: dump only summary of application memory usage.");
15577                pw.println("  -S: dump also SwapPss.");
15578                pw.println("  --oom: only show processes organized by oom adj.");
15579                pw.println("  --local: only collect details locally, don't call process.");
15580                pw.println("  --package: interpret process arg as package, dumping all");
15581                pw.println("             processes that have loaded that package.");
15582                pw.println("  --checkin: dump data for a checkin");
15583                pw.println("If [process] is specified it can be the name or ");
15584                pw.println("pid of a specific process to dump.");
15585                return;
15586            } else {
15587                pw.println("Unknown argument: " + opt + "; use -h for help");
15588            }
15589        }
15590
15591        long uptime = SystemClock.uptimeMillis();
15592        long realtime = SystemClock.elapsedRealtime();
15593        final long[] tmpLong = new long[1];
15594
15595        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15596        if (procs == null) {
15597            // No Java processes.  Maybe they want to print a native process.
15598            if (args != null && args.length > opti
15599                    && args[opti].charAt(0) != '-') {
15600                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15601                        = new ArrayList<ProcessCpuTracker.Stats>();
15602                updateCpuStatsNow();
15603                int findPid = -1;
15604                try {
15605                    findPid = Integer.parseInt(args[opti]);
15606                } catch (NumberFormatException e) {
15607                }
15608                synchronized (mProcessCpuTracker) {
15609                    final int N = mProcessCpuTracker.countStats();
15610                    for (int i=0; i<N; i++) {
15611                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15612                        if (st.pid == findPid || (st.baseName != null
15613                                && st.baseName.equals(args[opti]))) {
15614                            nativeProcs.add(st);
15615                        }
15616                    }
15617                }
15618                if (nativeProcs.size() > 0) {
15619                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15620                            isCompact);
15621                    Debug.MemoryInfo mi = null;
15622                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15623                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15624                        final int pid = r.pid;
15625                        if (!isCheckinRequest && dumpDetails) {
15626                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15627                        }
15628                        if (mi == null) {
15629                            mi = new Debug.MemoryInfo();
15630                        }
15631                        if (dumpDetails || (!brief && !oomOnly)) {
15632                            Debug.getMemoryInfo(pid, mi);
15633                        } else {
15634                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15635                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15636                        }
15637                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15638                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15639                        if (isCheckinRequest) {
15640                            pw.println();
15641                        }
15642                    }
15643                    return;
15644                }
15645            }
15646            pw.println("No process found for: " + args[opti]);
15647            return;
15648        }
15649
15650        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15651            dumpDetails = true;
15652        }
15653
15654        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15655
15656        String[] innerArgs = new String[args.length-opti];
15657        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15658
15659        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15660        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15661        long nativePss = 0;
15662        long nativeSwapPss = 0;
15663        long dalvikPss = 0;
15664        long dalvikSwapPss = 0;
15665        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15666                EmptyArray.LONG;
15667        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15668                EmptyArray.LONG;
15669        long otherPss = 0;
15670        long otherSwapPss = 0;
15671        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15672        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15673
15674        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15675        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15676        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15677                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15678
15679        long totalPss = 0;
15680        long totalSwapPss = 0;
15681        long cachedPss = 0;
15682        long cachedSwapPss = 0;
15683        boolean hasSwapPss = false;
15684
15685        Debug.MemoryInfo mi = null;
15686        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15687            final ProcessRecord r = procs.get(i);
15688            final IApplicationThread thread;
15689            final int pid;
15690            final int oomAdj;
15691            final boolean hasActivities;
15692            synchronized (this) {
15693                thread = r.thread;
15694                pid = r.pid;
15695                oomAdj = r.getSetAdjWithServices();
15696                hasActivities = r.activities.size() > 0;
15697            }
15698            if (thread != null) {
15699                if (!isCheckinRequest && dumpDetails) {
15700                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15701                }
15702                if (mi == null) {
15703                    mi = new Debug.MemoryInfo();
15704                }
15705                if (dumpDetails || (!brief && !oomOnly)) {
15706                    Debug.getMemoryInfo(pid, mi);
15707                    hasSwapPss = mi.hasSwappedOutPss;
15708                } else {
15709                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15710                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15711                }
15712                if (dumpDetails) {
15713                    if (localOnly) {
15714                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15715                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15716                        if (isCheckinRequest) {
15717                            pw.println();
15718                        }
15719                    } else {
15720                        try {
15721                            pw.flush();
15722                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15723                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15724                        } catch (RemoteException e) {
15725                            if (!isCheckinRequest) {
15726                                pw.println("Got RemoteException!");
15727                                pw.flush();
15728                            }
15729                        }
15730                    }
15731                }
15732
15733                final long myTotalPss = mi.getTotalPss();
15734                final long myTotalUss = mi.getTotalUss();
15735                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15736
15737                synchronized (this) {
15738                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15739                        // Record this for posterity if the process has been stable.
15740                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15741                    }
15742                }
15743
15744                if (!isCheckinRequest && mi != null) {
15745                    totalPss += myTotalPss;
15746                    totalSwapPss += myTotalSwapPss;
15747                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15748                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15749                            myTotalSwapPss, pid, hasActivities);
15750                    procMems.add(pssItem);
15751                    procMemsMap.put(pid, pssItem);
15752
15753                    nativePss += mi.nativePss;
15754                    nativeSwapPss += mi.nativeSwappedOutPss;
15755                    dalvikPss += mi.dalvikPss;
15756                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15757                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15758                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15759                        dalvikSubitemSwapPss[j] +=
15760                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15761                    }
15762                    otherPss += mi.otherPss;
15763                    otherSwapPss += mi.otherSwappedOutPss;
15764                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15765                        long mem = mi.getOtherPss(j);
15766                        miscPss[j] += mem;
15767                        otherPss -= mem;
15768                        mem = mi.getOtherSwappedOutPss(j);
15769                        miscSwapPss[j] += mem;
15770                        otherSwapPss -= mem;
15771                    }
15772
15773                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15774                        cachedPss += myTotalPss;
15775                        cachedSwapPss += myTotalSwapPss;
15776                    }
15777
15778                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15779                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15780                                || oomIndex == (oomPss.length-1)) {
15781                            oomPss[oomIndex] += myTotalPss;
15782                            oomSwapPss[oomIndex] += myTotalSwapPss;
15783                            if (oomProcs[oomIndex] == null) {
15784                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15785                            }
15786                            oomProcs[oomIndex].add(pssItem);
15787                            break;
15788                        }
15789                    }
15790                }
15791            }
15792        }
15793
15794        long nativeProcTotalPss = 0;
15795
15796        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15797            // If we are showing aggregations, also look for native processes to
15798            // include so that our aggregations are more accurate.
15799            updateCpuStatsNow();
15800            mi = null;
15801            synchronized (mProcessCpuTracker) {
15802                final int N = mProcessCpuTracker.countStats();
15803                for (int i=0; i<N; i++) {
15804                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15805                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15806                        if (mi == null) {
15807                            mi = new Debug.MemoryInfo();
15808                        }
15809                        if (!brief && !oomOnly) {
15810                            Debug.getMemoryInfo(st.pid, mi);
15811                        } else {
15812                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15813                            mi.nativePrivateDirty = (int)tmpLong[0];
15814                        }
15815
15816                        final long myTotalPss = mi.getTotalPss();
15817                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15818                        totalPss += myTotalPss;
15819                        nativeProcTotalPss += myTotalPss;
15820
15821                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15822                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15823                        procMems.add(pssItem);
15824
15825                        nativePss += mi.nativePss;
15826                        nativeSwapPss += mi.nativeSwappedOutPss;
15827                        dalvikPss += mi.dalvikPss;
15828                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15829                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15830                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15831                            dalvikSubitemSwapPss[j] +=
15832                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15833                        }
15834                        otherPss += mi.otherPss;
15835                        otherSwapPss += mi.otherSwappedOutPss;
15836                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15837                            long mem = mi.getOtherPss(j);
15838                            miscPss[j] += mem;
15839                            otherPss -= mem;
15840                            mem = mi.getOtherSwappedOutPss(j);
15841                            miscSwapPss[j] += mem;
15842                            otherSwapPss -= mem;
15843                        }
15844                        oomPss[0] += myTotalPss;
15845                        oomSwapPss[0] += myTotalSwapPss;
15846                        if (oomProcs[0] == null) {
15847                            oomProcs[0] = new ArrayList<MemItem>();
15848                        }
15849                        oomProcs[0].add(pssItem);
15850                    }
15851                }
15852            }
15853
15854            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15855
15856            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15857            final MemItem dalvikItem =
15858                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15859            if (dalvikSubitemPss.length > 0) {
15860                dalvikItem.subitems = new ArrayList<MemItem>();
15861                for (int j=0; j<dalvikSubitemPss.length; j++) {
15862                    final String name = Debug.MemoryInfo.getOtherLabel(
15863                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15864                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15865                                    dalvikSubitemSwapPss[j], j));
15866                }
15867            }
15868            catMems.add(dalvikItem);
15869            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15870            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15871                String label = Debug.MemoryInfo.getOtherLabel(j);
15872                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15873            }
15874
15875            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15876            for (int j=0; j<oomPss.length; j++) {
15877                if (oomPss[j] != 0) {
15878                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15879                            : DUMP_MEM_OOM_LABEL[j];
15880                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15881                            DUMP_MEM_OOM_ADJ[j]);
15882                    item.subitems = oomProcs[j];
15883                    oomMems.add(item);
15884                }
15885            }
15886
15887            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15888            if (!brief && !oomOnly && !isCompact) {
15889                pw.println();
15890                pw.println("Total PSS by process:");
15891                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15892                pw.println();
15893            }
15894            if (!isCompact) {
15895                pw.println("Total PSS by OOM adjustment:");
15896            }
15897            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15898            if (!brief && !oomOnly) {
15899                PrintWriter out = categoryPw != null ? categoryPw : pw;
15900                if (!isCompact) {
15901                    out.println();
15902                    out.println("Total PSS by category:");
15903                }
15904                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15905            }
15906            if (!isCompact) {
15907                pw.println();
15908            }
15909            MemInfoReader memInfo = new MemInfoReader();
15910            memInfo.readMemInfo();
15911            if (nativeProcTotalPss > 0) {
15912                synchronized (this) {
15913                    final long cachedKb = memInfo.getCachedSizeKb();
15914                    final long freeKb = memInfo.getFreeSizeKb();
15915                    final long zramKb = memInfo.getZramTotalSizeKb();
15916                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15917                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15918                            kernelKb*1024, nativeProcTotalPss*1024);
15919                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15920                            nativeProcTotalPss);
15921                }
15922            }
15923            if (!brief) {
15924                if (!isCompact) {
15925                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15926                    pw.print(" (status ");
15927                    switch (mLastMemoryLevel) {
15928                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15929                            pw.println("normal)");
15930                            break;
15931                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15932                            pw.println("moderate)");
15933                            break;
15934                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15935                            pw.println("low)");
15936                            break;
15937                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15938                            pw.println("critical)");
15939                            break;
15940                        default:
15941                            pw.print(mLastMemoryLevel);
15942                            pw.println(")");
15943                            break;
15944                    }
15945                    pw.print(" Free RAM: ");
15946                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15947                            + memInfo.getFreeSizeKb()));
15948                    pw.print(" (");
15949                    pw.print(stringifyKBSize(cachedPss));
15950                    pw.print(" cached pss + ");
15951                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15952                    pw.print(" cached kernel + ");
15953                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15954                    pw.println(" free)");
15955                } else {
15956                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15957                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15958                            + memInfo.getFreeSizeKb()); pw.print(",");
15959                    pw.println(totalPss - cachedPss);
15960                }
15961            }
15962            long lostRAM = memInfo.getTotalSizeKb()
15963                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15964                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15965            if (!isCompact) {
15966                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15967                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15968                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15969                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15970                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15971            } else {
15972                pw.print("lostram,"); pw.println(lostRAM);
15973            }
15974            if (!brief) {
15975                if (memInfo.getZramTotalSizeKb() != 0) {
15976                    if (!isCompact) {
15977                        pw.print("     ZRAM: ");
15978                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15979                                pw.print(" physical used for ");
15980                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15981                                        - memInfo.getSwapFreeSizeKb()));
15982                                pw.print(" in swap (");
15983                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15984                                pw.println(" total swap)");
15985                    } else {
15986                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15987                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15988                                pw.println(memInfo.getSwapFreeSizeKb());
15989                    }
15990                }
15991                final long[] ksm = getKsmInfo();
15992                if (!isCompact) {
15993                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15994                            || ksm[KSM_VOLATILE] != 0) {
15995                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15996                                pw.print(" saved from shared ");
15997                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15998                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15999                                pw.print(" unshared; ");
16000                                pw.print(stringifyKBSize(
16001                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16002                    }
16003                    pw.print("   Tuning: ");
16004                    pw.print(ActivityManager.staticGetMemoryClass());
16005                    pw.print(" (large ");
16006                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16007                    pw.print("), oom ");
16008                    pw.print(stringifySize(
16009                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16010                    pw.print(", restore limit ");
16011                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16012                    if (ActivityManager.isLowRamDeviceStatic()) {
16013                        pw.print(" (low-ram)");
16014                    }
16015                    if (ActivityManager.isHighEndGfx()) {
16016                        pw.print(" (high-end-gfx)");
16017                    }
16018                    pw.println();
16019                } else {
16020                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16021                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16022                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16023                    pw.print("tuning,");
16024                    pw.print(ActivityManager.staticGetMemoryClass());
16025                    pw.print(',');
16026                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16027                    pw.print(',');
16028                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16029                    if (ActivityManager.isLowRamDeviceStatic()) {
16030                        pw.print(",low-ram");
16031                    }
16032                    if (ActivityManager.isHighEndGfx()) {
16033                        pw.print(",high-end-gfx");
16034                    }
16035                    pw.println();
16036                }
16037            }
16038        }
16039    }
16040
16041    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16042            long memtrack, String name) {
16043        sb.append("  ");
16044        sb.append(ProcessList.makeOomAdjString(oomAdj));
16045        sb.append(' ');
16046        sb.append(ProcessList.makeProcStateString(procState));
16047        sb.append(' ');
16048        ProcessList.appendRamKb(sb, pss);
16049        sb.append(": ");
16050        sb.append(name);
16051        if (memtrack > 0) {
16052            sb.append(" (");
16053            sb.append(stringifyKBSize(memtrack));
16054            sb.append(" memtrack)");
16055        }
16056    }
16057
16058    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16059        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16060        sb.append(" (pid ");
16061        sb.append(mi.pid);
16062        sb.append(") ");
16063        sb.append(mi.adjType);
16064        sb.append('\n');
16065        if (mi.adjReason != null) {
16066            sb.append("                      ");
16067            sb.append(mi.adjReason);
16068            sb.append('\n');
16069        }
16070    }
16071
16072    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16073        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16074        for (int i=0, N=memInfos.size(); i<N; i++) {
16075            ProcessMemInfo mi = memInfos.get(i);
16076            infoMap.put(mi.pid, mi);
16077        }
16078        updateCpuStatsNow();
16079        long[] memtrackTmp = new long[1];
16080        synchronized (mProcessCpuTracker) {
16081            final int N = mProcessCpuTracker.countStats();
16082            for (int i=0; i<N; i++) {
16083                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16084                if (st.vsize > 0) {
16085                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16086                    if (pss > 0) {
16087                        if (infoMap.indexOfKey(st.pid) < 0) {
16088                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16089                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16090                            mi.pss = pss;
16091                            mi.memtrack = memtrackTmp[0];
16092                            memInfos.add(mi);
16093                        }
16094                    }
16095                }
16096            }
16097        }
16098
16099        long totalPss = 0;
16100        long totalMemtrack = 0;
16101        for (int i=0, N=memInfos.size(); i<N; i++) {
16102            ProcessMemInfo mi = memInfos.get(i);
16103            if (mi.pss == 0) {
16104                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16105                mi.memtrack = memtrackTmp[0];
16106            }
16107            totalPss += mi.pss;
16108            totalMemtrack += mi.memtrack;
16109        }
16110        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16111            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16112                if (lhs.oomAdj != rhs.oomAdj) {
16113                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16114                }
16115                if (lhs.pss != rhs.pss) {
16116                    return lhs.pss < rhs.pss ? 1 : -1;
16117                }
16118                return 0;
16119            }
16120        });
16121
16122        StringBuilder tag = new StringBuilder(128);
16123        StringBuilder stack = new StringBuilder(128);
16124        tag.append("Low on memory -- ");
16125        appendMemBucket(tag, totalPss, "total", false);
16126        appendMemBucket(stack, totalPss, "total", true);
16127
16128        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16129        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16130        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16131
16132        boolean firstLine = true;
16133        int lastOomAdj = Integer.MIN_VALUE;
16134        long extraNativeRam = 0;
16135        long extraNativeMemtrack = 0;
16136        long cachedPss = 0;
16137        for (int i=0, N=memInfos.size(); i<N; i++) {
16138            ProcessMemInfo mi = memInfos.get(i);
16139
16140            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16141                cachedPss += mi.pss;
16142            }
16143
16144            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16145                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16146                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16147                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16148                if (lastOomAdj != mi.oomAdj) {
16149                    lastOomAdj = mi.oomAdj;
16150                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16151                        tag.append(" / ");
16152                    }
16153                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16154                        if (firstLine) {
16155                            stack.append(":");
16156                            firstLine = false;
16157                        }
16158                        stack.append("\n\t at ");
16159                    } else {
16160                        stack.append("$");
16161                    }
16162                } else {
16163                    tag.append(" ");
16164                    stack.append("$");
16165                }
16166                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16167                    appendMemBucket(tag, mi.pss, mi.name, false);
16168                }
16169                appendMemBucket(stack, mi.pss, mi.name, true);
16170                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16171                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16172                    stack.append("(");
16173                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16174                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16175                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16176                            stack.append(":");
16177                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16178                        }
16179                    }
16180                    stack.append(")");
16181                }
16182            }
16183
16184            appendMemInfo(fullNativeBuilder, mi);
16185            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16186                // The short form only has native processes that are >= 512K.
16187                if (mi.pss >= 512) {
16188                    appendMemInfo(shortNativeBuilder, mi);
16189                } else {
16190                    extraNativeRam += mi.pss;
16191                    extraNativeMemtrack += mi.memtrack;
16192                }
16193            } else {
16194                // Short form has all other details, but if we have collected RAM
16195                // from smaller native processes let's dump a summary of that.
16196                if (extraNativeRam > 0) {
16197                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16198                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16199                    shortNativeBuilder.append('\n');
16200                    extraNativeRam = 0;
16201                }
16202                appendMemInfo(fullJavaBuilder, mi);
16203            }
16204        }
16205
16206        fullJavaBuilder.append("           ");
16207        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16208        fullJavaBuilder.append(": TOTAL");
16209        if (totalMemtrack > 0) {
16210            fullJavaBuilder.append(" (");
16211            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16212            fullJavaBuilder.append(" memtrack)");
16213        } else {
16214        }
16215        fullJavaBuilder.append("\n");
16216
16217        MemInfoReader memInfo = new MemInfoReader();
16218        memInfo.readMemInfo();
16219        final long[] infos = memInfo.getRawInfo();
16220
16221        StringBuilder memInfoBuilder = new StringBuilder(1024);
16222        Debug.getMemInfo(infos);
16223        memInfoBuilder.append("  MemInfo: ");
16224        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16225        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16226        memInfoBuilder.append(stringifyKBSize(
16227                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16228        memInfoBuilder.append(stringifyKBSize(
16229                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16230        memInfoBuilder.append(stringifyKBSize(
16231                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16232        memInfoBuilder.append("           ");
16233        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16234        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16235        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16236        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16237        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16238            memInfoBuilder.append("  ZRAM: ");
16239            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16240            memInfoBuilder.append(" RAM, ");
16241            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16242            memInfoBuilder.append(" swap total, ");
16243            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16244            memInfoBuilder.append(" swap free\n");
16245        }
16246        final long[] ksm = getKsmInfo();
16247        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16248                || ksm[KSM_VOLATILE] != 0) {
16249            memInfoBuilder.append("  KSM: ");
16250            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16251            memInfoBuilder.append(" saved from shared ");
16252            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16253            memInfoBuilder.append("\n       ");
16254            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16255            memInfoBuilder.append(" unshared; ");
16256            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16257            memInfoBuilder.append(" volatile\n");
16258        }
16259        memInfoBuilder.append("  Free RAM: ");
16260        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16261                + memInfo.getFreeSizeKb()));
16262        memInfoBuilder.append("\n");
16263        memInfoBuilder.append("  Used RAM: ");
16264        memInfoBuilder.append(stringifyKBSize(
16265                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16266        memInfoBuilder.append("\n");
16267        memInfoBuilder.append("  Lost RAM: ");
16268        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16269                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16270                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16271        memInfoBuilder.append("\n");
16272        Slog.i(TAG, "Low on memory:");
16273        Slog.i(TAG, shortNativeBuilder.toString());
16274        Slog.i(TAG, fullJavaBuilder.toString());
16275        Slog.i(TAG, memInfoBuilder.toString());
16276
16277        StringBuilder dropBuilder = new StringBuilder(1024);
16278        /*
16279        StringWriter oomSw = new StringWriter();
16280        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16281        StringWriter catSw = new StringWriter();
16282        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16283        String[] emptyArgs = new String[] { };
16284        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16285        oomPw.flush();
16286        String oomString = oomSw.toString();
16287        */
16288        dropBuilder.append("Low on memory:");
16289        dropBuilder.append(stack);
16290        dropBuilder.append('\n');
16291        dropBuilder.append(fullNativeBuilder);
16292        dropBuilder.append(fullJavaBuilder);
16293        dropBuilder.append('\n');
16294        dropBuilder.append(memInfoBuilder);
16295        dropBuilder.append('\n');
16296        /*
16297        dropBuilder.append(oomString);
16298        dropBuilder.append('\n');
16299        */
16300        StringWriter catSw = new StringWriter();
16301        synchronized (ActivityManagerService.this) {
16302            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16303            String[] emptyArgs = new String[] { };
16304            catPw.println();
16305            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16306            catPw.println();
16307            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16308                    false, false, null);
16309            catPw.println();
16310            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16311            catPw.flush();
16312        }
16313        dropBuilder.append(catSw.toString());
16314        addErrorToDropBox("lowmem", null, "system_server", null,
16315                null, tag.toString(), dropBuilder.toString(), null, null);
16316        //Slog.i(TAG, "Sent to dropbox:");
16317        //Slog.i(TAG, dropBuilder.toString());
16318        synchronized (ActivityManagerService.this) {
16319            long now = SystemClock.uptimeMillis();
16320            if (mLastMemUsageReportTime < now) {
16321                mLastMemUsageReportTime = now;
16322            }
16323        }
16324    }
16325
16326    /**
16327     * Searches array of arguments for the specified string
16328     * @param args array of argument strings
16329     * @param value value to search for
16330     * @return true if the value is contained in the array
16331     */
16332    private static boolean scanArgs(String[] args, String value) {
16333        if (args != null) {
16334            for (String arg : args) {
16335                if (value.equals(arg)) {
16336                    return true;
16337                }
16338            }
16339        }
16340        return false;
16341    }
16342
16343    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16344            ContentProviderRecord cpr, boolean always) {
16345        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16346
16347        if (!inLaunching || always) {
16348            synchronized (cpr) {
16349                cpr.launchingApp = null;
16350                cpr.notifyAll();
16351            }
16352            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16353            String names[] = cpr.info.authority.split(";");
16354            for (int j = 0; j < names.length; j++) {
16355                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16356            }
16357        }
16358
16359        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16360            ContentProviderConnection conn = cpr.connections.get(i);
16361            if (conn.waiting) {
16362                // If this connection is waiting for the provider, then we don't
16363                // need to mess with its process unless we are always removing
16364                // or for some reason the provider is not currently launching.
16365                if (inLaunching && !always) {
16366                    continue;
16367                }
16368            }
16369            ProcessRecord capp = conn.client;
16370            conn.dead = true;
16371            if (conn.stableCount > 0) {
16372                if (!capp.persistent && capp.thread != null
16373                        && capp.pid != 0
16374                        && capp.pid != MY_PID) {
16375                    capp.kill("depends on provider "
16376                            + cpr.name.flattenToShortString()
16377                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16378                }
16379            } else if (capp.thread != null && conn.provider.provider != null) {
16380                try {
16381                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16382                } catch (RemoteException e) {
16383                }
16384                // In the protocol here, we don't expect the client to correctly
16385                // clean up this connection, we'll just remove it.
16386                cpr.connections.remove(i);
16387                if (conn.client.conProviders.remove(conn)) {
16388                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16389                }
16390            }
16391        }
16392
16393        if (inLaunching && always) {
16394            mLaunchingProviders.remove(cpr);
16395        }
16396        return inLaunching;
16397    }
16398
16399    /**
16400     * Main code for cleaning up a process when it has gone away.  This is
16401     * called both as a result of the process dying, or directly when stopping
16402     * a process when running in single process mode.
16403     *
16404     * @return Returns true if the given process has been restarted, so the
16405     * app that was passed in must remain on the process lists.
16406     */
16407    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16408            boolean restarting, boolean allowRestart, int index) {
16409        if (index >= 0) {
16410            removeLruProcessLocked(app);
16411            ProcessList.remove(app.pid);
16412        }
16413
16414        mProcessesToGc.remove(app);
16415        mPendingPssProcesses.remove(app);
16416
16417        // Dismiss any open dialogs.
16418        if (app.crashDialog != null && !app.forceCrashReport) {
16419            app.crashDialog.dismiss();
16420            app.crashDialog = null;
16421        }
16422        if (app.anrDialog != null) {
16423            app.anrDialog.dismiss();
16424            app.anrDialog = null;
16425        }
16426        if (app.waitDialog != null) {
16427            app.waitDialog.dismiss();
16428            app.waitDialog = null;
16429        }
16430
16431        app.crashing = false;
16432        app.notResponding = false;
16433
16434        app.resetPackageList(mProcessStats);
16435        app.unlinkDeathRecipient();
16436        app.makeInactive(mProcessStats);
16437        app.waitingToKill = null;
16438        app.forcingToForeground = null;
16439        updateProcessForegroundLocked(app, false, false);
16440        app.foregroundActivities = false;
16441        app.hasShownUi = false;
16442        app.treatLikeActivity = false;
16443        app.hasAboveClient = false;
16444        app.hasClientActivities = false;
16445
16446        mServices.killServicesLocked(app, allowRestart);
16447
16448        boolean restart = false;
16449
16450        // Remove published content providers.
16451        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16452            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16453            final boolean always = app.bad || !allowRestart;
16454            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16455            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16456                // We left the provider in the launching list, need to
16457                // restart it.
16458                restart = true;
16459            }
16460
16461            cpr.provider = null;
16462            cpr.proc = null;
16463        }
16464        app.pubProviders.clear();
16465
16466        // Take care of any launching providers waiting for this process.
16467        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16468            restart = true;
16469        }
16470
16471        // Unregister from connected content providers.
16472        if (!app.conProviders.isEmpty()) {
16473            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16474                ContentProviderConnection conn = app.conProviders.get(i);
16475                conn.provider.connections.remove(conn);
16476                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16477                        conn.provider.name);
16478            }
16479            app.conProviders.clear();
16480        }
16481
16482        // At this point there may be remaining entries in mLaunchingProviders
16483        // where we were the only one waiting, so they are no longer of use.
16484        // Look for these and clean up if found.
16485        // XXX Commented out for now.  Trying to figure out a way to reproduce
16486        // the actual situation to identify what is actually going on.
16487        if (false) {
16488            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16489                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16490                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16491                    synchronized (cpr) {
16492                        cpr.launchingApp = null;
16493                        cpr.notifyAll();
16494                    }
16495                }
16496            }
16497        }
16498
16499        skipCurrentReceiverLocked(app);
16500
16501        // Unregister any receivers.
16502        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16503            removeReceiverLocked(app.receivers.valueAt(i));
16504        }
16505        app.receivers.clear();
16506
16507        // If the app is undergoing backup, tell the backup manager about it
16508        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16509            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16510                    + mBackupTarget.appInfo + " died during backup");
16511            try {
16512                IBackupManager bm = IBackupManager.Stub.asInterface(
16513                        ServiceManager.getService(Context.BACKUP_SERVICE));
16514                bm.agentDisconnected(app.info.packageName);
16515            } catch (RemoteException e) {
16516                // can't happen; backup manager is local
16517            }
16518        }
16519
16520        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16521            ProcessChangeItem item = mPendingProcessChanges.get(i);
16522            if (item.pid == app.pid) {
16523                mPendingProcessChanges.remove(i);
16524                mAvailProcessChanges.add(item);
16525            }
16526        }
16527        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16528                null).sendToTarget();
16529
16530        // If the caller is restarting this app, then leave it in its
16531        // current lists and let the caller take care of it.
16532        if (restarting) {
16533            return false;
16534        }
16535
16536        if (!app.persistent || app.isolated) {
16537            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16538                    "Removing non-persistent process during cleanup: " + app);
16539            removeProcessNameLocked(app.processName, app.uid);
16540            if (mHeavyWeightProcess == app) {
16541                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16542                        mHeavyWeightProcess.userId, 0));
16543                mHeavyWeightProcess = null;
16544            }
16545        } else if (!app.removed) {
16546            // This app is persistent, so we need to keep its record around.
16547            // If it is not already on the pending app list, add it there
16548            // and start a new process for it.
16549            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16550                mPersistentStartingProcesses.add(app);
16551                restart = true;
16552            }
16553        }
16554        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16555                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16556        mProcessesOnHold.remove(app);
16557
16558        if (app == mHomeProcess) {
16559            mHomeProcess = null;
16560        }
16561        if (app == mPreviousProcess) {
16562            mPreviousProcess = null;
16563        }
16564
16565        if (restart && !app.isolated) {
16566            // We have components that still need to be running in the
16567            // process, so re-launch it.
16568            if (index < 0) {
16569                ProcessList.remove(app.pid);
16570            }
16571            addProcessNameLocked(app);
16572            startProcessLocked(app, "restart", app.processName);
16573            return true;
16574        } else if (app.pid > 0 && app.pid != MY_PID) {
16575            // Goodbye!
16576            boolean removed;
16577            synchronized (mPidsSelfLocked) {
16578                mPidsSelfLocked.remove(app.pid);
16579                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16580            }
16581            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16582            if (app.isolated) {
16583                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16584            }
16585            app.setPid(0);
16586        }
16587        return false;
16588    }
16589
16590    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16591        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16592            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16593            if (cpr.launchingApp == app) {
16594                return true;
16595            }
16596        }
16597        return false;
16598    }
16599
16600    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16601        // Look through the content providers we are waiting to have launched,
16602        // and if any run in this process then either schedule a restart of
16603        // the process or kill the client waiting for it if this process has
16604        // gone bad.
16605        boolean restart = false;
16606        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16607            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16608            if (cpr.launchingApp == app) {
16609                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16610                    restart = true;
16611                } else {
16612                    removeDyingProviderLocked(app, cpr, true);
16613                }
16614            }
16615        }
16616        return restart;
16617    }
16618
16619    // =========================================================
16620    // SERVICES
16621    // =========================================================
16622
16623    @Override
16624    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16625            int flags) {
16626        enforceNotIsolatedCaller("getServices");
16627        synchronized (this) {
16628            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16629        }
16630    }
16631
16632    @Override
16633    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16634        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16635        synchronized (this) {
16636            return mServices.getRunningServiceControlPanelLocked(name);
16637        }
16638    }
16639
16640    @Override
16641    public ComponentName startService(IApplicationThread caller, Intent service,
16642            String resolvedType, String callingPackage, int userId)
16643            throws TransactionTooLargeException {
16644        enforceNotIsolatedCaller("startService");
16645        // Refuse possible leaked file descriptors
16646        if (service != null && service.hasFileDescriptors() == true) {
16647            throw new IllegalArgumentException("File descriptors passed in Intent");
16648        }
16649
16650        if (callingPackage == null) {
16651            throw new IllegalArgumentException("callingPackage cannot be null");
16652        }
16653
16654        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16655                "startService: " + service + " type=" + resolvedType);
16656        synchronized(this) {
16657            final int callingPid = Binder.getCallingPid();
16658            final int callingUid = Binder.getCallingUid();
16659            final long origId = Binder.clearCallingIdentity();
16660            ComponentName res = mServices.startServiceLocked(caller, service,
16661                    resolvedType, callingPid, callingUid, callingPackage, userId);
16662            Binder.restoreCallingIdentity(origId);
16663            return res;
16664        }
16665    }
16666
16667    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16668            String callingPackage, int userId)
16669            throws TransactionTooLargeException {
16670        synchronized(this) {
16671            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16672                    "startServiceInPackage: " + service + " type=" + resolvedType);
16673            final long origId = Binder.clearCallingIdentity();
16674            ComponentName res = mServices.startServiceLocked(null, service,
16675                    resolvedType, -1, uid, callingPackage, userId);
16676            Binder.restoreCallingIdentity(origId);
16677            return res;
16678        }
16679    }
16680
16681    @Override
16682    public int stopService(IApplicationThread caller, Intent service,
16683            String resolvedType, int userId) {
16684        enforceNotIsolatedCaller("stopService");
16685        // Refuse possible leaked file descriptors
16686        if (service != null && service.hasFileDescriptors() == true) {
16687            throw new IllegalArgumentException("File descriptors passed in Intent");
16688        }
16689
16690        synchronized(this) {
16691            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16692        }
16693    }
16694
16695    @Override
16696    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16697        enforceNotIsolatedCaller("peekService");
16698        // Refuse possible leaked file descriptors
16699        if (service != null && service.hasFileDescriptors() == true) {
16700            throw new IllegalArgumentException("File descriptors passed in Intent");
16701        }
16702
16703        if (callingPackage == null) {
16704            throw new IllegalArgumentException("callingPackage cannot be null");
16705        }
16706
16707        synchronized(this) {
16708            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16709        }
16710    }
16711
16712    @Override
16713    public boolean stopServiceToken(ComponentName className, IBinder token,
16714            int startId) {
16715        synchronized(this) {
16716            return mServices.stopServiceTokenLocked(className, token, startId);
16717        }
16718    }
16719
16720    @Override
16721    public void setServiceForeground(ComponentName className, IBinder token,
16722            int id, Notification notification, boolean removeNotification) {
16723        synchronized(this) {
16724            mServices.setServiceForegroundLocked(className, token, id, notification,
16725                    removeNotification);
16726        }
16727    }
16728
16729    @Override
16730    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16731            boolean requireFull, String name, String callerPackage) {
16732        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16733                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16734    }
16735
16736    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16737            String className, int flags) {
16738        boolean result = false;
16739        // For apps that don't have pre-defined UIDs, check for permission
16740        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16741            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16742                if (ActivityManager.checkUidPermission(
16743                        INTERACT_ACROSS_USERS,
16744                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16745                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16746                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16747                            + " requests FLAG_SINGLE_USER, but app does not hold "
16748                            + INTERACT_ACROSS_USERS;
16749                    Slog.w(TAG, msg);
16750                    throw new SecurityException(msg);
16751                }
16752                // Permission passed
16753                result = true;
16754            }
16755        } else if ("system".equals(componentProcessName)) {
16756            result = true;
16757        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16758            // Phone app and persistent apps are allowed to export singleuser providers.
16759            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16760                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16761        }
16762        if (DEBUG_MU) Slog.v(TAG_MU,
16763                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16764                + Integer.toHexString(flags) + ") = " + result);
16765        return result;
16766    }
16767
16768    /**
16769     * Checks to see if the caller is in the same app as the singleton
16770     * component, or the component is in a special app. It allows special apps
16771     * to export singleton components but prevents exporting singleton
16772     * components for regular apps.
16773     */
16774    boolean isValidSingletonCall(int callingUid, int componentUid) {
16775        int componentAppId = UserHandle.getAppId(componentUid);
16776        return UserHandle.isSameApp(callingUid, componentUid)
16777                || componentAppId == Process.SYSTEM_UID
16778                || componentAppId == Process.PHONE_UID
16779                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16780                        == PackageManager.PERMISSION_GRANTED;
16781    }
16782
16783    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16784            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16785            int userId) throws TransactionTooLargeException {
16786        enforceNotIsolatedCaller("bindService");
16787
16788        // Refuse possible leaked file descriptors
16789        if (service != null && service.hasFileDescriptors() == true) {
16790            throw new IllegalArgumentException("File descriptors passed in Intent");
16791        }
16792
16793        if (callingPackage == null) {
16794            throw new IllegalArgumentException("callingPackage cannot be null");
16795        }
16796
16797        synchronized(this) {
16798            return mServices.bindServiceLocked(caller, token, service,
16799                    resolvedType, connection, flags, callingPackage, userId);
16800        }
16801    }
16802
16803    public boolean unbindService(IServiceConnection connection) {
16804        synchronized (this) {
16805            return mServices.unbindServiceLocked(connection);
16806        }
16807    }
16808
16809    public void publishService(IBinder token, Intent intent, IBinder service) {
16810        // Refuse possible leaked file descriptors
16811        if (intent != null && intent.hasFileDescriptors() == true) {
16812            throw new IllegalArgumentException("File descriptors passed in Intent");
16813        }
16814
16815        synchronized(this) {
16816            if (!(token instanceof ServiceRecord)) {
16817                throw new IllegalArgumentException("Invalid service token");
16818            }
16819            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16820        }
16821    }
16822
16823    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16824        // Refuse possible leaked file descriptors
16825        if (intent != null && intent.hasFileDescriptors() == true) {
16826            throw new IllegalArgumentException("File descriptors passed in Intent");
16827        }
16828
16829        synchronized(this) {
16830            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16831        }
16832    }
16833
16834    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16835        synchronized(this) {
16836            if (!(token instanceof ServiceRecord)) {
16837                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16838                throw new IllegalArgumentException("Invalid service token");
16839            }
16840            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16841        }
16842    }
16843
16844    // =========================================================
16845    // BACKUP AND RESTORE
16846    // =========================================================
16847
16848    // Cause the target app to be launched if necessary and its backup agent
16849    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16850    // activity manager to announce its creation.
16851    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16852        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16853                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16854        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16855
16856        synchronized(this) {
16857            // !!! TODO: currently no check here that we're already bound
16858            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16859            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16860            synchronized (stats) {
16861                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16862            }
16863
16864            // Backup agent is now in use, its package can't be stopped.
16865            try {
16866                AppGlobals.getPackageManager().setPackageStoppedState(
16867                        app.packageName, false, UserHandle.getUserId(app.uid));
16868            } catch (RemoteException e) {
16869            } catch (IllegalArgumentException e) {
16870                Slog.w(TAG, "Failed trying to unstop package "
16871                        + app.packageName + ": " + e);
16872            }
16873
16874            BackupRecord r = new BackupRecord(ss, app, backupMode);
16875            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16876                    ? new ComponentName(app.packageName, app.backupAgentName)
16877                    : new ComponentName("android", "FullBackupAgent");
16878            // startProcessLocked() returns existing proc's record if it's already running
16879            ProcessRecord proc = startProcessLocked(app.processName, app,
16880                    false, 0, "backup", hostingName, false, false, false);
16881            if (proc == null) {
16882                Slog.e(TAG, "Unable to start backup agent process " + r);
16883                return false;
16884            }
16885
16886            r.app = proc;
16887            mBackupTarget = r;
16888            mBackupAppName = app.packageName;
16889
16890            // Try not to kill the process during backup
16891            updateOomAdjLocked(proc);
16892
16893            // If the process is already attached, schedule the creation of the backup agent now.
16894            // If it is not yet live, this will be done when it attaches to the framework.
16895            if (proc.thread != null) {
16896                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16897                try {
16898                    proc.thread.scheduleCreateBackupAgent(app,
16899                            compatibilityInfoForPackageLocked(app), backupMode);
16900                } catch (RemoteException e) {
16901                    // Will time out on the backup manager side
16902                }
16903            } else {
16904                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16905            }
16906            // Invariants: at this point, the target app process exists and the application
16907            // is either already running or in the process of coming up.  mBackupTarget and
16908            // mBackupAppName describe the app, so that when it binds back to the AM we
16909            // know that it's scheduled for a backup-agent operation.
16910        }
16911
16912        return true;
16913    }
16914
16915    @Override
16916    public void clearPendingBackup() {
16917        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16918        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16919
16920        synchronized (this) {
16921            mBackupTarget = null;
16922            mBackupAppName = null;
16923        }
16924    }
16925
16926    // A backup agent has just come up
16927    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16928        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16929                + " = " + agent);
16930
16931        synchronized(this) {
16932            if (!agentPackageName.equals(mBackupAppName)) {
16933                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16934                return;
16935            }
16936        }
16937
16938        long oldIdent = Binder.clearCallingIdentity();
16939        try {
16940            IBackupManager bm = IBackupManager.Stub.asInterface(
16941                    ServiceManager.getService(Context.BACKUP_SERVICE));
16942            bm.agentConnected(agentPackageName, agent);
16943        } catch (RemoteException e) {
16944            // can't happen; the backup manager service is local
16945        } catch (Exception e) {
16946            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16947            e.printStackTrace();
16948        } finally {
16949            Binder.restoreCallingIdentity(oldIdent);
16950        }
16951    }
16952
16953    // done with this agent
16954    public void unbindBackupAgent(ApplicationInfo appInfo) {
16955        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16956        if (appInfo == null) {
16957            Slog.w(TAG, "unbind backup agent for null app");
16958            return;
16959        }
16960
16961        synchronized(this) {
16962            try {
16963                if (mBackupAppName == null) {
16964                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16965                    return;
16966                }
16967
16968                if (!mBackupAppName.equals(appInfo.packageName)) {
16969                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16970                    return;
16971                }
16972
16973                // Not backing this app up any more; reset its OOM adjustment
16974                final ProcessRecord proc = mBackupTarget.app;
16975                updateOomAdjLocked(proc);
16976
16977                // If the app crashed during backup, 'thread' will be null here
16978                if (proc.thread != null) {
16979                    try {
16980                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16981                                compatibilityInfoForPackageLocked(appInfo));
16982                    } catch (Exception e) {
16983                        Slog.e(TAG, "Exception when unbinding backup agent:");
16984                        e.printStackTrace();
16985                    }
16986                }
16987            } finally {
16988                mBackupTarget = null;
16989                mBackupAppName = null;
16990            }
16991        }
16992    }
16993    // =========================================================
16994    // BROADCASTS
16995    // =========================================================
16996
16997    boolean isPendingBroadcastProcessLocked(int pid) {
16998        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16999                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17000    }
17001
17002    void skipPendingBroadcastLocked(int pid) {
17003            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17004            for (BroadcastQueue queue : mBroadcastQueues) {
17005                queue.skipPendingBroadcastLocked(pid);
17006            }
17007    }
17008
17009    // The app just attached; send any pending broadcasts that it should receive
17010    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17011        boolean didSomething = false;
17012        for (BroadcastQueue queue : mBroadcastQueues) {
17013            didSomething |= queue.sendPendingBroadcastsLocked(app);
17014        }
17015        return didSomething;
17016    }
17017
17018    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17019            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17020        enforceNotIsolatedCaller("registerReceiver");
17021        ArrayList<Intent> stickyIntents = null;
17022        ProcessRecord callerApp = null;
17023        int callingUid;
17024        int callingPid;
17025        synchronized(this) {
17026            if (caller != null) {
17027                callerApp = getRecordForAppLocked(caller);
17028                if (callerApp == null) {
17029                    throw new SecurityException(
17030                            "Unable to find app for caller " + caller
17031                            + " (pid=" + Binder.getCallingPid()
17032                            + ") when registering receiver " + receiver);
17033                }
17034                if (callerApp.info.uid != Process.SYSTEM_UID &&
17035                        !callerApp.pkgList.containsKey(callerPackage) &&
17036                        !"android".equals(callerPackage)) {
17037                    throw new SecurityException("Given caller package " + callerPackage
17038                            + " is not running in process " + callerApp);
17039                }
17040                callingUid = callerApp.info.uid;
17041                callingPid = callerApp.pid;
17042            } else {
17043                callerPackage = null;
17044                callingUid = Binder.getCallingUid();
17045                callingPid = Binder.getCallingPid();
17046            }
17047
17048            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17049                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17050
17051            Iterator<String> actions = filter.actionsIterator();
17052            if (actions == null) {
17053                ArrayList<String> noAction = new ArrayList<String>(1);
17054                noAction.add(null);
17055                actions = noAction.iterator();
17056            }
17057
17058            // Collect stickies of users
17059            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17060            while (actions.hasNext()) {
17061                String action = actions.next();
17062                for (int id : userIds) {
17063                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17064                    if (stickies != null) {
17065                        ArrayList<Intent> intents = stickies.get(action);
17066                        if (intents != null) {
17067                            if (stickyIntents == null) {
17068                                stickyIntents = new ArrayList<Intent>();
17069                            }
17070                            stickyIntents.addAll(intents);
17071                        }
17072                    }
17073                }
17074            }
17075        }
17076
17077        ArrayList<Intent> allSticky = null;
17078        if (stickyIntents != null) {
17079            final ContentResolver resolver = mContext.getContentResolver();
17080            // Look for any matching sticky broadcasts...
17081            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17082                Intent intent = stickyIntents.get(i);
17083                // If intent has scheme "content", it will need to acccess
17084                // provider that needs to lock mProviderMap in ActivityThread
17085                // and also it may need to wait application response, so we
17086                // cannot lock ActivityManagerService here.
17087                if (filter.match(resolver, intent, true, TAG) >= 0) {
17088                    if (allSticky == null) {
17089                        allSticky = new ArrayList<Intent>();
17090                    }
17091                    allSticky.add(intent);
17092                }
17093            }
17094        }
17095
17096        // The first sticky in the list is returned directly back to the client.
17097        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17098        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17099        if (receiver == null) {
17100            return sticky;
17101        }
17102
17103        synchronized (this) {
17104            if (callerApp != null && (callerApp.thread == null
17105                    || callerApp.thread.asBinder() != caller.asBinder())) {
17106                // Original caller already died
17107                return null;
17108            }
17109            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17110            if (rl == null) {
17111                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17112                        userId, receiver);
17113                if (rl.app != null) {
17114                    rl.app.receivers.add(rl);
17115                } else {
17116                    try {
17117                        receiver.asBinder().linkToDeath(rl, 0);
17118                    } catch (RemoteException e) {
17119                        return sticky;
17120                    }
17121                    rl.linkedToDeath = true;
17122                }
17123                mRegisteredReceivers.put(receiver.asBinder(), rl);
17124            } else if (rl.uid != callingUid) {
17125                throw new IllegalArgumentException(
17126                        "Receiver requested to register for uid " + callingUid
17127                        + " was previously registered for uid " + rl.uid);
17128            } else if (rl.pid != callingPid) {
17129                throw new IllegalArgumentException(
17130                        "Receiver requested to register for pid " + callingPid
17131                        + " was previously registered for pid " + rl.pid);
17132            } else if (rl.userId != userId) {
17133                throw new IllegalArgumentException(
17134                        "Receiver requested to register for user " + userId
17135                        + " was previously registered for user " + rl.userId);
17136            }
17137            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17138                    permission, callingUid, userId);
17139            rl.add(bf);
17140            if (!bf.debugCheck()) {
17141                Slog.w(TAG, "==> For Dynamic broadcast");
17142            }
17143            mReceiverResolver.addFilter(bf);
17144
17145            // Enqueue broadcasts for all existing stickies that match
17146            // this filter.
17147            if (allSticky != null) {
17148                ArrayList receivers = new ArrayList();
17149                receivers.add(bf);
17150
17151                final int stickyCount = allSticky.size();
17152                for (int i = 0; i < stickyCount; i++) {
17153                    Intent intent = allSticky.get(i);
17154                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17155                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17156                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17157                            null, 0, null, null, false, true, true, -1);
17158                    queue.enqueueParallelBroadcastLocked(r);
17159                    queue.scheduleBroadcastsLocked();
17160                }
17161            }
17162
17163            return sticky;
17164        }
17165    }
17166
17167    public void unregisterReceiver(IIntentReceiver receiver) {
17168        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17169
17170        final long origId = Binder.clearCallingIdentity();
17171        try {
17172            boolean doTrim = false;
17173
17174            synchronized(this) {
17175                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17176                if (rl != null) {
17177                    final BroadcastRecord r = rl.curBroadcast;
17178                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17179                        final boolean doNext = r.queue.finishReceiverLocked(
17180                                r, r.resultCode, r.resultData, r.resultExtras,
17181                                r.resultAbort, false);
17182                        if (doNext) {
17183                            doTrim = true;
17184                            r.queue.processNextBroadcast(false);
17185                        }
17186                    }
17187
17188                    if (rl.app != null) {
17189                        rl.app.receivers.remove(rl);
17190                    }
17191                    removeReceiverLocked(rl);
17192                    if (rl.linkedToDeath) {
17193                        rl.linkedToDeath = false;
17194                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17195                    }
17196                }
17197            }
17198
17199            // If we actually concluded any broadcasts, we might now be able
17200            // to trim the recipients' apps from our working set
17201            if (doTrim) {
17202                trimApplications();
17203                return;
17204            }
17205
17206        } finally {
17207            Binder.restoreCallingIdentity(origId);
17208        }
17209    }
17210
17211    void removeReceiverLocked(ReceiverList rl) {
17212        mRegisteredReceivers.remove(rl.receiver.asBinder());
17213        for (int i = rl.size() - 1; i >= 0; i--) {
17214            mReceiverResolver.removeFilter(rl.get(i));
17215        }
17216    }
17217
17218    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17219        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17220            ProcessRecord r = mLruProcesses.get(i);
17221            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17222                try {
17223                    r.thread.dispatchPackageBroadcast(cmd, packages);
17224                } catch (RemoteException ex) {
17225                }
17226            }
17227        }
17228    }
17229
17230    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17231            int callingUid, int[] users) {
17232        // TODO: come back and remove this assumption to triage all broadcasts
17233        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17234
17235        List<ResolveInfo> receivers = null;
17236        try {
17237            HashSet<ComponentName> singleUserReceivers = null;
17238            boolean scannedFirstReceivers = false;
17239            for (int user : users) {
17240                // Skip users that have Shell restrictions
17241                if (callingUid == Process.SHELL_UID
17242                        && mUserController.hasUserRestriction(
17243                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
17244                    continue;
17245                }
17246                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17247                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
17248                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17249                    // If this is not the system user, we need to check for
17250                    // any receivers that should be filtered out.
17251                    for (int i=0; i<newReceivers.size(); i++) {
17252                        ResolveInfo ri = newReceivers.get(i);
17253                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17254                            newReceivers.remove(i);
17255                            i--;
17256                        }
17257                    }
17258                }
17259                if (newReceivers != null && newReceivers.size() == 0) {
17260                    newReceivers = null;
17261                }
17262                if (receivers == null) {
17263                    receivers = newReceivers;
17264                } else if (newReceivers != null) {
17265                    // We need to concatenate the additional receivers
17266                    // found with what we have do far.  This would be easy,
17267                    // but we also need to de-dup any receivers that are
17268                    // singleUser.
17269                    if (!scannedFirstReceivers) {
17270                        // Collect any single user receivers we had already retrieved.
17271                        scannedFirstReceivers = true;
17272                        for (int i=0; i<receivers.size(); i++) {
17273                            ResolveInfo ri = receivers.get(i);
17274                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17275                                ComponentName cn = new ComponentName(
17276                                        ri.activityInfo.packageName, ri.activityInfo.name);
17277                                if (singleUserReceivers == null) {
17278                                    singleUserReceivers = new HashSet<ComponentName>();
17279                                }
17280                                singleUserReceivers.add(cn);
17281                            }
17282                        }
17283                    }
17284                    // Add the new results to the existing results, tracking
17285                    // and de-dupping single user receivers.
17286                    for (int i=0; i<newReceivers.size(); i++) {
17287                        ResolveInfo ri = newReceivers.get(i);
17288                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17289                            ComponentName cn = new ComponentName(
17290                                    ri.activityInfo.packageName, ri.activityInfo.name);
17291                            if (singleUserReceivers == null) {
17292                                singleUserReceivers = new HashSet<ComponentName>();
17293                            }
17294                            if (!singleUserReceivers.contains(cn)) {
17295                                singleUserReceivers.add(cn);
17296                                receivers.add(ri);
17297                            }
17298                        } else {
17299                            receivers.add(ri);
17300                        }
17301                    }
17302                }
17303            }
17304        } catch (RemoteException ex) {
17305            // pm is in same process, this will never happen.
17306        }
17307        return receivers;
17308    }
17309
17310    final int broadcastIntentLocked(ProcessRecord callerApp,
17311            String callerPackage, Intent intent, String resolvedType,
17312            IIntentReceiver resultTo, int resultCode, String resultData,
17313            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17314            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17315        intent = new Intent(intent);
17316
17317        // By default broadcasts do not go to stopped apps.
17318        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17319
17320        // If we have not finished booting, don't allow this to launch new processes.
17321        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17322            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17323        }
17324
17325        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17326                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17327                + " ordered=" + ordered + " userid=" + userId);
17328        if ((resultTo != null) && !ordered) {
17329            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17330        }
17331
17332        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17333                ALLOW_NON_FULL, "broadcast", callerPackage);
17334
17335        // Make sure that the user who is receiving this broadcast is running.
17336        // If not, we will just skip it. Make an exception for shutdown broadcasts
17337        // and upgrade steps.
17338
17339        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17340            if ((callingUid != Process.SYSTEM_UID
17341                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17342                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17343                Slog.w(TAG, "Skipping broadcast of " + intent
17344                        + ": user " + userId + " is stopped");
17345                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17346            }
17347        }
17348
17349        BroadcastOptions brOptions = null;
17350        if (bOptions != null) {
17351            brOptions = new BroadcastOptions(bOptions);
17352            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17353                // See if the caller is allowed to do this.  Note we are checking against
17354                // the actual real caller (not whoever provided the operation as say a
17355                // PendingIntent), because that who is actually supplied the arguments.
17356                if (checkComponentPermission(
17357                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17358                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17359                        != PackageManager.PERMISSION_GRANTED) {
17360                    String msg = "Permission Denial: " + intent.getAction()
17361                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17362                            + ", uid=" + callingUid + ")"
17363                            + " requires "
17364                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17365                    Slog.w(TAG, msg);
17366                    throw new SecurityException(msg);
17367                }
17368            }
17369        }
17370
17371        // Verify that protected broadcasts are only being sent by system code,
17372        // and that system code is only sending protected broadcasts.
17373        final String action = intent.getAction();
17374        final boolean isProtectedBroadcast;
17375        try {
17376            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17377        } catch (RemoteException e) {
17378            Slog.w(TAG, "Remote exception", e);
17379            return ActivityManager.BROADCAST_SUCCESS;
17380        }
17381
17382        final boolean isCallerSystem;
17383        switch (UserHandle.getAppId(callingUid)) {
17384            case Process.ROOT_UID:
17385            case Process.SYSTEM_UID:
17386            case Process.PHONE_UID:
17387            case Process.SHELL_UID:
17388            case Process.BLUETOOTH_UID:
17389            case Process.NFC_UID:
17390                isCallerSystem = true;
17391                break;
17392            default:
17393                isCallerSystem = (callerApp != null) && callerApp.persistent;
17394                break;
17395        }
17396
17397        if (isCallerSystem) {
17398            if (isProtectedBroadcast
17399                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17400                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17401                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17402                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17403                // Broadcast is either protected, or it's a public action that
17404                // we've relaxed, so it's fine for system internals to send.
17405            } else {
17406                // The vast majority of broadcasts sent from system internals
17407                // should be protected to avoid security holes, so yell loudly
17408                // to ensure we examine these cases.
17409                Log.wtf(TAG, "Sending non-protected broadcast " + action
17410                        + " from system", new Throwable());
17411            }
17412
17413        } else {
17414            if (isProtectedBroadcast) {
17415                String msg = "Permission Denial: not allowed to send broadcast "
17416                        + action + " from pid="
17417                        + callingPid + ", uid=" + callingUid;
17418                Slog.w(TAG, msg);
17419                throw new SecurityException(msg);
17420
17421            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17422                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17423                // Special case for compatibility: we don't want apps to send this,
17424                // but historically it has not been protected and apps may be using it
17425                // to poke their own app widget.  So, instead of making it protected,
17426                // just limit it to the caller.
17427                if (callerApp == null) {
17428                    String msg = "Permission Denial: not allowed to send broadcast "
17429                            + action + " from unknown caller.";
17430                    Slog.w(TAG, msg);
17431                    throw new SecurityException(msg);
17432                } else if (intent.getComponent() != null) {
17433                    // They are good enough to send to an explicit component...  verify
17434                    // it is being sent to the calling app.
17435                    if (!intent.getComponent().getPackageName().equals(
17436                            callerApp.info.packageName)) {
17437                        String msg = "Permission Denial: not allowed to send broadcast "
17438                                + action + " to "
17439                                + intent.getComponent().getPackageName() + " from "
17440                                + callerApp.info.packageName;
17441                        Slog.w(TAG, msg);
17442                        throw new SecurityException(msg);
17443                    }
17444                } else {
17445                    // Limit broadcast to their own package.
17446                    intent.setPackage(callerApp.info.packageName);
17447                }
17448            }
17449        }
17450
17451        if (action != null) {
17452            switch (action) {
17453                case Intent.ACTION_UID_REMOVED:
17454                case Intent.ACTION_PACKAGE_REMOVED:
17455                case Intent.ACTION_PACKAGE_CHANGED:
17456                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17457                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17458                    // Handle special intents: if this broadcast is from the package
17459                    // manager about a package being removed, we need to remove all of
17460                    // its activities from the history stack.
17461                    if (checkComponentPermission(
17462                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17463                            callingPid, callingUid, -1, true)
17464                            != PackageManager.PERMISSION_GRANTED) {
17465                        String msg = "Permission Denial: " + intent.getAction()
17466                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17467                                + ", uid=" + callingUid + ")"
17468                                + " requires "
17469                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17470                        Slog.w(TAG, msg);
17471                        throw new SecurityException(msg);
17472                    }
17473                    switch (action) {
17474                        case Intent.ACTION_UID_REMOVED:
17475                            final Bundle intentExtras = intent.getExtras();
17476                            final int uid = intentExtras != null
17477                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17478                            if (uid >= 0) {
17479                                mBatteryStatsService.removeUid(uid);
17480                                mAppOpsService.uidRemoved(uid);
17481                            }
17482                            break;
17483                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17484                            // If resources are unavailable just force stop all those packages
17485                            // and flush the attribute cache as well.
17486                            String list[] =
17487                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17488                            if (list != null && list.length > 0) {
17489                                for (int i = 0; i < list.length; i++) {
17490                                    forceStopPackageLocked(list[i], -1, false, true, true,
17491                                            false, false, userId, "storage unmount");
17492                                }
17493                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17494                                sendPackageBroadcastLocked(
17495                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17496                                        userId);
17497                            }
17498                            break;
17499                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17500                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17501                            break;
17502                        case Intent.ACTION_PACKAGE_REMOVED:
17503                        case Intent.ACTION_PACKAGE_CHANGED:
17504                            Uri data = intent.getData();
17505                            String ssp;
17506                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17507                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17508                                boolean fullUninstall = removed &&
17509                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17510                                final boolean killProcess =
17511                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17512                                if (killProcess) {
17513                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17514                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17515                                            false, true, true, false, fullUninstall, userId,
17516                                            removed ? "pkg removed" : "pkg changed");
17517                                }
17518                                if (removed) {
17519                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17520                                            new String[] {ssp}, userId);
17521                                    if (fullUninstall) {
17522                                        mAppOpsService.packageRemoved(
17523                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17524
17525                                        // Remove all permissions granted from/to this package
17526                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17527
17528                                        removeTasksByPackageNameLocked(ssp, userId);
17529                                        mBatteryStatsService.notePackageUninstalled(ssp);
17530                                    }
17531                                } else {
17532                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17533                                            intent.getStringArrayExtra(
17534                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17535                                }
17536                            }
17537                            break;
17538                    }
17539                    break;
17540                case Intent.ACTION_PACKAGE_ADDED:
17541                    // Special case for adding a package: by default turn on compatibility mode.
17542                    Uri data = intent.getData();
17543                    String ssp;
17544                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17545                        final boolean replacing =
17546                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17547                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17548
17549                        try {
17550                            ApplicationInfo ai = AppGlobals.getPackageManager().
17551                                    getApplicationInfo(ssp, 0, 0);
17552                            mBatteryStatsService.notePackageInstalled(ssp,
17553                                    ai != null ? ai.versionCode : 0);
17554                        } catch (RemoteException e) {
17555                        }
17556                    }
17557                    break;
17558                case Intent.ACTION_TIMEZONE_CHANGED:
17559                    // If this is the time zone changed action, queue up a message that will reset
17560                    // the timezone of all currently running processes. This message will get
17561                    // queued up before the broadcast happens.
17562                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17563                    break;
17564                case Intent.ACTION_TIME_CHANGED:
17565                    // If the user set the time, let all running processes know.
17566                    final int is24Hour =
17567                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17568                                    : 0;
17569                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17570                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17571                    synchronized (stats) {
17572                        stats.noteCurrentTimeChangedLocked();
17573                    }
17574                    break;
17575                case Intent.ACTION_CLEAR_DNS_CACHE:
17576                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17577                    break;
17578                case Proxy.PROXY_CHANGE_ACTION:
17579                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17580                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17581                    break;
17582            }
17583        }
17584
17585        // Add to the sticky list if requested.
17586        if (sticky) {
17587            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17588                    callingPid, callingUid)
17589                    != PackageManager.PERMISSION_GRANTED) {
17590                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17591                        + callingPid + ", uid=" + callingUid
17592                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17593                Slog.w(TAG, msg);
17594                throw new SecurityException(msg);
17595            }
17596            if (requiredPermissions != null && requiredPermissions.length > 0) {
17597                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17598                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17599                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17600            }
17601            if (intent.getComponent() != null) {
17602                throw new SecurityException(
17603                        "Sticky broadcasts can't target a specific component");
17604            }
17605            // We use userId directly here, since the "all" target is maintained
17606            // as a separate set of sticky broadcasts.
17607            if (userId != UserHandle.USER_ALL) {
17608                // But first, if this is not a broadcast to all users, then
17609                // make sure it doesn't conflict with an existing broadcast to
17610                // all users.
17611                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17612                        UserHandle.USER_ALL);
17613                if (stickies != null) {
17614                    ArrayList<Intent> list = stickies.get(intent.getAction());
17615                    if (list != null) {
17616                        int N = list.size();
17617                        int i;
17618                        for (i=0; i<N; i++) {
17619                            if (intent.filterEquals(list.get(i))) {
17620                                throw new IllegalArgumentException(
17621                                        "Sticky broadcast " + intent + " for user "
17622                                        + userId + " conflicts with existing global broadcast");
17623                            }
17624                        }
17625                    }
17626                }
17627            }
17628            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17629            if (stickies == null) {
17630                stickies = new ArrayMap<>();
17631                mStickyBroadcasts.put(userId, stickies);
17632            }
17633            ArrayList<Intent> list = stickies.get(intent.getAction());
17634            if (list == null) {
17635                list = new ArrayList<>();
17636                stickies.put(intent.getAction(), list);
17637            }
17638            final int stickiesCount = list.size();
17639            int i;
17640            for (i = 0; i < stickiesCount; i++) {
17641                if (intent.filterEquals(list.get(i))) {
17642                    // This sticky already exists, replace it.
17643                    list.set(i, new Intent(intent));
17644                    break;
17645                }
17646            }
17647            if (i >= stickiesCount) {
17648                list.add(new Intent(intent));
17649            }
17650        }
17651
17652        int[] users;
17653        if (userId == UserHandle.USER_ALL) {
17654            // Caller wants broadcast to go to all started users.
17655            users = mUserController.getStartedUserArrayLocked();
17656        } else {
17657            // Caller wants broadcast to go to one specific user.
17658            users = new int[] {userId};
17659        }
17660
17661        // Figure out who all will receive this broadcast.
17662        List receivers = null;
17663        List<BroadcastFilter> registeredReceivers = null;
17664        // Need to resolve the intent to interested receivers...
17665        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17666                 == 0) {
17667            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17668        }
17669        if (intent.getComponent() == null) {
17670            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17671                // Query one target user at a time, excluding shell-restricted users
17672                for (int i = 0; i < users.length; i++) {
17673                    if (mUserController.hasUserRestriction(
17674                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17675                        continue;
17676                    }
17677                    List<BroadcastFilter> registeredReceiversForUser =
17678                            mReceiverResolver.queryIntent(intent,
17679                                    resolvedType, false, users[i]);
17680                    if (registeredReceivers == null) {
17681                        registeredReceivers = registeredReceiversForUser;
17682                    } else if (registeredReceiversForUser != null) {
17683                        registeredReceivers.addAll(registeredReceiversForUser);
17684                    }
17685                }
17686            } else {
17687                registeredReceivers = mReceiverResolver.queryIntent(intent,
17688                        resolvedType, false, userId);
17689            }
17690        }
17691
17692        final boolean replacePending =
17693                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17694
17695        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17696                + " replacePending=" + replacePending);
17697
17698        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17699        if (!ordered && NR > 0) {
17700            // If we are not serializing this broadcast, then send the
17701            // registered receivers separately so they don't wait for the
17702            // components to be launched.
17703            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17704            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17705                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17706                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17707                    resultExtras, ordered, sticky, false, userId);
17708            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17709            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17710            if (!replaced) {
17711                queue.enqueueParallelBroadcastLocked(r);
17712                queue.scheduleBroadcastsLocked();
17713            }
17714            registeredReceivers = null;
17715            NR = 0;
17716        }
17717
17718        // Merge into one list.
17719        int ir = 0;
17720        if (receivers != null) {
17721            // A special case for PACKAGE_ADDED: do not allow the package
17722            // being added to see this broadcast.  This prevents them from
17723            // using this as a back door to get run as soon as they are
17724            // installed.  Maybe in the future we want to have a special install
17725            // broadcast or such for apps, but we'd like to deliberately make
17726            // this decision.
17727            String skipPackages[] = null;
17728            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17729                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17730                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17731                Uri data = intent.getData();
17732                if (data != null) {
17733                    String pkgName = data.getSchemeSpecificPart();
17734                    if (pkgName != null) {
17735                        skipPackages = new String[] { pkgName };
17736                    }
17737                }
17738            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17739                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17740            }
17741            if (skipPackages != null && (skipPackages.length > 0)) {
17742                for (String skipPackage : skipPackages) {
17743                    if (skipPackage != null) {
17744                        int NT = receivers.size();
17745                        for (int it=0; it<NT; it++) {
17746                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17747                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17748                                receivers.remove(it);
17749                                it--;
17750                                NT--;
17751                            }
17752                        }
17753                    }
17754                }
17755            }
17756
17757            int NT = receivers != null ? receivers.size() : 0;
17758            int it = 0;
17759            ResolveInfo curt = null;
17760            BroadcastFilter curr = null;
17761            while (it < NT && ir < NR) {
17762                if (curt == null) {
17763                    curt = (ResolveInfo)receivers.get(it);
17764                }
17765                if (curr == null) {
17766                    curr = registeredReceivers.get(ir);
17767                }
17768                if (curr.getPriority() >= curt.priority) {
17769                    // Insert this broadcast record into the final list.
17770                    receivers.add(it, curr);
17771                    ir++;
17772                    curr = null;
17773                    it++;
17774                    NT++;
17775                } else {
17776                    // Skip to the next ResolveInfo in the final list.
17777                    it++;
17778                    curt = null;
17779                }
17780            }
17781        }
17782        while (ir < NR) {
17783            if (receivers == null) {
17784                receivers = new ArrayList();
17785            }
17786            receivers.add(registeredReceivers.get(ir));
17787            ir++;
17788        }
17789
17790        if ((receivers != null && receivers.size() > 0)
17791                || resultTo != null) {
17792            BroadcastQueue queue = broadcastQueueForIntent(intent);
17793            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17794                    callerPackage, callingPid, callingUid, resolvedType,
17795                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17796                    resultData, resultExtras, ordered, sticky, false, userId);
17797
17798            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17799                    + ": prev had " + queue.mOrderedBroadcasts.size());
17800            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17801                    "Enqueueing broadcast " + r.intent.getAction());
17802
17803            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17804            if (!replaced) {
17805                queue.enqueueOrderedBroadcastLocked(r);
17806                queue.scheduleBroadcastsLocked();
17807            }
17808        }
17809
17810        return ActivityManager.BROADCAST_SUCCESS;
17811    }
17812
17813    final Intent verifyBroadcastLocked(Intent intent) {
17814        // Refuse possible leaked file descriptors
17815        if (intent != null && intent.hasFileDescriptors() == true) {
17816            throw new IllegalArgumentException("File descriptors passed in Intent");
17817        }
17818
17819        int flags = intent.getFlags();
17820
17821        if (!mProcessesReady) {
17822            // if the caller really truly claims to know what they're doing, go
17823            // ahead and allow the broadcast without launching any receivers
17824            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17825                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17826            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17827                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17828                        + " before boot completion");
17829                throw new IllegalStateException("Cannot broadcast before boot completed");
17830            }
17831        }
17832
17833        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17834            throw new IllegalArgumentException(
17835                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17836        }
17837
17838        return intent;
17839    }
17840
17841    public final int broadcastIntent(IApplicationThread caller,
17842            Intent intent, String resolvedType, IIntentReceiver resultTo,
17843            int resultCode, String resultData, Bundle resultExtras,
17844            String[] requiredPermissions, int appOp, Bundle bOptions,
17845            boolean serialized, boolean sticky, int userId) {
17846        enforceNotIsolatedCaller("broadcastIntent");
17847        synchronized(this) {
17848            intent = verifyBroadcastLocked(intent);
17849
17850            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17851            final int callingPid = Binder.getCallingPid();
17852            final int callingUid = Binder.getCallingUid();
17853            final long origId = Binder.clearCallingIdentity();
17854            int res = broadcastIntentLocked(callerApp,
17855                    callerApp != null ? callerApp.info.packageName : null,
17856                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17857                    requiredPermissions, appOp, null, serialized, sticky,
17858                    callingPid, callingUid, userId);
17859            Binder.restoreCallingIdentity(origId);
17860            return res;
17861        }
17862    }
17863
17864
17865    int broadcastIntentInPackage(String packageName, int uid,
17866            Intent intent, String resolvedType, IIntentReceiver resultTo,
17867            int resultCode, String resultData, Bundle resultExtras,
17868            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17869            int userId) {
17870        synchronized(this) {
17871            intent = verifyBroadcastLocked(intent);
17872
17873            final long origId = Binder.clearCallingIdentity();
17874            String[] requiredPermissions = requiredPermission == null ? null
17875                    : new String[] {requiredPermission};
17876            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17877                    resultTo, resultCode, resultData, resultExtras,
17878                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17879                    sticky, -1, uid, userId);
17880            Binder.restoreCallingIdentity(origId);
17881            return res;
17882        }
17883    }
17884
17885    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17886        // Refuse possible leaked file descriptors
17887        if (intent != null && intent.hasFileDescriptors() == true) {
17888            throw new IllegalArgumentException("File descriptors passed in Intent");
17889        }
17890
17891        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17892                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17893
17894        synchronized(this) {
17895            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17896                    != PackageManager.PERMISSION_GRANTED) {
17897                String msg = "Permission Denial: unbroadcastIntent() from pid="
17898                        + Binder.getCallingPid()
17899                        + ", uid=" + Binder.getCallingUid()
17900                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17901                Slog.w(TAG, msg);
17902                throw new SecurityException(msg);
17903            }
17904            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17905            if (stickies != null) {
17906                ArrayList<Intent> list = stickies.get(intent.getAction());
17907                if (list != null) {
17908                    int N = list.size();
17909                    int i;
17910                    for (i=0; i<N; i++) {
17911                        if (intent.filterEquals(list.get(i))) {
17912                            list.remove(i);
17913                            break;
17914                        }
17915                    }
17916                    if (list.size() <= 0) {
17917                        stickies.remove(intent.getAction());
17918                    }
17919                }
17920                if (stickies.size() <= 0) {
17921                    mStickyBroadcasts.remove(userId);
17922                }
17923            }
17924        }
17925    }
17926
17927    void backgroundServicesFinishedLocked(int userId) {
17928        for (BroadcastQueue queue : mBroadcastQueues) {
17929            queue.backgroundServicesFinishedLocked(userId);
17930        }
17931    }
17932
17933    public void finishReceiver(IBinder who, int resultCode, String resultData,
17934            Bundle resultExtras, boolean resultAbort, int flags) {
17935        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17936
17937        // Refuse possible leaked file descriptors
17938        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17939            throw new IllegalArgumentException("File descriptors passed in Bundle");
17940        }
17941
17942        final long origId = Binder.clearCallingIdentity();
17943        try {
17944            boolean doNext = false;
17945            BroadcastRecord r;
17946
17947            synchronized(this) {
17948                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17949                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17950                r = queue.getMatchingOrderedReceiver(who);
17951                if (r != null) {
17952                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17953                        resultData, resultExtras, resultAbort, true);
17954                }
17955            }
17956
17957            if (doNext) {
17958                r.queue.processNextBroadcast(false);
17959            }
17960            trimApplications();
17961        } finally {
17962            Binder.restoreCallingIdentity(origId);
17963        }
17964    }
17965
17966    // =========================================================
17967    // INSTRUMENTATION
17968    // =========================================================
17969
17970    public boolean startInstrumentation(ComponentName className,
17971            String profileFile, int flags, Bundle arguments,
17972            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17973            int userId, String abiOverride) {
17974        enforceNotIsolatedCaller("startInstrumentation");
17975        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17976                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17977        // Refuse possible leaked file descriptors
17978        if (arguments != null && arguments.hasFileDescriptors()) {
17979            throw new IllegalArgumentException("File descriptors passed in Bundle");
17980        }
17981
17982        synchronized(this) {
17983            InstrumentationInfo ii = null;
17984            ApplicationInfo ai = null;
17985            try {
17986                ii = mContext.getPackageManager().getInstrumentationInfo(
17987                    className, STOCK_PM_FLAGS);
17988                ai = AppGlobals.getPackageManager().getApplicationInfo(
17989                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17990            } catch (PackageManager.NameNotFoundException e) {
17991            } catch (RemoteException e) {
17992            }
17993            if (ii == null) {
17994                reportStartInstrumentationFailure(watcher, className,
17995                        "Unable to find instrumentation info for: " + className);
17996                return false;
17997            }
17998            if (ai == null) {
17999                reportStartInstrumentationFailure(watcher, className,
18000                        "Unable to find instrumentation target package: " + ii.targetPackage);
18001                return false;
18002            }
18003            if (!ai.hasCode()) {
18004                reportStartInstrumentationFailure(watcher, className,
18005                        "Instrumentation target has no code: " + ii.targetPackage);
18006                return false;
18007            }
18008
18009            int match = mContext.getPackageManager().checkSignatures(
18010                    ii.targetPackage, ii.packageName);
18011            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18012                String msg = "Permission Denial: starting instrumentation "
18013                        + className + " from pid="
18014                        + Binder.getCallingPid()
18015                        + ", uid=" + Binder.getCallingPid()
18016                        + " not allowed because package " + ii.packageName
18017                        + " does not have a signature matching the target "
18018                        + ii.targetPackage;
18019                reportStartInstrumentationFailure(watcher, className, msg);
18020                throw new SecurityException(msg);
18021            }
18022
18023            final long origId = Binder.clearCallingIdentity();
18024            // Instrumentation can kill and relaunch even persistent processes
18025            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18026                    "start instr");
18027            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18028            app.instrumentationClass = className;
18029            app.instrumentationInfo = ai;
18030            app.instrumentationProfileFile = profileFile;
18031            app.instrumentationArguments = arguments;
18032            app.instrumentationWatcher = watcher;
18033            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18034            app.instrumentationResultClass = className;
18035            Binder.restoreCallingIdentity(origId);
18036        }
18037
18038        return true;
18039    }
18040
18041    /**
18042     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18043     * error to the logs, but if somebody is watching, send the report there too.  This enables
18044     * the "am" command to report errors with more information.
18045     *
18046     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18047     * @param cn The component name of the instrumentation.
18048     * @param report The error report.
18049     */
18050    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
18051            ComponentName cn, String report) {
18052        Slog.w(TAG, report);
18053        try {
18054            if (watcher != null) {
18055                Bundle results = new Bundle();
18056                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18057                results.putString("Error", report);
18058                watcher.instrumentationStatus(cn, -1, results);
18059            }
18060        } catch (RemoteException e) {
18061            Slog.w(TAG, e);
18062        }
18063    }
18064
18065    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18066        if (app.instrumentationWatcher != null) {
18067            try {
18068                // NOTE:  IInstrumentationWatcher *must* be oneway here
18069                app.instrumentationWatcher.instrumentationFinished(
18070                    app.instrumentationClass,
18071                    resultCode,
18072                    results);
18073            } catch (RemoteException e) {
18074            }
18075        }
18076
18077        // Can't call out of the system process with a lock held, so post a message.
18078        if (app.instrumentationUiAutomationConnection != null) {
18079            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18080                    app.instrumentationUiAutomationConnection).sendToTarget();
18081        }
18082
18083        app.instrumentationWatcher = null;
18084        app.instrumentationUiAutomationConnection = null;
18085        app.instrumentationClass = null;
18086        app.instrumentationInfo = null;
18087        app.instrumentationProfileFile = null;
18088        app.instrumentationArguments = null;
18089
18090        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18091                "finished inst");
18092    }
18093
18094    public void finishInstrumentation(IApplicationThread target,
18095            int resultCode, Bundle results) {
18096        int userId = UserHandle.getCallingUserId();
18097        // Refuse possible leaked file descriptors
18098        if (results != null && results.hasFileDescriptors()) {
18099            throw new IllegalArgumentException("File descriptors passed in Intent");
18100        }
18101
18102        synchronized(this) {
18103            ProcessRecord app = getRecordForAppLocked(target);
18104            if (app == null) {
18105                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18106                return;
18107            }
18108            final long origId = Binder.clearCallingIdentity();
18109            finishInstrumentationLocked(app, resultCode, results);
18110            Binder.restoreCallingIdentity(origId);
18111        }
18112    }
18113
18114    // =========================================================
18115    // CONFIGURATION
18116    // =========================================================
18117
18118    public ConfigurationInfo getDeviceConfigurationInfo() {
18119        ConfigurationInfo config = new ConfigurationInfo();
18120        synchronized (this) {
18121            config.reqTouchScreen = mConfiguration.touchscreen;
18122            config.reqKeyboardType = mConfiguration.keyboard;
18123            config.reqNavigation = mConfiguration.navigation;
18124            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18125                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18126                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18127            }
18128            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18129                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18130                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18131            }
18132            config.reqGlEsVersion = GL_ES_VERSION;
18133        }
18134        return config;
18135    }
18136
18137    ActivityStack getFocusedStack() {
18138        return mStackSupervisor.getFocusedStack();
18139    }
18140
18141    @Override
18142    public int getFocusedStackId() throws RemoteException {
18143        ActivityStack focusedStack = getFocusedStack();
18144        if (focusedStack != null) {
18145            return focusedStack.getStackId();
18146        }
18147        return -1;
18148    }
18149
18150    public Configuration getConfiguration() {
18151        Configuration ci;
18152        synchronized(this) {
18153            ci = new Configuration(mConfiguration);
18154            ci.userSetLocale = false;
18155        }
18156        return ci;
18157    }
18158
18159    @Override
18160    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18162        synchronized (this) {
18163            mSuppressResizeConfigChanges = suppress;
18164        }
18165    }
18166
18167    @Override
18168    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18169        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18170        if (fromStackId == HOME_STACK_ID) {
18171            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18172        }
18173        synchronized (this) {
18174            final long origId = Binder.clearCallingIdentity();
18175            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
18176            if (stack != null) {
18177                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
18178                final int size = tasks.size();
18179                if (onTop) {
18180                    for (int i = 0; i < size; i++) {
18181                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18182                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
18183                                "moveTasksToFullscreenStack", ANIMATE);
18184                    }
18185                } else {
18186                    for (int i = size - 1; i >= 0; i--) {
18187                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18188                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
18189                    }
18190                }
18191            }
18192            Binder.restoreCallingIdentity(origId);
18193        }
18194    }
18195
18196    @Override
18197    public void updatePersistentConfiguration(Configuration values) {
18198        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18199                "updateConfiguration()");
18200        enforceWriteSettingsPermission("updateConfiguration()");
18201        if (values == null) {
18202            throw new NullPointerException("Configuration must not be null");
18203        }
18204
18205        int userId = UserHandle.getCallingUserId();
18206
18207        synchronized(this) {
18208            final long origId = Binder.clearCallingIdentity();
18209            updateConfigurationLocked(values, null, false, true, userId);
18210            Binder.restoreCallingIdentity(origId);
18211        }
18212    }
18213
18214    private void enforceWriteSettingsPermission(String func) {
18215        int uid = Binder.getCallingUid();
18216        if (uid == Process.ROOT_UID) {
18217            return;
18218        }
18219
18220        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18221                Settings.getPackageNameForUid(mContext, uid), false)) {
18222            return;
18223        }
18224
18225        String msg = "Permission Denial: " + func + " from pid="
18226                + Binder.getCallingPid()
18227                + ", uid=" + uid
18228                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18229        Slog.w(TAG, msg);
18230        throw new SecurityException(msg);
18231    }
18232
18233    public void updateConfiguration(Configuration values) {
18234        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18235                "updateConfiguration()");
18236
18237        synchronized(this) {
18238            if (values == null && mWindowManager != null) {
18239                // sentinel: fetch the current configuration from the window manager
18240                values = mWindowManager.computeNewConfiguration();
18241            }
18242
18243            if (mWindowManager != null) {
18244                mProcessList.applyDisplaySize(mWindowManager);
18245            }
18246
18247            final long origId = Binder.clearCallingIdentity();
18248            if (values != null) {
18249                Settings.System.clearConfiguration(values);
18250            }
18251            updateConfigurationLocked(values, null, false);
18252            Binder.restoreCallingIdentity(origId);
18253        }
18254    }
18255
18256    void updateUserConfigurationLocked() {
18257        Configuration configuration = new Configuration(mConfiguration);
18258        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18259                mUserController.getCurrentUserIdLocked());
18260        updateConfigurationLocked(configuration, null, false);
18261    }
18262
18263    boolean updateConfigurationLocked(Configuration values,
18264            ActivityRecord starting, boolean initLocale) {
18265        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18266        return updateConfigurationLocked(values, starting, initLocale, false,
18267                UserHandle.USER_NULL);
18268    }
18269
18270    // To cache the list of supported system locales
18271    private String[] mSupportedSystemLocales = null;
18272
18273    /**
18274     * Do either or both things: (1) change the current configuration, and (2)
18275     * make sure the given activity is running with the (now) current
18276     * configuration.  Returns true if the activity has been left running, or
18277     * false if <var>starting</var> is being destroyed to match the new
18278     * configuration.
18279     *
18280     * @param userId is only used when persistent parameter is set to true to persist configuration
18281     *               for that particular user
18282     */
18283    private boolean updateConfigurationLocked(Configuration values,
18284            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18285        int changes = 0;
18286
18287        if (values != null) {
18288            Configuration newConfig = new Configuration(mConfiguration);
18289            changes = newConfig.updateFrom(values);
18290            if (changes != 0) {
18291                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18292                        "Updating configuration to: " + values);
18293
18294                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18295
18296                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18297                    final Locale locale;
18298                    if (values.getLocales().size() == 1) {
18299                        // This is an optimization to avoid the JNI call when the result of
18300                        // getFirstMatch() does not depend on the supported locales.
18301                        locale = values.getLocales().getPrimary();
18302                    } else {
18303                        if (mSupportedSystemLocales == null) {
18304                            mSupportedSystemLocales =
18305                                    Resources.getSystem().getAssets().getLocales();
18306                        }
18307                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18308                    }
18309                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18310                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18311                            locale));
18312                }
18313
18314                mConfigurationSeq++;
18315                if (mConfigurationSeq <= 0) {
18316                    mConfigurationSeq = 1;
18317                }
18318                newConfig.seq = mConfigurationSeq;
18319                mConfiguration = newConfig;
18320                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18321                mUsageStatsService.reportConfigurationChange(newConfig,
18322                        mUserController.getCurrentUserIdLocked());
18323                //mUsageStatsService.noteStartConfig(newConfig);
18324
18325                final Configuration configCopy = new Configuration(mConfiguration);
18326
18327                // TODO: If our config changes, should we auto dismiss any currently
18328                // showing dialogs?
18329                mShowDialogs = shouldShowDialogs(newConfig);
18330
18331                AttributeCache ac = AttributeCache.instance();
18332                if (ac != null) {
18333                    ac.updateConfiguration(configCopy);
18334                }
18335
18336                // Make sure all resources in our process are updated
18337                // right now, so that anyone who is going to retrieve
18338                // resource values after we return will be sure to get
18339                // the new ones.  This is especially important during
18340                // boot, where the first config change needs to guarantee
18341                // all resources have that config before following boot
18342                // code is executed.
18343                mSystemThread.applyConfigurationToResources(configCopy);
18344
18345                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18346                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18347                    msg.obj = new Configuration(configCopy);
18348                    msg.arg1 = userId;
18349                    mHandler.sendMessage(msg);
18350                }
18351
18352                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18353                    ProcessRecord app = mLruProcesses.get(i);
18354                    try {
18355                        if (app.thread != null) {
18356                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18357                                    + app.processName + " new config " + mConfiguration);
18358                            app.thread.scheduleConfigurationChanged(configCopy);
18359                        }
18360                    } catch (Exception e) {
18361                    }
18362                }
18363                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18364                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18365                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18366                        | Intent.FLAG_RECEIVER_FOREGROUND);
18367                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18368                        null, AppOpsManager.OP_NONE, null, false, false,
18369                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18370                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18371                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18372                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18373                    if (!mProcessesReady) {
18374                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18375                    }
18376                    broadcastIntentLocked(null, null, intent,
18377                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18378                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18379                }
18380            }
18381        }
18382
18383        boolean kept = true;
18384        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18385        // mainStack is null during startup.
18386        if (mainStack != null) {
18387            if (changes != 0 && starting == null) {
18388                // If the configuration changed, and the caller is not already
18389                // in the process of starting an activity, then find the top
18390                // activity to check if its configuration needs to change.
18391                starting = mainStack.topRunningActivityLocked();
18392            }
18393
18394            if (starting != null) {
18395                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18396                // And we need to make sure at this point that all other activities
18397                // are made visible with the correct configuration.
18398                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18399                        !PRESERVE_WINDOWS);
18400            }
18401        }
18402
18403        if (values != null && mWindowManager != null) {
18404            mWindowManager.setNewConfiguration(mConfiguration);
18405        }
18406
18407        return kept;
18408    }
18409
18410    /**
18411     * Decide based on the configuration whether we should shouw the ANR,
18412     * crash, etc dialogs.  The idea is that if there is no affordnace to
18413     * press the on-screen buttons, we shouldn't show the dialog.
18414     *
18415     * A thought: SystemUI might also want to get told about this, the Power
18416     * dialog / global actions also might want different behaviors.
18417     */
18418    private static final boolean shouldShowDialogs(Configuration config) {
18419        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18420                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18421                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18422        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18423                                    == Configuration.UI_MODE_TYPE_CAR);
18424        return inputMethodExists && uiIsNotCarType;
18425    }
18426
18427    @Override
18428    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18429        synchronized (this) {
18430            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18431            if (srec != null) {
18432                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18433            }
18434        }
18435        return false;
18436    }
18437
18438    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18439            Intent resultData) {
18440
18441        synchronized (this) {
18442            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18443            if (r != null) {
18444                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18445            }
18446            return false;
18447        }
18448    }
18449
18450    public int getLaunchedFromUid(IBinder activityToken) {
18451        ActivityRecord srec;
18452        synchronized (this) {
18453            srec = ActivityRecord.forTokenLocked(activityToken);
18454        }
18455        if (srec == null) {
18456            return -1;
18457        }
18458        return srec.launchedFromUid;
18459    }
18460
18461    public String getLaunchedFromPackage(IBinder activityToken) {
18462        ActivityRecord srec;
18463        synchronized (this) {
18464            srec = ActivityRecord.forTokenLocked(activityToken);
18465        }
18466        if (srec == null) {
18467            return null;
18468        }
18469        return srec.launchedFromPackage;
18470    }
18471
18472    // =========================================================
18473    // LIFETIME MANAGEMENT
18474    // =========================================================
18475
18476    // Returns which broadcast queue the app is the current [or imminent] receiver
18477    // on, or 'null' if the app is not an active broadcast recipient.
18478    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18479        BroadcastRecord r = app.curReceiver;
18480        if (r != null) {
18481            return r.queue;
18482        }
18483
18484        // It's not the current receiver, but it might be starting up to become one
18485        synchronized (this) {
18486            for (BroadcastQueue queue : mBroadcastQueues) {
18487                r = queue.mPendingBroadcast;
18488                if (r != null && r.curApp == app) {
18489                    // found it; report which queue it's in
18490                    return queue;
18491                }
18492            }
18493        }
18494
18495        return null;
18496    }
18497
18498    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18499            ComponentName targetComponent, String targetProcess) {
18500        if (!mTrackingAssociations) {
18501            return null;
18502        }
18503        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18504                = mAssociations.get(targetUid);
18505        if (components == null) {
18506            components = new ArrayMap<>();
18507            mAssociations.put(targetUid, components);
18508        }
18509        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18510        if (sourceUids == null) {
18511            sourceUids = new SparseArray<>();
18512            components.put(targetComponent, sourceUids);
18513        }
18514        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18515        if (sourceProcesses == null) {
18516            sourceProcesses = new ArrayMap<>();
18517            sourceUids.put(sourceUid, sourceProcesses);
18518        }
18519        Association ass = sourceProcesses.get(sourceProcess);
18520        if (ass == null) {
18521            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18522                    targetProcess);
18523            sourceProcesses.put(sourceProcess, ass);
18524        }
18525        ass.mCount++;
18526        ass.mNesting++;
18527        if (ass.mNesting == 1) {
18528            ass.mStartTime = SystemClock.uptimeMillis();
18529        }
18530        return ass;
18531    }
18532
18533    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18534            ComponentName targetComponent) {
18535        if (!mTrackingAssociations) {
18536            return;
18537        }
18538        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18539                = mAssociations.get(targetUid);
18540        if (components == null) {
18541            return;
18542        }
18543        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18544        if (sourceUids == null) {
18545            return;
18546        }
18547        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18548        if (sourceProcesses == null) {
18549            return;
18550        }
18551        Association ass = sourceProcesses.get(sourceProcess);
18552        if (ass == null || ass.mNesting <= 0) {
18553            return;
18554        }
18555        ass.mNesting--;
18556        if (ass.mNesting == 0) {
18557            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18558        }
18559    }
18560
18561    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18562            boolean doingAll, long now) {
18563        if (mAdjSeq == app.adjSeq) {
18564            // This adjustment has already been computed.
18565            return app.curRawAdj;
18566        }
18567
18568        if (app.thread == null) {
18569            app.adjSeq = mAdjSeq;
18570            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18571            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18572            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18573        }
18574
18575        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18576        app.adjSource = null;
18577        app.adjTarget = null;
18578        app.empty = false;
18579        app.cached = false;
18580
18581        final int activitiesSize = app.activities.size();
18582
18583        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18584            // The max adjustment doesn't allow this app to be anything
18585            // below foreground, so it is not worth doing work for it.
18586            app.adjType = "fixed";
18587            app.adjSeq = mAdjSeq;
18588            app.curRawAdj = app.maxAdj;
18589            app.foregroundActivities = false;
18590            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18591            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18592            // System processes can do UI, and when they do we want to have
18593            // them trim their memory after the user leaves the UI.  To
18594            // facilitate this, here we need to determine whether or not it
18595            // is currently showing UI.
18596            app.systemNoUi = true;
18597            if (app == TOP_APP) {
18598                app.systemNoUi = false;
18599            } else if (activitiesSize > 0) {
18600                for (int j = 0; j < activitiesSize; j++) {
18601                    final ActivityRecord r = app.activities.get(j);
18602                    if (r.visible) {
18603                        app.systemNoUi = false;
18604                    }
18605                }
18606            }
18607            if (!app.systemNoUi) {
18608                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18609            }
18610            return (app.curAdj=app.maxAdj);
18611        }
18612
18613        app.systemNoUi = false;
18614
18615        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18616
18617        // Determine the importance of the process, starting with most
18618        // important to least, and assign an appropriate OOM adjustment.
18619        int adj;
18620        int schedGroup;
18621        int procState;
18622        boolean foregroundActivities = false;
18623        BroadcastQueue queue;
18624        if (app == TOP_APP) {
18625            // The last app on the list is the foreground app.
18626            adj = ProcessList.FOREGROUND_APP_ADJ;
18627            schedGroup = Process.THREAD_GROUP_DEFAULT;
18628            app.adjType = "top-activity";
18629            foregroundActivities = true;
18630            procState = PROCESS_STATE_CUR_TOP;
18631        } else if (app.instrumentationClass != null) {
18632            // Don't want to kill running instrumentation.
18633            adj = ProcessList.FOREGROUND_APP_ADJ;
18634            schedGroup = Process.THREAD_GROUP_DEFAULT;
18635            app.adjType = "instrumentation";
18636            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18637        } else if ((queue = isReceivingBroadcast(app)) != null) {
18638            // An app that is currently receiving a broadcast also
18639            // counts as being in the foreground for OOM killer purposes.
18640            // It's placed in a sched group based on the nature of the
18641            // broadcast as reflected by which queue it's active in.
18642            adj = ProcessList.FOREGROUND_APP_ADJ;
18643            schedGroup = (queue == mFgBroadcastQueue)
18644                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18645            app.adjType = "broadcast";
18646            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18647        } else if (app.executingServices.size() > 0) {
18648            // An app that is currently executing a service callback also
18649            // counts as being in the foreground.
18650            adj = ProcessList.FOREGROUND_APP_ADJ;
18651            schedGroup = app.execServicesFg ?
18652                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18653            app.adjType = "exec-service";
18654            procState = ActivityManager.PROCESS_STATE_SERVICE;
18655            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18656        } else {
18657            // As far as we know the process is empty.  We may change our mind later.
18658            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18659            // At this point we don't actually know the adjustment.  Use the cached adj
18660            // value that the caller wants us to.
18661            adj = cachedAdj;
18662            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18663            app.cached = true;
18664            app.empty = true;
18665            app.adjType = "cch-empty";
18666        }
18667
18668        // Examine all activities if not already foreground.
18669        if (!foregroundActivities && activitiesSize > 0) {
18670            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18671            for (int j = 0; j < activitiesSize; j++) {
18672                final ActivityRecord r = app.activities.get(j);
18673                if (r.app != app) {
18674                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18675                            + app + "?!? Using " + r.app + " instead.");
18676                    continue;
18677                }
18678                if (r.visible) {
18679                    // App has a visible activity; only upgrade adjustment.
18680                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18681                        adj = ProcessList.VISIBLE_APP_ADJ;
18682                        app.adjType = "visible";
18683                    }
18684                    if (procState > PROCESS_STATE_CUR_TOP) {
18685                        procState = PROCESS_STATE_CUR_TOP;
18686                    }
18687                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18688                    app.cached = false;
18689                    app.empty = false;
18690                    foregroundActivities = true;
18691                    if (r.task != null && minLayer > 0) {
18692                        final int layer = r.task.mLayerRank;
18693                        if (layer >= 0 && minLayer > layer) {
18694                            minLayer = layer;
18695                        }
18696                    }
18697                    break;
18698                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18699                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18700                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18701                        app.adjType = "pausing";
18702                    }
18703                    if (procState > PROCESS_STATE_CUR_TOP) {
18704                        procState = PROCESS_STATE_CUR_TOP;
18705                    }
18706                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18707                    app.cached = false;
18708                    app.empty = false;
18709                    foregroundActivities = true;
18710                } else if (r.state == ActivityState.STOPPING) {
18711                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18712                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18713                        app.adjType = "stopping";
18714                    }
18715                    // For the process state, we will at this point consider the
18716                    // process to be cached.  It will be cached either as an activity
18717                    // or empty depending on whether the activity is finishing.  We do
18718                    // this so that we can treat the process as cached for purposes of
18719                    // memory trimming (determing current memory level, trim command to
18720                    // send to process) since there can be an arbitrary number of stopping
18721                    // processes and they should soon all go into the cached state.
18722                    if (!r.finishing) {
18723                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18724                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18725                        }
18726                    }
18727                    app.cached = false;
18728                    app.empty = false;
18729                    foregroundActivities = true;
18730                } else {
18731                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18732                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18733                        app.adjType = "cch-act";
18734                    }
18735                }
18736            }
18737            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18738                adj += minLayer;
18739            }
18740        }
18741
18742        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18743                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18744            if (app.foregroundServices) {
18745                // The user is aware of this app, so make it visible.
18746                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18747                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18748                app.cached = false;
18749                app.adjType = "fg-service";
18750                schedGroup = Process.THREAD_GROUP_DEFAULT;
18751            } else if (app.forcingToForeground != null) {
18752                // The user is aware of this app, so make it visible.
18753                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18754                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18755                app.cached = false;
18756                app.adjType = "force-fg";
18757                app.adjSource = app.forcingToForeground;
18758                schedGroup = Process.THREAD_GROUP_DEFAULT;
18759            }
18760        }
18761
18762        if (app == mHeavyWeightProcess) {
18763            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18764                // We don't want to kill the current heavy-weight process.
18765                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18766                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18767                app.cached = false;
18768                app.adjType = "heavy";
18769            }
18770            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18771                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18772            }
18773        }
18774
18775        if (app == mHomeProcess) {
18776            if (adj > ProcessList.HOME_APP_ADJ) {
18777                // This process is hosting what we currently consider to be the
18778                // home app, so we don't want to let it go into the background.
18779                adj = ProcessList.HOME_APP_ADJ;
18780                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18781                app.cached = false;
18782                app.adjType = "home";
18783            }
18784            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18785                procState = ActivityManager.PROCESS_STATE_HOME;
18786            }
18787        }
18788
18789        if (app == mPreviousProcess && app.activities.size() > 0) {
18790            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18791                // This was the previous process that showed UI to the user.
18792                // We want to try to keep it around more aggressively, to give
18793                // a good experience around switching between two apps.
18794                adj = ProcessList.PREVIOUS_APP_ADJ;
18795                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18796                app.cached = false;
18797                app.adjType = "previous";
18798            }
18799            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18800                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18801            }
18802        }
18803
18804        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18805                + " reason=" + app.adjType);
18806
18807        // By default, we use the computed adjustment.  It may be changed if
18808        // there are applications dependent on our services or providers, but
18809        // this gives us a baseline and makes sure we don't get into an
18810        // infinite recursion.
18811        app.adjSeq = mAdjSeq;
18812        app.curRawAdj = adj;
18813        app.hasStartedServices = false;
18814
18815        if (mBackupTarget != null && app == mBackupTarget.app) {
18816            // If possible we want to avoid killing apps while they're being backed up
18817            if (adj > ProcessList.BACKUP_APP_ADJ) {
18818                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18819                adj = ProcessList.BACKUP_APP_ADJ;
18820                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18821                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18822                }
18823                app.adjType = "backup";
18824                app.cached = false;
18825            }
18826            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18827                procState = ActivityManager.PROCESS_STATE_BACKUP;
18828            }
18829        }
18830
18831        boolean mayBeTop = false;
18832
18833        for (int is = app.services.size()-1;
18834                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18835                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18836                        || procState > ActivityManager.PROCESS_STATE_TOP);
18837                is--) {
18838            ServiceRecord s = app.services.valueAt(is);
18839            if (s.startRequested) {
18840                app.hasStartedServices = true;
18841                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18842                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18843                }
18844                if (app.hasShownUi && app != mHomeProcess) {
18845                    // If this process has shown some UI, let it immediately
18846                    // go to the LRU list because it may be pretty heavy with
18847                    // UI stuff.  We'll tag it with a label just to help
18848                    // debug and understand what is going on.
18849                    if (adj > ProcessList.SERVICE_ADJ) {
18850                        app.adjType = "cch-started-ui-services";
18851                    }
18852                } else {
18853                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18854                        // This service has seen some activity within
18855                        // recent memory, so we will keep its process ahead
18856                        // of the background processes.
18857                        if (adj > ProcessList.SERVICE_ADJ) {
18858                            adj = ProcessList.SERVICE_ADJ;
18859                            app.adjType = "started-services";
18860                            app.cached = false;
18861                        }
18862                    }
18863                    // If we have let the service slide into the background
18864                    // state, still have some text describing what it is doing
18865                    // even though the service no longer has an impact.
18866                    if (adj > ProcessList.SERVICE_ADJ) {
18867                        app.adjType = "cch-started-services";
18868                    }
18869                }
18870            }
18871            for (int conni = s.connections.size()-1;
18872                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18873                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18874                            || procState > ActivityManager.PROCESS_STATE_TOP);
18875                    conni--) {
18876                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18877                for (int i = 0;
18878                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18879                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18880                                || procState > ActivityManager.PROCESS_STATE_TOP);
18881                        i++) {
18882                    // XXX should compute this based on the max of
18883                    // all connected clients.
18884                    ConnectionRecord cr = clist.get(i);
18885                    if (cr.binding.client == app) {
18886                        // Binding to ourself is not interesting.
18887                        continue;
18888                    }
18889                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18890                        ProcessRecord client = cr.binding.client;
18891                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18892                                TOP_APP, doingAll, now);
18893                        int clientProcState = client.curProcState;
18894                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18895                            // If the other app is cached for any reason, for purposes here
18896                            // we are going to consider it empty.  The specific cached state
18897                            // doesn't propagate except under certain conditions.
18898                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18899                        }
18900                        String adjType = null;
18901                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18902                            // Not doing bind OOM management, so treat
18903                            // this guy more like a started service.
18904                            if (app.hasShownUi && app != mHomeProcess) {
18905                                // If this process has shown some UI, let it immediately
18906                                // go to the LRU list because it may be pretty heavy with
18907                                // UI stuff.  We'll tag it with a label just to help
18908                                // debug and understand what is going on.
18909                                if (adj > clientAdj) {
18910                                    adjType = "cch-bound-ui-services";
18911                                }
18912                                app.cached = false;
18913                                clientAdj = adj;
18914                                clientProcState = procState;
18915                            } else {
18916                                if (now >= (s.lastActivity
18917                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18918                                    // This service has not seen activity within
18919                                    // recent memory, so allow it to drop to the
18920                                    // LRU list if there is no other reason to keep
18921                                    // it around.  We'll also tag it with a label just
18922                                    // to help debug and undertand what is going on.
18923                                    if (adj > clientAdj) {
18924                                        adjType = "cch-bound-services";
18925                                    }
18926                                    clientAdj = adj;
18927                                }
18928                            }
18929                        }
18930                        if (adj > clientAdj) {
18931                            // If this process has recently shown UI, and
18932                            // the process that is binding to it is less
18933                            // important than being visible, then we don't
18934                            // care about the binding as much as we care
18935                            // about letting this process get into the LRU
18936                            // list to be killed and restarted if needed for
18937                            // memory.
18938                            if (app.hasShownUi && app != mHomeProcess
18939                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18940                                adjType = "cch-bound-ui-services";
18941                            } else {
18942                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18943                                        |Context.BIND_IMPORTANT)) != 0) {
18944                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18945                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18946                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18947                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18948                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18949                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18950                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18951                                    adj = clientAdj;
18952                                } else {
18953                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18954                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18955                                    }
18956                                }
18957                                if (!client.cached) {
18958                                    app.cached = false;
18959                                }
18960                                adjType = "service";
18961                            }
18962                        }
18963                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18964                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18965                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18966                            }
18967                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18968                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18969                                    // Special handling of clients who are in the top state.
18970                                    // We *may* want to consider this process to be in the
18971                                    // top state as well, but only if there is not another
18972                                    // reason for it to be running.  Being on the top is a
18973                                    // special state, meaning you are specifically running
18974                                    // for the current top app.  If the process is already
18975                                    // running in the background for some other reason, it
18976                                    // is more important to continue considering it to be
18977                                    // in the background state.
18978                                    mayBeTop = true;
18979                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18980                                } else {
18981                                    // Special handling for above-top states (persistent
18982                                    // processes).  These should not bring the current process
18983                                    // into the top state, since they are not on top.  Instead
18984                                    // give them the best state after that.
18985                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18986                                        clientProcState =
18987                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18988                                    } else if (mWakefulness
18989                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18990                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18991                                                    != 0) {
18992                                        clientProcState =
18993                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18994                                    } else {
18995                                        clientProcState =
18996                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18997                                    }
18998                                }
18999                            }
19000                        } else {
19001                            if (clientProcState <
19002                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19003                                clientProcState =
19004                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19005                            }
19006                        }
19007                        if (procState > clientProcState) {
19008                            procState = clientProcState;
19009                        }
19010                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19011                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19012                            app.pendingUiClean = true;
19013                        }
19014                        if (adjType != null) {
19015                            app.adjType = adjType;
19016                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19017                                    .REASON_SERVICE_IN_USE;
19018                            app.adjSource = cr.binding.client;
19019                            app.adjSourceProcState = clientProcState;
19020                            app.adjTarget = s.name;
19021                        }
19022                    }
19023                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19024                        app.treatLikeActivity = true;
19025                    }
19026                    final ActivityRecord a = cr.activity;
19027                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19028                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19029                                (a.visible || a.state == ActivityState.RESUMED
19030                                 || a.state == ActivityState.PAUSING)) {
19031                            adj = ProcessList.FOREGROUND_APP_ADJ;
19032                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19033                                schedGroup = Process.THREAD_GROUP_DEFAULT;
19034                            }
19035                            app.cached = false;
19036                            app.adjType = "service";
19037                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19038                                    .REASON_SERVICE_IN_USE;
19039                            app.adjSource = a;
19040                            app.adjSourceProcState = procState;
19041                            app.adjTarget = s.name;
19042                        }
19043                    }
19044                }
19045            }
19046        }
19047
19048        for (int provi = app.pubProviders.size()-1;
19049                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19050                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
19051                        || procState > ActivityManager.PROCESS_STATE_TOP);
19052                provi--) {
19053            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19054            for (int i = cpr.connections.size()-1;
19055                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19056                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
19057                            || procState > ActivityManager.PROCESS_STATE_TOP);
19058                    i--) {
19059                ContentProviderConnection conn = cpr.connections.get(i);
19060                ProcessRecord client = conn.client;
19061                if (client == app) {
19062                    // Being our own client is not interesting.
19063                    continue;
19064                }
19065                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19066                int clientProcState = client.curProcState;
19067                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19068                    // If the other app is cached for any reason, for purposes here
19069                    // we are going to consider it empty.
19070                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19071                }
19072                if (adj > clientAdj) {
19073                    if (app.hasShownUi && app != mHomeProcess
19074                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19075                        app.adjType = "cch-ui-provider";
19076                    } else {
19077                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19078                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19079                        app.adjType = "provider";
19080                    }
19081                    app.cached &= client.cached;
19082                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19083                            .REASON_PROVIDER_IN_USE;
19084                    app.adjSource = client;
19085                    app.adjSourceProcState = clientProcState;
19086                    app.adjTarget = cpr.name;
19087                }
19088                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19089                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19090                        // Special handling of clients who are in the top state.
19091                        // We *may* want to consider this process to be in the
19092                        // top state as well, but only if there is not another
19093                        // reason for it to be running.  Being on the top is a
19094                        // special state, meaning you are specifically running
19095                        // for the current top app.  If the process is already
19096                        // running in the background for some other reason, it
19097                        // is more important to continue considering it to be
19098                        // in the background state.
19099                        mayBeTop = true;
19100                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19101                    } else {
19102                        // Special handling for above-top states (persistent
19103                        // processes).  These should not bring the current process
19104                        // into the top state, since they are not on top.  Instead
19105                        // give them the best state after that.
19106                        clientProcState =
19107                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19108                    }
19109                }
19110                if (procState > clientProcState) {
19111                    procState = clientProcState;
19112                }
19113                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
19114                    schedGroup = Process.THREAD_GROUP_DEFAULT;
19115                }
19116            }
19117            // If the provider has external (non-framework) process
19118            // dependencies, ensure that its adjustment is at least
19119            // FOREGROUND_APP_ADJ.
19120            if (cpr.hasExternalProcessHandles()) {
19121                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19122                    adj = ProcessList.FOREGROUND_APP_ADJ;
19123                    schedGroup = Process.THREAD_GROUP_DEFAULT;
19124                    app.cached = false;
19125                    app.adjType = "provider";
19126                    app.adjTarget = cpr.name;
19127                }
19128                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19129                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19130                }
19131            }
19132        }
19133
19134        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19135            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19136                adj = ProcessList.PREVIOUS_APP_ADJ;
19137                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19138                app.cached = false;
19139                app.adjType = "provider";
19140            }
19141            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19142                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19143            }
19144        }
19145
19146        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19147            // A client of one of our services or providers is in the top state.  We
19148            // *may* want to be in the top state, but not if we are already running in
19149            // the background for some other reason.  For the decision here, we are going
19150            // to pick out a few specific states that we want to remain in when a client
19151            // is top (states that tend to be longer-term) and otherwise allow it to go
19152            // to the top state.
19153            switch (procState) {
19154                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19155                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19156                case ActivityManager.PROCESS_STATE_SERVICE:
19157                    // These all are longer-term states, so pull them up to the top
19158                    // of the background states, but not all the way to the top state.
19159                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19160                    break;
19161                default:
19162                    // Otherwise, top is a better choice, so take it.
19163                    procState = ActivityManager.PROCESS_STATE_TOP;
19164                    break;
19165            }
19166        }
19167
19168        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19169            if (app.hasClientActivities) {
19170                // This is a cached process, but with client activities.  Mark it so.
19171                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19172                app.adjType = "cch-client-act";
19173            } else if (app.treatLikeActivity) {
19174                // This is a cached process, but somebody wants us to treat it like it has
19175                // an activity, okay!
19176                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19177                app.adjType = "cch-as-act";
19178            }
19179        }
19180
19181        if (adj == ProcessList.SERVICE_ADJ) {
19182            if (doingAll) {
19183                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19184                mNewNumServiceProcs++;
19185                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19186                if (!app.serviceb) {
19187                    // This service isn't far enough down on the LRU list to
19188                    // normally be a B service, but if we are low on RAM and it
19189                    // is large we want to force it down since we would prefer to
19190                    // keep launcher over it.
19191                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19192                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19193                        app.serviceHighRam = true;
19194                        app.serviceb = true;
19195                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19196                    } else {
19197                        mNewNumAServiceProcs++;
19198                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19199                    }
19200                } else {
19201                    app.serviceHighRam = false;
19202                }
19203            }
19204            if (app.serviceb) {
19205                adj = ProcessList.SERVICE_B_ADJ;
19206            }
19207        }
19208
19209        app.curRawAdj = adj;
19210
19211        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19212        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19213        if (adj > app.maxAdj) {
19214            adj = app.maxAdj;
19215            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19216                schedGroup = Process.THREAD_GROUP_DEFAULT;
19217            }
19218        }
19219
19220        // Do final modification to adj.  Everything we do between here and applying
19221        // the final setAdj must be done in this function, because we will also use
19222        // it when computing the final cached adj later.  Note that we don't need to
19223        // worry about this for max adj above, since max adj will always be used to
19224        // keep it out of the cached vaues.
19225        app.curAdj = app.modifyRawOomAdj(adj);
19226        app.curSchedGroup = schedGroup;
19227        app.curProcState = procState;
19228        app.foregroundActivities = foregroundActivities;
19229
19230        return app.curRawAdj;
19231    }
19232
19233    /**
19234     * Record new PSS sample for a process.
19235     */
19236    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19237            long now) {
19238        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19239                swapPss * 1024);
19240        proc.lastPssTime = now;
19241        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19242        if (DEBUG_PSS) Slog.d(TAG_PSS,
19243                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19244                + " state=" + ProcessList.makeProcStateString(procState));
19245        if (proc.initialIdlePss == 0) {
19246            proc.initialIdlePss = pss;
19247        }
19248        proc.lastPss = pss;
19249        proc.lastSwapPss = swapPss;
19250        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19251            proc.lastCachedPss = pss;
19252            proc.lastCachedSwapPss = swapPss;
19253        }
19254
19255        final SparseArray<Pair<Long, String>> watchUids
19256                = mMemWatchProcesses.getMap().get(proc.processName);
19257        Long check = null;
19258        if (watchUids != null) {
19259            Pair<Long, String> val = watchUids.get(proc.uid);
19260            if (val == null) {
19261                val = watchUids.get(0);
19262            }
19263            if (val != null) {
19264                check = val.first;
19265            }
19266        }
19267        if (check != null) {
19268            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19269                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19270                if (!isDebuggable) {
19271                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19272                        isDebuggable = true;
19273                    }
19274                }
19275                if (isDebuggable) {
19276                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19277                    final ProcessRecord myProc = proc;
19278                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19279                    mMemWatchDumpProcName = proc.processName;
19280                    mMemWatchDumpFile = heapdumpFile.toString();
19281                    mMemWatchDumpPid = proc.pid;
19282                    mMemWatchDumpUid = proc.uid;
19283                    BackgroundThread.getHandler().post(new Runnable() {
19284                        @Override
19285                        public void run() {
19286                            revokeUriPermission(ActivityThread.currentActivityThread()
19287                                            .getApplicationThread(),
19288                                    DumpHeapActivity.JAVA_URI,
19289                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19290                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19291                                    UserHandle.myUserId());
19292                            ParcelFileDescriptor fd = null;
19293                            try {
19294                                heapdumpFile.delete();
19295                                fd = ParcelFileDescriptor.open(heapdumpFile,
19296                                        ParcelFileDescriptor.MODE_CREATE |
19297                                                ParcelFileDescriptor.MODE_TRUNCATE |
19298                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19299                                                ParcelFileDescriptor.MODE_APPEND);
19300                                IApplicationThread thread = myProc.thread;
19301                                if (thread != null) {
19302                                    try {
19303                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19304                                                "Requesting dump heap from "
19305                                                + myProc + " to " + heapdumpFile);
19306                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19307                                    } catch (RemoteException e) {
19308                                    }
19309                                }
19310                            } catch (FileNotFoundException e) {
19311                                e.printStackTrace();
19312                            } finally {
19313                                if (fd != null) {
19314                                    try {
19315                                        fd.close();
19316                                    } catch (IOException e) {
19317                                    }
19318                                }
19319                            }
19320                        }
19321                    });
19322                } else {
19323                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19324                            + ", but debugging not enabled");
19325                }
19326            }
19327        }
19328    }
19329
19330    /**
19331     * Schedule PSS collection of a process.
19332     */
19333    void requestPssLocked(ProcessRecord proc, int procState) {
19334        if (mPendingPssProcesses.contains(proc)) {
19335            return;
19336        }
19337        if (mPendingPssProcesses.size() == 0) {
19338            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19339        }
19340        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19341        proc.pssProcState = procState;
19342        mPendingPssProcesses.add(proc);
19343    }
19344
19345    /**
19346     * Schedule PSS collection of all processes.
19347     */
19348    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19349        if (!always) {
19350            if (now < (mLastFullPssTime +
19351                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19352                return;
19353            }
19354        }
19355        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19356        mLastFullPssTime = now;
19357        mFullPssPending = true;
19358        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19359        mPendingPssProcesses.clear();
19360        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19361            ProcessRecord app = mLruProcesses.get(i);
19362            if (app.thread == null
19363                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19364                continue;
19365            }
19366            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19367                app.pssProcState = app.setProcState;
19368                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19369                        mTestPssMode, isSleeping(), now);
19370                mPendingPssProcesses.add(app);
19371            }
19372        }
19373        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19374    }
19375
19376    public void setTestPssMode(boolean enabled) {
19377        synchronized (this) {
19378            mTestPssMode = enabled;
19379            if (enabled) {
19380                // Whenever we enable the mode, we want to take a snapshot all of current
19381                // process mem use.
19382                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19383            }
19384        }
19385    }
19386
19387    /**
19388     * Ask a given process to GC right now.
19389     */
19390    final void performAppGcLocked(ProcessRecord app) {
19391        try {
19392            app.lastRequestedGc = SystemClock.uptimeMillis();
19393            if (app.thread != null) {
19394                if (app.reportLowMemory) {
19395                    app.reportLowMemory = false;
19396                    app.thread.scheduleLowMemory();
19397                } else {
19398                    app.thread.processInBackground();
19399                }
19400            }
19401        } catch (Exception e) {
19402            // whatever.
19403        }
19404    }
19405
19406    /**
19407     * Returns true if things are idle enough to perform GCs.
19408     */
19409    private final boolean canGcNowLocked() {
19410        boolean processingBroadcasts = false;
19411        for (BroadcastQueue q : mBroadcastQueues) {
19412            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19413                processingBroadcasts = true;
19414            }
19415        }
19416        return !processingBroadcasts
19417                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19418    }
19419
19420    /**
19421     * Perform GCs on all processes that are waiting for it, but only
19422     * if things are idle.
19423     */
19424    final void performAppGcsLocked() {
19425        final int N = mProcessesToGc.size();
19426        if (N <= 0) {
19427            return;
19428        }
19429        if (canGcNowLocked()) {
19430            while (mProcessesToGc.size() > 0) {
19431                ProcessRecord proc = mProcessesToGc.remove(0);
19432                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19433                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19434                            <= SystemClock.uptimeMillis()) {
19435                        // To avoid spamming the system, we will GC processes one
19436                        // at a time, waiting a few seconds between each.
19437                        performAppGcLocked(proc);
19438                        scheduleAppGcsLocked();
19439                        return;
19440                    } else {
19441                        // It hasn't been long enough since we last GCed this
19442                        // process...  put it in the list to wait for its time.
19443                        addProcessToGcListLocked(proc);
19444                        break;
19445                    }
19446                }
19447            }
19448
19449            scheduleAppGcsLocked();
19450        }
19451    }
19452
19453    /**
19454     * If all looks good, perform GCs on all processes waiting for them.
19455     */
19456    final void performAppGcsIfAppropriateLocked() {
19457        if (canGcNowLocked()) {
19458            performAppGcsLocked();
19459            return;
19460        }
19461        // Still not idle, wait some more.
19462        scheduleAppGcsLocked();
19463    }
19464
19465    /**
19466     * Schedule the execution of all pending app GCs.
19467     */
19468    final void scheduleAppGcsLocked() {
19469        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19470
19471        if (mProcessesToGc.size() > 0) {
19472            // Schedule a GC for the time to the next process.
19473            ProcessRecord proc = mProcessesToGc.get(0);
19474            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19475
19476            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19477            long now = SystemClock.uptimeMillis();
19478            if (when < (now+GC_TIMEOUT)) {
19479                when = now + GC_TIMEOUT;
19480            }
19481            mHandler.sendMessageAtTime(msg, when);
19482        }
19483    }
19484
19485    /**
19486     * Add a process to the array of processes waiting to be GCed.  Keeps the
19487     * list in sorted order by the last GC time.  The process can't already be
19488     * on the list.
19489     */
19490    final void addProcessToGcListLocked(ProcessRecord proc) {
19491        boolean added = false;
19492        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19493            if (mProcessesToGc.get(i).lastRequestedGc <
19494                    proc.lastRequestedGc) {
19495                added = true;
19496                mProcessesToGc.add(i+1, proc);
19497                break;
19498            }
19499        }
19500        if (!added) {
19501            mProcessesToGc.add(0, proc);
19502        }
19503    }
19504
19505    /**
19506     * Set up to ask a process to GC itself.  This will either do it
19507     * immediately, or put it on the list of processes to gc the next
19508     * time things are idle.
19509     */
19510    final void scheduleAppGcLocked(ProcessRecord app) {
19511        long now = SystemClock.uptimeMillis();
19512        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19513            return;
19514        }
19515        if (!mProcessesToGc.contains(app)) {
19516            addProcessToGcListLocked(app);
19517            scheduleAppGcsLocked();
19518        }
19519    }
19520
19521    final void checkExcessivePowerUsageLocked(boolean doKills) {
19522        updateCpuStatsNow();
19523
19524        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19525        boolean doWakeKills = doKills;
19526        boolean doCpuKills = doKills;
19527        if (mLastPowerCheckRealtime == 0) {
19528            doWakeKills = false;
19529        }
19530        if (mLastPowerCheckUptime == 0) {
19531            doCpuKills = false;
19532        }
19533        if (stats.isScreenOn()) {
19534            doWakeKills = false;
19535        }
19536        final long curRealtime = SystemClock.elapsedRealtime();
19537        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19538        final long curUptime = SystemClock.uptimeMillis();
19539        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19540        mLastPowerCheckRealtime = curRealtime;
19541        mLastPowerCheckUptime = curUptime;
19542        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19543            doWakeKills = false;
19544        }
19545        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19546            doCpuKills = false;
19547        }
19548        int i = mLruProcesses.size();
19549        while (i > 0) {
19550            i--;
19551            ProcessRecord app = mLruProcesses.get(i);
19552            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19553                long wtime;
19554                synchronized (stats) {
19555                    wtime = stats.getProcessWakeTime(app.info.uid,
19556                            app.pid, curRealtime);
19557                }
19558                long wtimeUsed = wtime - app.lastWakeTime;
19559                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19560                if (DEBUG_POWER) {
19561                    StringBuilder sb = new StringBuilder(128);
19562                    sb.append("Wake for ");
19563                    app.toShortString(sb);
19564                    sb.append(": over ");
19565                    TimeUtils.formatDuration(realtimeSince, sb);
19566                    sb.append(" used ");
19567                    TimeUtils.formatDuration(wtimeUsed, sb);
19568                    sb.append(" (");
19569                    sb.append((wtimeUsed*100)/realtimeSince);
19570                    sb.append("%)");
19571                    Slog.i(TAG_POWER, sb.toString());
19572                    sb.setLength(0);
19573                    sb.append("CPU for ");
19574                    app.toShortString(sb);
19575                    sb.append(": over ");
19576                    TimeUtils.formatDuration(uptimeSince, sb);
19577                    sb.append(" used ");
19578                    TimeUtils.formatDuration(cputimeUsed, sb);
19579                    sb.append(" (");
19580                    sb.append((cputimeUsed*100)/uptimeSince);
19581                    sb.append("%)");
19582                    Slog.i(TAG_POWER, sb.toString());
19583                }
19584                // If a process has held a wake lock for more
19585                // than 50% of the time during this period,
19586                // that sounds bad.  Kill!
19587                if (doWakeKills && realtimeSince > 0
19588                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19589                    synchronized (stats) {
19590                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19591                                realtimeSince, wtimeUsed);
19592                    }
19593                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19594                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19595                } else if (doCpuKills && uptimeSince > 0
19596                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19597                    synchronized (stats) {
19598                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19599                                uptimeSince, cputimeUsed);
19600                    }
19601                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19602                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19603                } else {
19604                    app.lastWakeTime = wtime;
19605                    app.lastCpuTime = app.curCpuTime;
19606                }
19607            }
19608        }
19609    }
19610
19611    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19612            long nowElapsed) {
19613        boolean success = true;
19614
19615        if (app.curRawAdj != app.setRawAdj) {
19616            app.setRawAdj = app.curRawAdj;
19617        }
19618
19619        int changes = 0;
19620
19621        if (app.curAdj != app.setAdj) {
19622            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19623            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19624                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19625                    + app.adjType);
19626            app.setAdj = app.curAdj;
19627        }
19628
19629        if (app.setSchedGroup != app.curSchedGroup) {
19630            app.setSchedGroup = app.curSchedGroup;
19631            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19632                    "Setting process group of " + app.processName
19633                    + " to " + app.curSchedGroup);
19634            if (app.waitingToKill != null && app.curReceiver == null
19635                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19636                app.kill(app.waitingToKill, true);
19637                success = false;
19638            } else {
19639                if (true) {
19640                    long oldId = Binder.clearCallingIdentity();
19641                    try {
19642                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19643                    } catch (Exception e) {
19644                        Slog.w(TAG, "Failed setting process group of " + app.pid
19645                                + " to " + app.curSchedGroup);
19646                        e.printStackTrace();
19647                    } finally {
19648                        Binder.restoreCallingIdentity(oldId);
19649                    }
19650                } else {
19651                    if (app.thread != null) {
19652                        try {
19653                            app.thread.setSchedulingGroup(app.curSchedGroup);
19654                        } catch (RemoteException e) {
19655                        }
19656                    }
19657                }
19658            }
19659        }
19660        if (app.repForegroundActivities != app.foregroundActivities) {
19661            app.repForegroundActivities = app.foregroundActivities;
19662            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19663        }
19664        if (app.repProcState != app.curProcState) {
19665            app.repProcState = app.curProcState;
19666            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19667            if (app.thread != null) {
19668                try {
19669                    if (false) {
19670                        //RuntimeException h = new RuntimeException("here");
19671                        Slog.i(TAG, "Sending new process state " + app.repProcState
19672                                + " to " + app /*, h*/);
19673                    }
19674                    app.thread.setProcessState(app.repProcState);
19675                } catch (RemoteException e) {
19676                }
19677            }
19678        }
19679        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19680                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19681            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19682                // Experimental code to more aggressively collect pss while
19683                // running test...  the problem is that this tends to collect
19684                // the data right when a process is transitioning between process
19685                // states, which well tend to give noisy data.
19686                long start = SystemClock.uptimeMillis();
19687                long pss = Debug.getPss(app.pid, mTmpLong, null);
19688                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19689                mPendingPssProcesses.remove(app);
19690                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19691                        + " to " + app.curProcState + ": "
19692                        + (SystemClock.uptimeMillis()-start) + "ms");
19693            }
19694            app.lastStateTime = now;
19695            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19696                    mTestPssMode, isSleeping(), now);
19697            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19698                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19699                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19700                    + (app.nextPssTime-now) + ": " + app);
19701        } else {
19702            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19703                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19704                    mTestPssMode)))) {
19705                requestPssLocked(app, app.setProcState);
19706                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19707                        mTestPssMode, isSleeping(), now);
19708            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19709                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19710        }
19711        if (app.setProcState != app.curProcState) {
19712            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19713                    "Proc state change of " + app.processName
19714                            + " to " + app.curProcState);
19715            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19716            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19717            if (setImportant && !curImportant) {
19718                // This app is no longer something we consider important enough to allow to
19719                // use arbitrary amounts of battery power.  Note
19720                // its current wake lock time to later know to kill it if
19721                // it is not behaving well.
19722                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19723                synchronized (stats) {
19724                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19725                            app.pid, nowElapsed);
19726                }
19727                app.lastCpuTime = app.curCpuTime;
19728
19729            }
19730            // Inform UsageStats of important process state change
19731            // Must be called before updating setProcState
19732            maybeUpdateUsageStatsLocked(app, nowElapsed);
19733
19734            app.setProcState = app.curProcState;
19735            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19736                app.notCachedSinceIdle = false;
19737            }
19738            if (!doingAll) {
19739                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19740            } else {
19741                app.procStateChanged = true;
19742            }
19743        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19744                > USAGE_STATS_INTERACTION_INTERVAL) {
19745            // For apps that sit around for a long time in the interactive state, we need
19746            // to report this at least once a day so they don't go idle.
19747            maybeUpdateUsageStatsLocked(app, nowElapsed);
19748        }
19749
19750        if (changes != 0) {
19751            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19752                    "Changes in " + app + ": " + changes);
19753            int i = mPendingProcessChanges.size()-1;
19754            ProcessChangeItem item = null;
19755            while (i >= 0) {
19756                item = mPendingProcessChanges.get(i);
19757                if (item.pid == app.pid) {
19758                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19759                            "Re-using existing item: " + item);
19760                    break;
19761                }
19762                i--;
19763            }
19764            if (i < 0) {
19765                // No existing item in pending changes; need a new one.
19766                final int NA = mAvailProcessChanges.size();
19767                if (NA > 0) {
19768                    item = mAvailProcessChanges.remove(NA-1);
19769                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19770                            "Retrieving available item: " + item);
19771                } else {
19772                    item = new ProcessChangeItem();
19773                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19774                            "Allocating new item: " + item);
19775                }
19776                item.changes = 0;
19777                item.pid = app.pid;
19778                item.uid = app.info.uid;
19779                if (mPendingProcessChanges.size() == 0) {
19780                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19781                            "*** Enqueueing dispatch processes changed!");
19782                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19783                }
19784                mPendingProcessChanges.add(item);
19785            }
19786            item.changes |= changes;
19787            item.processState = app.repProcState;
19788            item.foregroundActivities = app.repForegroundActivities;
19789            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19790                    "Item " + Integer.toHexString(System.identityHashCode(item))
19791                    + " " + app.toShortString() + ": changes=" + item.changes
19792                    + " procState=" + item.processState
19793                    + " foreground=" + item.foregroundActivities
19794                    + " type=" + app.adjType + " source=" + app.adjSource
19795                    + " target=" + app.adjTarget);
19796        }
19797
19798        return success;
19799    }
19800
19801    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19802        final UidRecord.ChangeItem pendingChange;
19803        if (uidRec == null || uidRec.pendingChange == null) {
19804            if (mPendingUidChanges.size() == 0) {
19805                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19806                        "*** Enqueueing dispatch uid changed!");
19807                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19808            }
19809            final int NA = mAvailUidChanges.size();
19810            if (NA > 0) {
19811                pendingChange = mAvailUidChanges.remove(NA-1);
19812                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19813                        "Retrieving available item: " + pendingChange);
19814            } else {
19815                pendingChange = new UidRecord.ChangeItem();
19816                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19817                        "Allocating new item: " + pendingChange);
19818            }
19819            if (uidRec != null) {
19820                uidRec.pendingChange = pendingChange;
19821                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19822                    // If this uid is going away, and we haven't yet reported it is gone,
19823                    // then do so now.
19824                    change = UidRecord.CHANGE_GONE_IDLE;
19825                }
19826            } else if (uid < 0) {
19827                throw new IllegalArgumentException("No UidRecord or uid");
19828            }
19829            pendingChange.uidRecord = uidRec;
19830            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19831            mPendingUidChanges.add(pendingChange);
19832        } else {
19833            pendingChange = uidRec.pendingChange;
19834            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19835                change = UidRecord.CHANGE_GONE_IDLE;
19836            }
19837        }
19838        pendingChange.change = change;
19839        pendingChange.processState = uidRec != null
19840                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19841    }
19842
19843    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19844            String authority) {
19845        if (app == null) return;
19846        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19847            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19848            if (userState == null) return;
19849            final long now = SystemClock.elapsedRealtime();
19850            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19851            if (lastReported == null || lastReported < now - 60 * 1000L) {
19852                mUsageStatsService.reportContentProviderUsage(
19853                        authority, providerPkgName, app.userId);
19854                userState.mProviderLastReportedFg.put(authority, now);
19855            }
19856        }
19857    }
19858
19859    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19860        if (DEBUG_USAGE_STATS) {
19861            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19862                    + "] state changes: old = " + app.setProcState + ", new = "
19863                    + app.curProcState);
19864        }
19865        if (mUsageStatsService == null) {
19866            return;
19867        }
19868        boolean isInteraction;
19869        // To avoid some abuse patterns, we are going to be careful about what we consider
19870        // to be an app interaction.  Being the top activity doesn't count while the display
19871        // is sleeping, nor do short foreground services.
19872        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19873            isInteraction = true;
19874            app.fgInteractionTime = 0;
19875        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19876            if (app.fgInteractionTime == 0) {
19877                app.fgInteractionTime = nowElapsed;
19878                isInteraction = false;
19879            } else {
19880                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19881            }
19882        } else {
19883            isInteraction = app.curProcState
19884                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19885            app.fgInteractionTime = 0;
19886        }
19887        if (isInteraction && (!app.reportedInteraction
19888                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19889            app.interactionEventTime = nowElapsed;
19890            String[] packages = app.getPackageList();
19891            if (packages != null) {
19892                for (int i = 0; i < packages.length; i++) {
19893                    mUsageStatsService.reportEvent(packages[i], app.userId,
19894                            UsageEvents.Event.SYSTEM_INTERACTION);
19895                }
19896            }
19897        }
19898        app.reportedInteraction = isInteraction;
19899        if (!isInteraction) {
19900            app.interactionEventTime = 0;
19901        }
19902    }
19903
19904    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19905        if (proc.thread != null) {
19906            if (proc.baseProcessTracker != null) {
19907                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19908            }
19909        }
19910    }
19911
19912    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19913            ProcessRecord TOP_APP, boolean doingAll, long now) {
19914        if (app.thread == null) {
19915            return false;
19916        }
19917
19918        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19919
19920        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19921    }
19922
19923    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19924            boolean oomAdj) {
19925        if (isForeground != proc.foregroundServices) {
19926            proc.foregroundServices = isForeground;
19927            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19928                    proc.info.uid);
19929            if (isForeground) {
19930                if (curProcs == null) {
19931                    curProcs = new ArrayList<ProcessRecord>();
19932                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19933                }
19934                if (!curProcs.contains(proc)) {
19935                    curProcs.add(proc);
19936                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19937                            proc.info.packageName, proc.info.uid);
19938                }
19939            } else {
19940                if (curProcs != null) {
19941                    if (curProcs.remove(proc)) {
19942                        mBatteryStatsService.noteEvent(
19943                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19944                                proc.info.packageName, proc.info.uid);
19945                        if (curProcs.size() <= 0) {
19946                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19947                        }
19948                    }
19949                }
19950            }
19951            if (oomAdj) {
19952                updateOomAdjLocked();
19953            }
19954        }
19955    }
19956
19957    private final ActivityRecord resumedAppLocked() {
19958        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19959        String pkg;
19960        int uid;
19961        if (act != null) {
19962            pkg = act.packageName;
19963            uid = act.info.applicationInfo.uid;
19964        } else {
19965            pkg = null;
19966            uid = -1;
19967        }
19968        // Has the UID or resumed package name changed?
19969        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19970                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19971            if (mCurResumedPackage != null) {
19972                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19973                        mCurResumedPackage, mCurResumedUid);
19974            }
19975            mCurResumedPackage = pkg;
19976            mCurResumedUid = uid;
19977            if (mCurResumedPackage != null) {
19978                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19979                        mCurResumedPackage, mCurResumedUid);
19980            }
19981        }
19982        return act;
19983    }
19984
19985    final boolean updateOomAdjLocked(ProcessRecord app) {
19986        final ActivityRecord TOP_ACT = resumedAppLocked();
19987        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19988        final boolean wasCached = app.cached;
19989
19990        mAdjSeq++;
19991
19992        // This is the desired cached adjusment we want to tell it to use.
19993        // If our app is currently cached, we know it, and that is it.  Otherwise,
19994        // we don't know it yet, and it needs to now be cached we will then
19995        // need to do a complete oom adj.
19996        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19997                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19998        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19999                SystemClock.uptimeMillis());
20000        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20001            // Changed to/from cached state, so apps after it in the LRU
20002            // list may also be changed.
20003            updateOomAdjLocked();
20004        }
20005        return success;
20006    }
20007
20008    final void updateOomAdjLocked() {
20009        final ActivityRecord TOP_ACT = resumedAppLocked();
20010        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20011        final long now = SystemClock.uptimeMillis();
20012        final long nowElapsed = SystemClock.elapsedRealtime();
20013        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20014        final int N = mLruProcesses.size();
20015
20016        if (false) {
20017            RuntimeException e = new RuntimeException();
20018            e.fillInStackTrace();
20019            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20020        }
20021
20022        // Reset state in all uid records.
20023        for (int i=mActiveUids.size()-1; i>=0; i--) {
20024            final UidRecord uidRec = mActiveUids.valueAt(i);
20025            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20026                    "Starting update of " + uidRec);
20027            uidRec.reset();
20028        }
20029
20030        mStackSupervisor.rankTaskLayersIfNeeded();
20031
20032        mAdjSeq++;
20033        mNewNumServiceProcs = 0;
20034        mNewNumAServiceProcs = 0;
20035
20036        final int emptyProcessLimit;
20037        final int cachedProcessLimit;
20038        if (mProcessLimit <= 0) {
20039            emptyProcessLimit = cachedProcessLimit = 0;
20040        } else if (mProcessLimit == 1) {
20041            emptyProcessLimit = 1;
20042            cachedProcessLimit = 0;
20043        } else {
20044            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20045            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20046        }
20047
20048        // Let's determine how many processes we have running vs.
20049        // how many slots we have for background processes; we may want
20050        // to put multiple processes in a slot of there are enough of
20051        // them.
20052        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20053                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20054        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20055        if (numEmptyProcs > cachedProcessLimit) {
20056            // If there are more empty processes than our limit on cached
20057            // processes, then use the cached process limit for the factor.
20058            // This ensures that the really old empty processes get pushed
20059            // down to the bottom, so if we are running low on memory we will
20060            // have a better chance at keeping around more cached processes
20061            // instead of a gazillion empty processes.
20062            numEmptyProcs = cachedProcessLimit;
20063        }
20064        int emptyFactor = numEmptyProcs/numSlots;
20065        if (emptyFactor < 1) emptyFactor = 1;
20066        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20067        if (cachedFactor < 1) cachedFactor = 1;
20068        int stepCached = 0;
20069        int stepEmpty = 0;
20070        int numCached = 0;
20071        int numEmpty = 0;
20072        int numTrimming = 0;
20073
20074        mNumNonCachedProcs = 0;
20075        mNumCachedHiddenProcs = 0;
20076
20077        // First update the OOM adjustment for each of the
20078        // application processes based on their current state.
20079        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20080        int nextCachedAdj = curCachedAdj+1;
20081        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20082        int nextEmptyAdj = curEmptyAdj+2;
20083        for (int i=N-1; i>=0; i--) {
20084            ProcessRecord app = mLruProcesses.get(i);
20085            if (!app.killedByAm && app.thread != null) {
20086                app.procStateChanged = false;
20087                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20088
20089                // If we haven't yet assigned the final cached adj
20090                // to the process, do that now.
20091                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20092                    switch (app.curProcState) {
20093                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20094                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20095                            // This process is a cached process holding activities...
20096                            // assign it the next cached value for that type, and then
20097                            // step that cached level.
20098                            app.curRawAdj = curCachedAdj;
20099                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20100                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20101                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20102                                    + ")");
20103                            if (curCachedAdj != nextCachedAdj) {
20104                                stepCached++;
20105                                if (stepCached >= cachedFactor) {
20106                                    stepCached = 0;
20107                                    curCachedAdj = nextCachedAdj;
20108                                    nextCachedAdj += 2;
20109                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20110                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20111                                    }
20112                                }
20113                            }
20114                            break;
20115                        default:
20116                            // For everything else, assign next empty cached process
20117                            // level and bump that up.  Note that this means that
20118                            // long-running services that have dropped down to the
20119                            // cached level will be treated as empty (since their process
20120                            // state is still as a service), which is what we want.
20121                            app.curRawAdj = curEmptyAdj;
20122                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20123                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20124                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20125                                    + ")");
20126                            if (curEmptyAdj != nextEmptyAdj) {
20127                                stepEmpty++;
20128                                if (stepEmpty >= emptyFactor) {
20129                                    stepEmpty = 0;
20130                                    curEmptyAdj = nextEmptyAdj;
20131                                    nextEmptyAdj += 2;
20132                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20133                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20134                                    }
20135                                }
20136                            }
20137                            break;
20138                    }
20139                }
20140
20141                applyOomAdjLocked(app, true, now, nowElapsed);
20142
20143                // Count the number of process types.
20144                switch (app.curProcState) {
20145                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20146                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20147                        mNumCachedHiddenProcs++;
20148                        numCached++;
20149                        if (numCached > cachedProcessLimit) {
20150                            app.kill("cached #" + numCached, true);
20151                        }
20152                        break;
20153                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20154                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20155                                && app.lastActivityTime < oldTime) {
20156                            app.kill("empty for "
20157                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20158                                    / 1000) + "s", true);
20159                        } else {
20160                            numEmpty++;
20161                            if (numEmpty > emptyProcessLimit) {
20162                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20163                            }
20164                        }
20165                        break;
20166                    default:
20167                        mNumNonCachedProcs++;
20168                        break;
20169                }
20170
20171                if (app.isolated && app.services.size() <= 0) {
20172                    // If this is an isolated process, and there are no
20173                    // services running in it, then the process is no longer
20174                    // needed.  We agressively kill these because we can by
20175                    // definition not re-use the same process again, and it is
20176                    // good to avoid having whatever code was running in them
20177                    // left sitting around after no longer needed.
20178                    app.kill("isolated not needed", true);
20179                } else {
20180                    // Keeping this process, update its uid.
20181                    final UidRecord uidRec = app.uidRecord;
20182                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20183                        uidRec.curProcState = app.curProcState;
20184                    }
20185                }
20186
20187                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20188                        && !app.killedByAm) {
20189                    numTrimming++;
20190                }
20191            }
20192        }
20193
20194        mNumServiceProcs = mNewNumServiceProcs;
20195
20196        // Now determine the memory trimming level of background processes.
20197        // Unfortunately we need to start at the back of the list to do this
20198        // properly.  We only do this if the number of background apps we
20199        // are managing to keep around is less than half the maximum we desire;
20200        // if we are keeping a good number around, we'll let them use whatever
20201        // memory they want.
20202        final int numCachedAndEmpty = numCached + numEmpty;
20203        int memFactor;
20204        if (numCached <= ProcessList.TRIM_CACHED_APPS
20205                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20206            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20207                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20208            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20209                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20210            } else {
20211                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20212            }
20213        } else {
20214            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20215        }
20216        // We always allow the memory level to go up (better).  We only allow it to go
20217        // down if we are in a state where that is allowed, *and* the total number of processes
20218        // has gone down since last time.
20219        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20220                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20221                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20222        if (memFactor > mLastMemoryLevel) {
20223            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20224                memFactor = mLastMemoryLevel;
20225                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20226            }
20227        }
20228        mLastMemoryLevel = memFactor;
20229        mLastNumProcesses = mLruProcesses.size();
20230        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20231        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20232        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20233            if (mLowRamStartTime == 0) {
20234                mLowRamStartTime = now;
20235            }
20236            int step = 0;
20237            int fgTrimLevel;
20238            switch (memFactor) {
20239                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20240                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20241                    break;
20242                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20243                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20244                    break;
20245                default:
20246                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20247                    break;
20248            }
20249            int factor = numTrimming/3;
20250            int minFactor = 2;
20251            if (mHomeProcess != null) minFactor++;
20252            if (mPreviousProcess != null) minFactor++;
20253            if (factor < minFactor) factor = minFactor;
20254            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20255            for (int i=N-1; i>=0; i--) {
20256                ProcessRecord app = mLruProcesses.get(i);
20257                if (allChanged || app.procStateChanged) {
20258                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20259                    app.procStateChanged = false;
20260                }
20261                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20262                        && !app.killedByAm) {
20263                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20264                        try {
20265                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20266                                    "Trimming memory of " + app.processName + " to " + curLevel);
20267                            app.thread.scheduleTrimMemory(curLevel);
20268                        } catch (RemoteException e) {
20269                        }
20270                        if (false) {
20271                            // For now we won't do this; our memory trimming seems
20272                            // to be good enough at this point that destroying
20273                            // activities causes more harm than good.
20274                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20275                                    && app != mHomeProcess && app != mPreviousProcess) {
20276                                // Need to do this on its own message because the stack may not
20277                                // be in a consistent state at this point.
20278                                // For these apps we will also finish their activities
20279                                // to help them free memory.
20280                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20281                            }
20282                        }
20283                    }
20284                    app.trimMemoryLevel = curLevel;
20285                    step++;
20286                    if (step >= factor) {
20287                        step = 0;
20288                        switch (curLevel) {
20289                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20290                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20291                                break;
20292                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20293                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20294                                break;
20295                        }
20296                    }
20297                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20298                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20299                            && app.thread != null) {
20300                        try {
20301                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20302                                    "Trimming memory of heavy-weight " + app.processName
20303                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20304                            app.thread.scheduleTrimMemory(
20305                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20306                        } catch (RemoteException e) {
20307                        }
20308                    }
20309                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20310                } else {
20311                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20312                            || app.systemNoUi) && app.pendingUiClean) {
20313                        // If this application is now in the background and it
20314                        // had done UI, then give it the special trim level to
20315                        // have it free UI resources.
20316                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20317                        if (app.trimMemoryLevel < level && app.thread != null) {
20318                            try {
20319                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20320                                        "Trimming memory of bg-ui " + app.processName
20321                                        + " to " + level);
20322                                app.thread.scheduleTrimMemory(level);
20323                            } catch (RemoteException e) {
20324                            }
20325                        }
20326                        app.pendingUiClean = false;
20327                    }
20328                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20329                        try {
20330                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20331                                    "Trimming memory of fg " + app.processName
20332                                    + " to " + fgTrimLevel);
20333                            app.thread.scheduleTrimMemory(fgTrimLevel);
20334                        } catch (RemoteException e) {
20335                        }
20336                    }
20337                    app.trimMemoryLevel = fgTrimLevel;
20338                }
20339            }
20340        } else {
20341            if (mLowRamStartTime != 0) {
20342                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20343                mLowRamStartTime = 0;
20344            }
20345            for (int i=N-1; i>=0; i--) {
20346                ProcessRecord app = mLruProcesses.get(i);
20347                if (allChanged || app.procStateChanged) {
20348                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20349                    app.procStateChanged = false;
20350                }
20351                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20352                        || app.systemNoUi) && app.pendingUiClean) {
20353                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20354                            && app.thread != null) {
20355                        try {
20356                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20357                                    "Trimming memory of ui hidden " + app.processName
20358                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20359                            app.thread.scheduleTrimMemory(
20360                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20361                        } catch (RemoteException e) {
20362                        }
20363                    }
20364                    app.pendingUiClean = false;
20365                }
20366                app.trimMemoryLevel = 0;
20367            }
20368        }
20369
20370        if (mAlwaysFinishActivities) {
20371            // Need to do this on its own message because the stack may not
20372            // be in a consistent state at this point.
20373            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20374        }
20375
20376        if (allChanged) {
20377            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20378        }
20379
20380        // Update from any uid changes.
20381        for (int i=mActiveUids.size()-1; i>=0; i--) {
20382            final UidRecord uidRec = mActiveUids.valueAt(i);
20383            int uidChange = UidRecord.CHANGE_PROCSTATE;
20384            if (uidRec.setProcState != uidRec.curProcState) {
20385                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20386                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20387                        + " to " + uidRec.curProcState);
20388                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20389                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20390                        uidRec.lastBackgroundTime = nowElapsed;
20391                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20392                            // Note: the background settle time is in elapsed realtime, while
20393                            // the handler time base is uptime.  All this means is that we may
20394                            // stop background uids later than we had intended, but that only
20395                            // happens because the device was sleeping so we are okay anyway.
20396                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20397                        }
20398                    }
20399                } else {
20400                    if (uidRec.idle) {
20401                        uidChange = UidRecord.CHANGE_ACTIVE;
20402                        uidRec.idle = false;
20403                    }
20404                    uidRec.lastBackgroundTime = 0;
20405                }
20406                uidRec.setProcState = uidRec.curProcState;
20407                enqueueUidChangeLocked(uidRec, -1, uidChange);
20408                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20409            }
20410        }
20411
20412        if (mProcessStats.shouldWriteNowLocked(now)) {
20413            mHandler.post(new Runnable() {
20414                @Override public void run() {
20415                    synchronized (ActivityManagerService.this) {
20416                        mProcessStats.writeStateAsyncLocked();
20417                    }
20418                }
20419            });
20420        }
20421
20422        if (DEBUG_OOM_ADJ) {
20423            final long duration = SystemClock.uptimeMillis() - now;
20424            if (false) {
20425                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20426                        new RuntimeException("here").fillInStackTrace());
20427            } else {
20428                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20429            }
20430        }
20431    }
20432
20433    final void idleUids() {
20434        synchronized (this) {
20435            final long nowElapsed = SystemClock.elapsedRealtime();
20436            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20437            long nextTime = 0;
20438            for (int i=mActiveUids.size()-1; i>=0; i--) {
20439                final UidRecord uidRec = mActiveUids.valueAt(i);
20440                final long bgTime = uidRec.lastBackgroundTime;
20441                if (bgTime > 0 && !uidRec.idle) {
20442                    if (bgTime <= maxBgTime) {
20443                        uidRec.idle = true;
20444                        doStopUidLocked(uidRec.uid, uidRec);
20445                    } else {
20446                        if (nextTime == 0 || nextTime > bgTime) {
20447                            nextTime = bgTime;
20448                        }
20449                    }
20450                }
20451            }
20452            if (nextTime > 0) {
20453                mHandler.removeMessages(IDLE_UIDS_MSG);
20454                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20455                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20456            }
20457        }
20458    }
20459
20460    final void runInBackgroundDisabled(int uid) {
20461        synchronized (this) {
20462            UidRecord uidRec = mActiveUids.get(uid);
20463            if (uidRec != null) {
20464                // This uid is actually running...  should it be considered background now?
20465                if (uidRec.idle) {
20466                    doStopUidLocked(uidRec.uid, uidRec);
20467                }
20468            } else {
20469                // This uid isn't actually running...  still send a report about it being "stopped".
20470                doStopUidLocked(uid, null);
20471            }
20472        }
20473    }
20474
20475    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20476        mServices.stopInBackgroundLocked(uid);
20477        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20478    }
20479
20480    final void trimApplications() {
20481        synchronized (this) {
20482            int i;
20483
20484            // First remove any unused application processes whose package
20485            // has been removed.
20486            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20487                final ProcessRecord app = mRemovedProcesses.get(i);
20488                if (app.activities.size() == 0
20489                        && app.curReceiver == null && app.services.size() == 0) {
20490                    Slog.i(
20491                        TAG, "Exiting empty application process "
20492                        + app.processName + " ("
20493                        + (app.thread != null ? app.thread.asBinder() : null)
20494                        + ")\n");
20495                    if (app.pid > 0 && app.pid != MY_PID) {
20496                        app.kill("empty", false);
20497                    } else {
20498                        try {
20499                            app.thread.scheduleExit();
20500                        } catch (Exception e) {
20501                            // Ignore exceptions.
20502                        }
20503                    }
20504                    cleanUpApplicationRecordLocked(app, false, true, -1);
20505                    mRemovedProcesses.remove(i);
20506
20507                    if (app.persistent) {
20508                        addAppLocked(app.info, false, null /* ABI override */);
20509                    }
20510                }
20511            }
20512
20513            // Now update the oom adj for all processes.
20514            updateOomAdjLocked();
20515        }
20516    }
20517
20518    /** This method sends the specified signal to each of the persistent apps */
20519    public void signalPersistentProcesses(int sig) throws RemoteException {
20520        if (sig != Process.SIGNAL_USR1) {
20521            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20522        }
20523
20524        synchronized (this) {
20525            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20526                    != PackageManager.PERMISSION_GRANTED) {
20527                throw new SecurityException("Requires permission "
20528                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20529            }
20530
20531            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20532                ProcessRecord r = mLruProcesses.get(i);
20533                if (r.thread != null && r.persistent) {
20534                    Process.sendSignal(r.pid, sig);
20535                }
20536            }
20537        }
20538    }
20539
20540    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20541        if (proc == null || proc == mProfileProc) {
20542            proc = mProfileProc;
20543            profileType = mProfileType;
20544            clearProfilerLocked();
20545        }
20546        if (proc == null) {
20547            return;
20548        }
20549        try {
20550            proc.thread.profilerControl(false, null, profileType);
20551        } catch (RemoteException e) {
20552            throw new IllegalStateException("Process disappeared");
20553        }
20554    }
20555
20556    private void clearProfilerLocked() {
20557        if (mProfileFd != null) {
20558            try {
20559                mProfileFd.close();
20560            } catch (IOException e) {
20561            }
20562        }
20563        mProfileApp = null;
20564        mProfileProc = null;
20565        mProfileFile = null;
20566        mProfileType = 0;
20567        mAutoStopProfiler = false;
20568        mSamplingInterval = 0;
20569    }
20570
20571    public boolean profileControl(String process, int userId, boolean start,
20572            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20573
20574        try {
20575            synchronized (this) {
20576                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20577                // its own permission.
20578                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20579                        != PackageManager.PERMISSION_GRANTED) {
20580                    throw new SecurityException("Requires permission "
20581                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20582                }
20583
20584                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20585                    throw new IllegalArgumentException("null profile info or fd");
20586                }
20587
20588                ProcessRecord proc = null;
20589                if (process != null) {
20590                    proc = findProcessLocked(process, userId, "profileControl");
20591                }
20592
20593                if (start && (proc == null || proc.thread == null)) {
20594                    throw new IllegalArgumentException("Unknown process: " + process);
20595                }
20596
20597                if (start) {
20598                    stopProfilerLocked(null, 0);
20599                    setProfileApp(proc.info, proc.processName, profilerInfo);
20600                    mProfileProc = proc;
20601                    mProfileType = profileType;
20602                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20603                    try {
20604                        fd = fd.dup();
20605                    } catch (IOException e) {
20606                        fd = null;
20607                    }
20608                    profilerInfo.profileFd = fd;
20609                    proc.thread.profilerControl(start, profilerInfo, profileType);
20610                    fd = null;
20611                    mProfileFd = null;
20612                } else {
20613                    stopProfilerLocked(proc, profileType);
20614                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20615                        try {
20616                            profilerInfo.profileFd.close();
20617                        } catch (IOException e) {
20618                        }
20619                    }
20620                }
20621
20622                return true;
20623            }
20624        } catch (RemoteException e) {
20625            throw new IllegalStateException("Process disappeared");
20626        } finally {
20627            if (profilerInfo != null && profilerInfo.profileFd != null) {
20628                try {
20629                    profilerInfo.profileFd.close();
20630                } catch (IOException e) {
20631                }
20632            }
20633        }
20634    }
20635
20636    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20637        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20638                userId, true, ALLOW_FULL_ONLY, callName, null);
20639        ProcessRecord proc = null;
20640        try {
20641            int pid = Integer.parseInt(process);
20642            synchronized (mPidsSelfLocked) {
20643                proc = mPidsSelfLocked.get(pid);
20644            }
20645        } catch (NumberFormatException e) {
20646        }
20647
20648        if (proc == null) {
20649            ArrayMap<String, SparseArray<ProcessRecord>> all
20650                    = mProcessNames.getMap();
20651            SparseArray<ProcessRecord> procs = all.get(process);
20652            if (procs != null && procs.size() > 0) {
20653                proc = procs.valueAt(0);
20654                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20655                    for (int i=1; i<procs.size(); i++) {
20656                        ProcessRecord thisProc = procs.valueAt(i);
20657                        if (thisProc.userId == userId) {
20658                            proc = thisProc;
20659                            break;
20660                        }
20661                    }
20662                }
20663            }
20664        }
20665
20666        return proc;
20667    }
20668
20669    public boolean dumpHeap(String process, int userId, boolean managed,
20670            String path, ParcelFileDescriptor fd) throws RemoteException {
20671
20672        try {
20673            synchronized (this) {
20674                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20675                // its own permission (same as profileControl).
20676                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20677                        != PackageManager.PERMISSION_GRANTED) {
20678                    throw new SecurityException("Requires permission "
20679                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20680                }
20681
20682                if (fd == null) {
20683                    throw new IllegalArgumentException("null fd");
20684                }
20685
20686                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20687                if (proc == null || proc.thread == null) {
20688                    throw new IllegalArgumentException("Unknown process: " + process);
20689                }
20690
20691                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20692                if (!isDebuggable) {
20693                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20694                        throw new SecurityException("Process not debuggable: " + proc);
20695                    }
20696                }
20697
20698                proc.thread.dumpHeap(managed, path, fd);
20699                fd = null;
20700                return true;
20701            }
20702        } catch (RemoteException e) {
20703            throw new IllegalStateException("Process disappeared");
20704        } finally {
20705            if (fd != null) {
20706                try {
20707                    fd.close();
20708                } catch (IOException e) {
20709                }
20710            }
20711        }
20712    }
20713
20714    @Override
20715    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20716            String reportPackage) {
20717        if (processName != null) {
20718            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20719                    "setDumpHeapDebugLimit()");
20720        } else {
20721            synchronized (mPidsSelfLocked) {
20722                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20723                if (proc == null) {
20724                    throw new SecurityException("No process found for calling pid "
20725                            + Binder.getCallingPid());
20726                }
20727                if (!Build.IS_DEBUGGABLE
20728                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20729                    throw new SecurityException("Not running a debuggable build");
20730                }
20731                processName = proc.processName;
20732                uid = proc.uid;
20733                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20734                    throw new SecurityException("Package " + reportPackage + " is not running in "
20735                            + proc);
20736                }
20737            }
20738        }
20739        synchronized (this) {
20740            if (maxMemSize > 0) {
20741                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20742            } else {
20743                if (uid != 0) {
20744                    mMemWatchProcesses.remove(processName, uid);
20745                } else {
20746                    mMemWatchProcesses.getMap().remove(processName);
20747                }
20748            }
20749        }
20750    }
20751
20752    @Override
20753    public void dumpHeapFinished(String path) {
20754        synchronized (this) {
20755            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20756                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20757                        + " does not match last pid " + mMemWatchDumpPid);
20758                return;
20759            }
20760            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20761                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20762                        + " does not match last path " + mMemWatchDumpFile);
20763                return;
20764            }
20765            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20766            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20767        }
20768    }
20769
20770    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20771    public void monitor() {
20772        synchronized (this) { }
20773    }
20774
20775    void onCoreSettingsChange(Bundle settings) {
20776        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20777            ProcessRecord processRecord = mLruProcesses.get(i);
20778            try {
20779                if (processRecord.thread != null) {
20780                    processRecord.thread.setCoreSettings(settings);
20781                }
20782            } catch (RemoteException re) {
20783                /* ignore */
20784            }
20785        }
20786    }
20787
20788    // Multi-user methods
20789
20790    /**
20791     * Start user, if its not already running, but don't bring it to foreground.
20792     */
20793    @Override
20794    public boolean startUserInBackground(final int userId) {
20795        return mUserController.startUser(userId, /* foreground */ false);
20796    }
20797
20798    @Override
20799    public boolean unlockUser(int userId, byte[] token) {
20800        return mUserController.unlockUser(userId, token);
20801    }
20802
20803    @Override
20804    public boolean switchUser(final int targetUserId) {
20805        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20806        UserInfo currentUserInfo;
20807        UserInfo targetUserInfo;
20808        synchronized (this) {
20809            int currentUserId = mUserController.getCurrentUserIdLocked();
20810            currentUserInfo = mUserController.getUserInfo(currentUserId);
20811            targetUserInfo = mUserController.getUserInfo(targetUserId);
20812            if (targetUserInfo == null) {
20813                Slog.w(TAG, "No user info for user #" + targetUserId);
20814                return false;
20815            }
20816            if (targetUserInfo.isManagedProfile()) {
20817                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20818                return false;
20819            }
20820            mUserController.setTargetUserIdLocked(targetUserId);
20821        }
20822        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20823        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20824        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20825        return true;
20826    }
20827
20828    void scheduleStartProfilesLocked() {
20829        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20830            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20831                    DateUtils.SECOND_IN_MILLIS);
20832        }
20833    }
20834
20835    @Override
20836    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20837        return mUserController.stopUser(userId, force, callback);
20838    }
20839
20840    @Override
20841    public UserInfo getCurrentUser() {
20842        return mUserController.getCurrentUser();
20843    }
20844
20845    @Override
20846    public boolean isUserRunning(int userId, int flags) {
20847        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20848                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20849            String msg = "Permission Denial: isUserRunning() from pid="
20850                    + Binder.getCallingPid()
20851                    + ", uid=" + Binder.getCallingUid()
20852                    + " requires " + INTERACT_ACROSS_USERS;
20853            Slog.w(TAG, msg);
20854            throw new SecurityException(msg);
20855        }
20856        synchronized (this) {
20857            return mUserController.isUserRunningLocked(userId, flags);
20858        }
20859    }
20860
20861    @Override
20862    public int[] getRunningUserIds() {
20863        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20864                != PackageManager.PERMISSION_GRANTED) {
20865            String msg = "Permission Denial: isUserRunning() from pid="
20866                    + Binder.getCallingPid()
20867                    + ", uid=" + Binder.getCallingUid()
20868                    + " requires " + INTERACT_ACROSS_USERS;
20869            Slog.w(TAG, msg);
20870            throw new SecurityException(msg);
20871        }
20872        synchronized (this) {
20873            return mUserController.getStartedUserArrayLocked();
20874        }
20875    }
20876
20877    @Override
20878    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20879        mUserController.registerUserSwitchObserver(observer);
20880    }
20881
20882    @Override
20883    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20884        mUserController.unregisterUserSwitchObserver(observer);
20885    }
20886
20887    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20888        if (info == null) return null;
20889        ApplicationInfo newInfo = new ApplicationInfo(info);
20890        newInfo.initForUser(userId);
20891        return newInfo;
20892    }
20893
20894    public boolean isUserStopped(int userId) {
20895        return mUserController.getStartedUserStateLocked(userId) == null;
20896    }
20897
20898    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20899        if (aInfo == null
20900                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20901            return aInfo;
20902        }
20903
20904        ActivityInfo info = new ActivityInfo(aInfo);
20905        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20906        return info;
20907    }
20908
20909    private boolean processSanityChecksLocked(ProcessRecord process) {
20910        if (process == null || process.thread == null) {
20911            return false;
20912        }
20913
20914        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20915        if (!isDebuggable) {
20916            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20917                return false;
20918            }
20919        }
20920
20921        return true;
20922    }
20923
20924    public boolean startBinderTracking() throws RemoteException {
20925        synchronized (this) {
20926            mBinderTransactionTrackingEnabled = true;
20927            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20928            // permission (same as profileControl).
20929            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20930                    != PackageManager.PERMISSION_GRANTED) {
20931                throw new SecurityException("Requires permission "
20932                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20933            }
20934
20935            for (int i = 0; i < mLruProcesses.size(); i++) {
20936                ProcessRecord process = mLruProcesses.get(i);
20937                if (!processSanityChecksLocked(process)) {
20938                    continue;
20939                }
20940                try {
20941                    process.thread.startBinderTracking();
20942                } catch (RemoteException e) {
20943                    Log.v(TAG, "Process disappared");
20944                }
20945            }
20946            return true;
20947        }
20948    }
20949
20950    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20951        try {
20952            synchronized (this) {
20953                mBinderTransactionTrackingEnabled = false;
20954                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20955                // permission (same as profileControl).
20956                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20957                        != PackageManager.PERMISSION_GRANTED) {
20958                    throw new SecurityException("Requires permission "
20959                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20960                }
20961
20962                if (fd == null) {
20963                    throw new IllegalArgumentException("null fd");
20964                }
20965
20966                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20967                pw.println("Binder transaction traces for all processes.\n");
20968                for (ProcessRecord process : mLruProcesses) {
20969                    if (!processSanityChecksLocked(process)) {
20970                        continue;
20971                    }
20972
20973                    pw.println("Traces for process: " + process.processName);
20974                    pw.flush();
20975                    try {
20976                        TransferPipe tp = new TransferPipe();
20977                        try {
20978                            process.thread.stopBinderTrackingAndDump(
20979                                    tp.getWriteFd().getFileDescriptor());
20980                            tp.go(fd.getFileDescriptor());
20981                        } finally {
20982                            tp.kill();
20983                        }
20984                    } catch (IOException e) {
20985                        pw.println("Failure while dumping IPC traces from " + process +
20986                                ".  Exception: " + e);
20987                        pw.flush();
20988                    } catch (RemoteException e) {
20989                        pw.println("Got a RemoteException while dumping IPC traces from " +
20990                                process + ".  Exception: " + e);
20991                        pw.flush();
20992                    }
20993                }
20994                fd = null;
20995                return true;
20996            }
20997        } finally {
20998            if (fd != null) {
20999                try {
21000                    fd.close();
21001                } catch (IOException e) {
21002                }
21003            }
21004        }
21005    }
21006
21007    void stopReportingCrashesLocked(ProcessRecord proc) {
21008        if (mAppsNotReportingCrashes == null) {
21009            mAppsNotReportingCrashes = new ArraySet<>();
21010        }
21011        mAppsNotReportingCrashes.add(proc.info.packageName);
21012    }
21013
21014    private final class LocalService extends ActivityManagerInternal {
21015        @Override
21016        public void onWakefulnessChanged(int wakefulness) {
21017            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21018        }
21019
21020        @Override
21021        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21022                String processName, String abiOverride, int uid, Runnable crashHandler) {
21023            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21024                    processName, abiOverride, uid, crashHandler);
21025        }
21026
21027        @Override
21028        public SleepToken acquireSleepToken(String tag) {
21029            Preconditions.checkNotNull(tag);
21030
21031            synchronized (ActivityManagerService.this) {
21032                SleepTokenImpl token = new SleepTokenImpl(tag);
21033                mSleepTokens.add(token);
21034                updateSleepIfNeededLocked();
21035                return token;
21036            }
21037        }
21038
21039        @Override
21040        public ComponentName getHomeActivityForUser(int userId) {
21041            synchronized (ActivityManagerService.this) {
21042                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21043                return homeActivity == null ? null : homeActivity.realActivity;
21044            }
21045        }
21046
21047        @Override
21048        public void onUserRemoved(int userId) {
21049            synchronized (ActivityManagerService.this) {
21050                ActivityManagerService.this.onUserStoppedLocked(userId);
21051            }
21052        }
21053    }
21054
21055    private final class SleepTokenImpl extends SleepToken {
21056        private final String mTag;
21057        private final long mAcquireTime;
21058
21059        public SleepTokenImpl(String tag) {
21060            mTag = tag;
21061            mAcquireTime = SystemClock.uptimeMillis();
21062        }
21063
21064        @Override
21065        public void release() {
21066            synchronized (ActivityManagerService.this) {
21067                if (mSleepTokens.remove(this)) {
21068                    updateSleepIfNeededLocked();
21069                }
21070            }
21071        }
21072
21073        @Override
21074        public String toString() {
21075            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21076        }
21077    }
21078
21079    /**
21080     * An implementation of IAppTask, that allows an app to manage its own tasks via
21081     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21082     * only the process that calls getAppTasks() can call the AppTask methods.
21083     */
21084    class AppTaskImpl extends IAppTask.Stub {
21085        private int mTaskId;
21086        private int mCallingUid;
21087
21088        public AppTaskImpl(int taskId, int callingUid) {
21089            mTaskId = taskId;
21090            mCallingUid = callingUid;
21091        }
21092
21093        private void checkCaller() {
21094            if (mCallingUid != Binder.getCallingUid()) {
21095                throw new SecurityException("Caller " + mCallingUid
21096                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21097            }
21098        }
21099
21100        @Override
21101        public void finishAndRemoveTask() {
21102            checkCaller();
21103
21104            synchronized (ActivityManagerService.this) {
21105                long origId = Binder.clearCallingIdentity();
21106                try {
21107                    // We remove the task from recents to preserve backwards
21108                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21109                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21110                    }
21111                } finally {
21112                    Binder.restoreCallingIdentity(origId);
21113                }
21114            }
21115        }
21116
21117        @Override
21118        public ActivityManager.RecentTaskInfo getTaskInfo() {
21119            checkCaller();
21120
21121            synchronized (ActivityManagerService.this) {
21122                long origId = Binder.clearCallingIdentity();
21123                try {
21124                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21125                    if (tr == null) {
21126                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21127                    }
21128                    return createRecentTaskInfoFromTaskRecord(tr);
21129                } finally {
21130                    Binder.restoreCallingIdentity(origId);
21131                }
21132            }
21133        }
21134
21135        @Override
21136        public void moveToFront() {
21137            checkCaller();
21138            // Will bring task to front if it already has a root activity.
21139            startActivityFromRecentsInner(mTaskId, null);
21140        }
21141
21142        @Override
21143        public int startActivity(IBinder whoThread, String callingPackage,
21144                Intent intent, String resolvedType, Bundle bOptions) {
21145            checkCaller();
21146
21147            int callingUser = UserHandle.getCallingUserId();
21148            TaskRecord tr;
21149            IApplicationThread appThread;
21150            synchronized (ActivityManagerService.this) {
21151                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21152                if (tr == null) {
21153                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21154                }
21155                appThread = ApplicationThreadNative.asInterface(whoThread);
21156                if (appThread == null) {
21157                    throw new IllegalArgumentException("Bad app thread " + appThread);
21158                }
21159            }
21160            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21161                    resolvedType, null, null, null, null, 0, 0, null, null,
21162                    null, bOptions, false, callingUser, null, tr);
21163        }
21164
21165        @Override
21166        public void setExcludeFromRecents(boolean exclude) {
21167            checkCaller();
21168
21169            synchronized (ActivityManagerService.this) {
21170                long origId = Binder.clearCallingIdentity();
21171                try {
21172                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21173                    if (tr == null) {
21174                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21175                    }
21176                    Intent intent = tr.getBaseIntent();
21177                    if (exclude) {
21178                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21179                    } else {
21180                        intent.setFlags(intent.getFlags()
21181                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21182                    }
21183                } finally {
21184                    Binder.restoreCallingIdentity(origId);
21185                }
21186            }
21187        }
21188    }
21189
21190    /**
21191     * Kill processes for the user with id userId and that depend on the package named packageName
21192     */
21193    @Override
21194    public void killPackageDependents(String packageName, int userId) {
21195        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21196        if (packageName == null) {
21197            throw new NullPointerException(
21198                    "Cannot kill the dependents of a package without its name.");
21199        }
21200
21201        long callingId = Binder.clearCallingIdentity();
21202        IPackageManager pm = AppGlobals.getPackageManager();
21203        int pkgUid = -1;
21204        try {
21205            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21206        } catch (RemoteException e) {
21207        }
21208        if (pkgUid == -1) {
21209            throw new IllegalArgumentException(
21210                    "Cannot kill dependents of non-existing package " + packageName);
21211        }
21212        try {
21213            synchronized(this) {
21214                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21215                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21216                        "dep: " + packageName);
21217            }
21218        } finally {
21219            Binder.restoreCallingIdentity(callingId);
21220        }
21221    }
21222}
21223