ActivityManagerService.java revision 3716e52be592482534943d32ba0f72309305a224
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.LockGuard;
49import com.android.server.ServiceThread;
50import com.android.server.SystemService;
51import com.android.server.SystemServiceManager;
52import com.android.server.Watchdog;
53import com.android.server.am.ActivityStack.ActivityState;
54import com.android.server.firewall.IntentFirewall;
55import com.android.server.pm.Installer;
56import com.android.server.statusbar.StatusBarManagerInternal;
57import com.android.server.vr.VrManagerInternal;
58import com.android.server.wm.AppTransition;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.app.Activity;
67import android.app.ActivityManager;
68import android.app.ActivityManager.RunningTaskInfo;
69import android.app.ActivityManager.StackId;
70import android.app.ActivityManager.StackInfo;
71import android.app.ActivityManager.TaskThumbnailInfo;
72import android.app.ActivityManagerInternal;
73import android.app.ActivityManagerInternal.SleepToken;
74import android.app.ActivityManagerNative;
75import android.app.ActivityOptions;
76import android.app.ActivityThread;
77import android.app.AlertDialog;
78import android.app.AppGlobals;
79import android.app.AppOpsManager;
80import android.app.ApplicationErrorReport;
81import android.app.ApplicationThreadNative;
82import android.app.BroadcastOptions;
83import android.app.Dialog;
84import android.app.IActivityContainer;
85import android.app.IActivityContainerCallback;
86import android.app.IActivityController;
87import android.app.IAppTask;
88import android.app.IApplicationThread;
89import android.app.IInstrumentationWatcher;
90import android.app.INotificationManager;
91import android.app.IProcessObserver;
92import android.app.IServiceConnection;
93import android.app.IStopUserCallback;
94import android.app.ITaskStackListener;
95import android.app.IUiAutomationConnection;
96import android.app.IUidObserver;
97import android.app.IUserSwitchObserver;
98import android.app.Instrumentation;
99import android.app.Notification;
100import android.app.NotificationManager;
101import android.app.PendingIntent;
102import android.app.ProfilerInfo;
103import android.app.admin.DevicePolicyManager;
104import android.app.assist.AssistContent;
105import android.app.assist.AssistStructure;
106import android.app.backup.IBackupManager;
107import android.app.usage.UsageEvents;
108import android.app.usage.UsageStatsManagerInternal;
109import android.appwidget.AppWidgetManager;
110import android.content.ActivityNotFoundException;
111import android.content.BroadcastReceiver;
112import android.content.ClipData;
113import android.content.ComponentCallbacks2;
114import android.content.ComponentName;
115import android.content.ContentProvider;
116import android.content.ContentResolver;
117import android.content.Context;
118import android.content.DialogInterface;
119import android.content.IContentProvider;
120import android.content.IIntentReceiver;
121import android.content.IIntentSender;
122import android.content.Intent;
123import android.content.IntentFilter;
124import android.content.IntentSender;
125import android.content.pm.ActivityInfo;
126import android.content.pm.ApplicationInfo;
127import android.content.pm.ConfigurationInfo;
128import android.content.pm.IPackageDataObserver;
129import android.content.pm.IPackageManager;
130import android.content.pm.InstrumentationInfo;
131import android.content.pm.PackageInfo;
132import android.content.pm.PackageManager;
133import android.content.pm.PackageManager.NameNotFoundException;
134import android.content.pm.PackageManagerInternal;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.PathPermission;
137import android.content.pm.PermissionInfo;
138import android.content.pm.ProviderInfo;
139import android.content.pm.ResolveInfo;
140import android.content.pm.ServiceInfo;
141import android.content.pm.UserInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.content.res.Resources;
145import android.database.ContentObserver;
146import android.graphics.Bitmap;
147import android.graphics.Point;
148import android.graphics.Rect;
149import android.location.LocationManager;
150import android.net.Proxy;
151import android.net.ProxyInfo;
152import android.net.Uri;
153import android.os.BatteryStats;
154import android.os.Binder;
155import android.os.Build;
156import android.os.Bundle;
157import android.os.Debug;
158import android.os.DropBoxManager;
159import android.os.Environment;
160import android.os.FactoryTest;
161import android.os.FileObserver;
162import android.os.FileUtils;
163import android.os.Handler;
164import android.os.IBinder;
165import android.os.IPermissionController;
166import android.os.IProcessInfoService;
167import android.os.Looper;
168import android.os.Message;
169import android.os.Parcel;
170import android.os.ParcelFileDescriptor;
171import android.os.PersistableBundle;
172import android.os.PowerManager;
173import android.os.PowerManagerInternal;
174import android.os.Process;
175import android.os.RemoteCallbackList;
176import android.os.RemoteException;
177import android.os.ResultReceiver;
178import android.os.ServiceManager;
179import android.os.StrictMode;
180import android.os.SystemClock;
181import android.os.SystemProperties;
182import android.os.Trace;
183import android.os.TransactionTooLargeException;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.os.WorkSource;
188import android.os.storage.IMountService;
189import android.os.storage.MountServiceInternal;
190import android.os.storage.StorageManager;
191import android.provider.Settings;
192import android.service.voice.IVoiceInteractionSession;
193import android.service.voice.VoiceInteractionManagerInternal;
194import android.service.voice.VoiceInteractionSession;
195import android.text.format.DateUtils;
196import android.text.format.Time;
197import android.util.ArrayMap;
198import android.util.ArraySet;
199import android.util.AtomicFile;
200import android.util.DebugUtils;
201import android.util.EventLog;
202import android.util.LocaleList;
203import android.util.Log;
204import android.util.Pair;
205import android.util.PrintWriterPrinter;
206import android.util.Slog;
207import android.util.SparseArray;
208import android.util.TimeUtils;
209import android.util.Xml;
210import android.view.Display;
211import android.view.Gravity;
212import android.view.LayoutInflater;
213import android.view.View;
214import android.view.WindowManager;
215
216import java.io.BufferedInputStream;
217import java.io.BufferedOutputStream;
218import java.io.DataInputStream;
219import java.io.DataOutputStream;
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
341import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
343import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
344import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
345import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
346import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
347import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
348import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
352import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
353import static org.xmlpull.v1.XmlPullParser.START_TAG;
354
355public final class ActivityManagerService extends ActivityManagerNative
356        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
357
358    // File that stores last updated system version and called preboot receivers
359    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
360
361    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
362    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
363    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
364    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
365    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
366    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
367    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
368    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
369    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
370    private static final String TAG_LRU = TAG + POSTFIX_LRU;
371    private static final String TAG_MU = TAG + POSTFIX_MU;
372    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
373    private static final String TAG_POWER = TAG + POSTFIX_POWER;
374    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
375    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
376    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
377    private static final String TAG_PSS = TAG + POSTFIX_PSS;
378    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
379    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
380    private static final String TAG_STACK = TAG + POSTFIX_STACK;
381    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
382    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
383    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
384    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
385    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
386
387    /** Control over CPU and battery monitoring */
388    // write battery stats every 30 minutes.
389    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
390    static final boolean MONITOR_CPU_USAGE = true;
391    // don't sample cpu less than every 5 seconds.
392    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
393    // wait possibly forever for next cpu sample.
394    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
395    static final boolean MONITOR_THREAD_CPU_USAGE = false;
396
397    // The flags that are set for all calls we make to the package manager.
398    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
399
400    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
401
402    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
403
404    // Amount of time after a call to stopAppSwitches() during which we will
405    // prevent further untrusted switches from happening.
406    static final long APP_SWITCH_DELAY_TIME = 5*1000;
407
408    // How long we wait for a launched process to attach to the activity manager
409    // before we decide it's never going to come up for real.
410    static final int PROC_START_TIMEOUT = 10*1000;
411    // How long we wait for an attached process to publish its content providers
412    // before we decide it must be hung.
413    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
414
415    // How long we will retain processes hosting content providers in the "last activity"
416    // state before allowing them to drop down to the regular cached LRU list.  This is
417    // to avoid thrashing of provider processes under low memory situations.
418    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
419
420    // How long we wait for a launched process to attach to the activity manager
421    // before we decide it's never going to come up for real, when the process was
422    // started with a wrapper for instrumentation (such as Valgrind) because it
423    // could take much longer than usual.
424    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
425
426    // How long to wait after going idle before forcing apps to GC.
427    static final int GC_TIMEOUT = 5*1000;
428
429    // The minimum amount of time between successive GC requests for a process.
430    static final int GC_MIN_INTERVAL = 60*1000;
431
432    // The minimum amount of time between successive PSS requests for a process.
433    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
434
435    // The minimum amount of time between successive PSS requests for a process
436    // when the request is due to the memory state being lowered.
437    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
438
439    // The rate at which we check for apps using excessive power -- 15 mins.
440    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
441
442    // The minimum sample duration we will allow before deciding we have
443    // enough data on wake locks to start killing things.
444    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
445
446    // The minimum sample duration we will allow before deciding we have
447    // enough data on CPU usage to start killing things.
448    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
449
450    // How long we allow a receiver to run before giving up on it.
451    static final int BROADCAST_FG_TIMEOUT = 10*1000;
452    static final int BROADCAST_BG_TIMEOUT = 60*1000;
453
454    // How long we wait until we timeout on key dispatching.
455    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
456
457    // How long we wait until we timeout on key dispatching during instrumentation.
458    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
459
460    // This is the amount of time an app needs to be running a foreground service before
461    // we will consider it to be doing interaction for usage stats.
462    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
463
464    // Maximum amount of time we will allow to elapse before re-reporting usage stats
465    // interaction with foreground processes.
466    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
467
468    // This is the amount of time we allow an app to settle after it goes into the background,
469    // before we start restricting what it can do.
470    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
471
472    // How long to wait in getAssistContextExtras for the activity and foreground services
473    // to respond with the result.
474    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
475
476    // How long top wait when going through the modern assist (which doesn't need to block
477    // on getting this result before starting to launch its UI).
478    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
479
480    // Maximum number of persisted Uri grants a package is allowed
481    static final int MAX_PERSISTED_URI_GRANTS = 128;
482
483    static final int MY_PID = Process.myPid();
484
485    static final String[] EMPTY_STRING_ARRAY = new String[0];
486
487    // How many bytes to write into the dropbox log before truncating
488    static final int DROPBOX_MAX_SIZE = 256 * 1024;
489
490    // Access modes for handleIncomingUser.
491    static final int ALLOW_NON_FULL = 0;
492    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
493    static final int ALLOW_FULL_ONLY = 2;
494
495    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
496
497    // Delay in notifying task stack change listeners (in millis)
498    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
499
500    // Necessary ApplicationInfo flags to mark an app as persistent
501    private static final int PERSISTENT_MASK =
502            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
503
504    // Intent sent when remote bugreport collection has been completed
505    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
506            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
507
508    // Delay to disable app launch boost
509    static final int APP_BOOST_MESSAGE_DELAY = 3000;
510    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
511    static final int APP_BOOST_TIMEOUT = 2500;
512
513    // Used to indicate that a task is removed it should also be removed from recents.
514    private static final boolean REMOVE_FROM_RECENTS = true;
515    // Used to indicate that an app transition should be animated.
516    static final boolean ANIMATE = true;
517
518    // Determines whether to take full screen screenshots
519    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
520
521    private static native int nativeMigrateToBoost();
522    private static native int nativeMigrateFromBoost();
523    private boolean mIsBoosted = false;
524    private long mBoostStartTime = 0;
525
526    /** All system services */
527    SystemServiceManager mSystemServiceManager;
528
529    private Installer mInstaller;
530
531    /** Run all ActivityStacks through this */
532    final ActivityStackSupervisor mStackSupervisor;
533
534    final ActivityStarter mActivityStarter;
535
536    /** Task stack change listeners. */
537    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
538            new RemoteCallbackList<ITaskStackListener>();
539
540    public IntentFirewall mIntentFirewall;
541
542    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
543    // default actuion automatically.  Important for devices without direct input
544    // devices.
545    private boolean mShowDialogs = true;
546    private boolean mInVrMode = false;
547
548    BroadcastQueue mFgBroadcastQueue;
549    BroadcastQueue mBgBroadcastQueue;
550    // Convenient for easy iteration over the queues. Foreground is first
551    // so that dispatch of foreground broadcasts gets precedence.
552    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
553
554    BroadcastQueue broadcastQueueForIntent(Intent intent) {
555        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
556        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
557                "Broadcast intent " + intent + " on "
558                + (isFg ? "foreground" : "background") + " queue");
559        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
560    }
561
562    /**
563     * Activity we have told the window manager to have key focus.
564     */
565    ActivityRecord mFocusedActivity = null;
566
567    /**
568     * User id of the last activity mFocusedActivity was set to.
569     */
570    private int mLastFocusedUserId;
571
572    /**
573     * If non-null, we are tracking the time the user spends in the currently focused app.
574     */
575    private AppTimeTracker mCurAppTimeTracker;
576
577    /**
578     * List of intents that were used to start the most recent tasks.
579     */
580    final RecentTasks mRecentTasks;
581
582    /**
583     * For addAppTask: cached of the last activity component that was added.
584     */
585    ComponentName mLastAddedTaskComponent;
586
587    /**
588     * For addAppTask: cached of the last activity uid that was added.
589     */
590    int mLastAddedTaskUid;
591
592    /**
593     * For addAppTask: cached of the last ActivityInfo that was added.
594     */
595    ActivityInfo mLastAddedTaskActivity;
596
597    /**
598     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
599     */
600    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
601
602    /**
603     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
604     */
605    String mDeviceOwnerName;
606
607    final UserController mUserController;
608
609    final AppErrors mAppErrors;
610
611    boolean mDoingSetFocusedActivity;
612
613    public boolean canShowErrorDialogs() {
614        return mShowDialogs && !mSleeping && !mShuttingDown;
615    }
616
617    public class PendingAssistExtras extends Binder implements Runnable {
618        public final ActivityRecord activity;
619        public final Bundle extras;
620        public final Intent intent;
621        public final String hint;
622        public final IResultReceiver receiver;
623        public final int userHandle;
624        public boolean haveResult = false;
625        public Bundle result = null;
626        public AssistStructure structure = null;
627        public AssistContent content = null;
628        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
629                String _hint, IResultReceiver _receiver, int _userHandle) {
630            activity = _activity;
631            extras = _extras;
632            intent = _intent;
633            hint = _hint;
634            receiver = _receiver;
635            userHandle = _userHandle;
636        }
637        @Override
638        public void run() {
639            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
640            synchronized (this) {
641                haveResult = true;
642                notifyAll();
643            }
644            pendingAssistExtrasTimedOut(this);
645        }
646    }
647
648    final ArrayList<PendingAssistExtras> mPendingAssistExtras
649            = new ArrayList<PendingAssistExtras>();
650
651    /**
652     * Process management.
653     */
654    final ProcessList mProcessList = new ProcessList();
655
656    /**
657     * All of the applications we currently have running organized by name.
658     * The keys are strings of the application package name (as
659     * returned by the package manager), and the keys are ApplicationRecord
660     * objects.
661     */
662    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
663
664    /**
665     * Tracking long-term execution of processes to look for abuse and other
666     * bad app behavior.
667     */
668    final ProcessStatsService mProcessStats;
669
670    /**
671     * The currently running isolated processes.
672     */
673    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
674
675    /**
676     * Counter for assigning isolated process uids, to avoid frequently reusing the
677     * same ones.
678     */
679    int mNextIsolatedProcessUid = 0;
680
681    /**
682     * The currently running heavy-weight process, if any.
683     */
684    ProcessRecord mHeavyWeightProcess = null;
685
686    /**
687     * All of the processes we currently have running organized by pid.
688     * The keys are the pid running the application.
689     *
690     * <p>NOTE: This object is protected by its own lock, NOT the global
691     * activity manager lock!
692     */
693    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
694
695    /**
696     * All of the processes that have been forced to be foreground.  The key
697     * is the pid of the caller who requested it (we hold a death
698     * link on it).
699     */
700    abstract class ForegroundToken implements IBinder.DeathRecipient {
701        int pid;
702        IBinder token;
703    }
704    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
705
706    /**
707     * List of records for processes that someone had tried to start before the
708     * system was ready.  We don't start them at that point, but ensure they
709     * are started by the time booting is complete.
710     */
711    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
712
713    /**
714     * List of persistent applications that are in the process
715     * of being started.
716     */
717    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
718
719    /**
720     * Processes that are being forcibly torn down.
721     */
722    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
723
724    /**
725     * List of running applications, sorted by recent usage.
726     * The first entry in the list is the least recently used.
727     */
728    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
729
730    /**
731     * Where in mLruProcesses that the processes hosting activities start.
732     */
733    int mLruProcessActivityStart = 0;
734
735    /**
736     * Where in mLruProcesses that the processes hosting services start.
737     * This is after (lower index) than mLruProcessesActivityStart.
738     */
739    int mLruProcessServiceStart = 0;
740
741    /**
742     * List of processes that should gc as soon as things are idle.
743     */
744    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
745
746    /**
747     * Processes we want to collect PSS data from.
748     */
749    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
750
751    private boolean mBinderTransactionTrackingEnabled = false;
752
753    /**
754     * Last time we requested PSS data of all processes.
755     */
756    long mLastFullPssTime = SystemClock.uptimeMillis();
757
758    /**
759     * If set, the next time we collect PSS data we should do a full collection
760     * with data from native processes and the kernel.
761     */
762    boolean mFullPssPending = false;
763
764    /**
765     * This is the process holding what we currently consider to be
766     * the "home" activity.
767     */
768    ProcessRecord mHomeProcess;
769
770    /**
771     * This is the process holding the activity the user last visited that
772     * is in a different process from the one they are currently in.
773     */
774    ProcessRecord mPreviousProcess;
775
776    /**
777     * The time at which the previous process was last visible.
778     */
779    long mPreviousProcessVisibleTime;
780
781    /**
782     * Track all uids that have actively running processes.
783     */
784    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
785
786    /**
787     * This is for verifying the UID report flow.
788     */
789    static final boolean VALIDATE_UID_STATES = true;
790    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
791
792    /**
793     * Packages that the user has asked to have run in screen size
794     * compatibility mode instead of filling the screen.
795     */
796    final CompatModePackages mCompatModePackages;
797
798    /**
799     * Set of IntentSenderRecord objects that are currently active.
800     */
801    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
802            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
803
804    /**
805     * Fingerprints (hashCode()) of stack traces that we've
806     * already logged DropBox entries for.  Guarded by itself.  If
807     * something (rogue user app) forces this over
808     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
809     */
810    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
811    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
812
813    /**
814     * Strict Mode background batched logging state.
815     *
816     * The string buffer is guarded by itself, and its lock is also
817     * used to determine if another batched write is already
818     * in-flight.
819     */
820    private final StringBuilder mStrictModeBuffer = new StringBuilder();
821
822    /**
823     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
824     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
825     */
826    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
827
828    /**
829     * Resolver for broadcast intents to registered receivers.
830     * Holds BroadcastFilter (subclass of IntentFilter).
831     */
832    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
833            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
834        @Override
835        protected boolean allowFilterResult(
836                BroadcastFilter filter, List<BroadcastFilter> dest) {
837            IBinder target = filter.receiverList.receiver.asBinder();
838            for (int i = dest.size() - 1; i >= 0; i--) {
839                if (dest.get(i).receiverList.receiver.asBinder() == target) {
840                    return false;
841                }
842            }
843            return true;
844        }
845
846        @Override
847        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
848            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
849                    || userId == filter.owningUserId) {
850                return super.newResult(filter, match, userId);
851            }
852            return null;
853        }
854
855        @Override
856        protected BroadcastFilter[] newArray(int size) {
857            return new BroadcastFilter[size];
858        }
859
860        @Override
861        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
862            return packageName.equals(filter.packageName);
863        }
864    };
865
866    /**
867     * State of all active sticky broadcasts per user.  Keys are the action of the
868     * sticky Intent, values are an ArrayList of all broadcasted intents with
869     * that action (which should usually be one).  The SparseArray is keyed
870     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
871     * for stickies that are sent to all users.
872     */
873    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
874            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
875
876    final ActiveServices mServices;
877
878    final static class Association {
879        final int mSourceUid;
880        final String mSourceProcess;
881        final int mTargetUid;
882        final ComponentName mTargetComponent;
883        final String mTargetProcess;
884
885        int mCount;
886        long mTime;
887
888        int mNesting;
889        long mStartTime;
890
891        Association(int sourceUid, String sourceProcess, int targetUid,
892                ComponentName targetComponent, String targetProcess) {
893            mSourceUid = sourceUid;
894            mSourceProcess = sourceProcess;
895            mTargetUid = targetUid;
896            mTargetComponent = targetComponent;
897            mTargetProcess = targetProcess;
898        }
899    }
900
901    /**
902     * When service association tracking is enabled, this is all of the associations we
903     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
904     * -> association data.
905     */
906    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
907            mAssociations = new SparseArray<>();
908    boolean mTrackingAssociations;
909
910    /**
911     * Backup/restore process management
912     */
913    String mBackupAppName = null;
914    BackupRecord mBackupTarget = null;
915
916    final ProviderMap mProviderMap;
917
918    /**
919     * List of content providers who have clients waiting for them.  The
920     * application is currently being launched and the provider will be
921     * removed from this list once it is published.
922     */
923    final ArrayList<ContentProviderRecord> mLaunchingProviders
924            = new ArrayList<ContentProviderRecord>();
925
926    /**
927     * File storing persisted {@link #mGrantedUriPermissions}.
928     */
929    private final AtomicFile mGrantFile;
930
931    /** XML constants used in {@link #mGrantFile} */
932    private static final String TAG_URI_GRANTS = "uri-grants";
933    private static final String TAG_URI_GRANT = "uri-grant";
934    private static final String ATTR_USER_HANDLE = "userHandle";
935    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
936    private static final String ATTR_TARGET_USER_ID = "targetUserId";
937    private static final String ATTR_SOURCE_PKG = "sourcePkg";
938    private static final String ATTR_TARGET_PKG = "targetPkg";
939    private static final String ATTR_URI = "uri";
940    private static final String ATTR_MODE_FLAGS = "modeFlags";
941    private static final String ATTR_CREATED_TIME = "createdTime";
942    private static final String ATTR_PREFIX = "prefix";
943
944    /**
945     * Global set of specific {@link Uri} permissions that have been granted.
946     * This optimized lookup structure maps from {@link UriPermission#targetUid}
947     * to {@link UriPermission#uri} to {@link UriPermission}.
948     */
949    @GuardedBy("this")
950    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
951            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
952
953    public static class GrantUri {
954        public final int sourceUserId;
955        public final Uri uri;
956        public boolean prefix;
957
958        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
959            this.sourceUserId = sourceUserId;
960            this.uri = uri;
961            this.prefix = prefix;
962        }
963
964        @Override
965        public int hashCode() {
966            int hashCode = 1;
967            hashCode = 31 * hashCode + sourceUserId;
968            hashCode = 31 * hashCode + uri.hashCode();
969            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
970            return hashCode;
971        }
972
973        @Override
974        public boolean equals(Object o) {
975            if (o instanceof GrantUri) {
976                GrantUri other = (GrantUri) o;
977                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
978                        && prefix == other.prefix;
979            }
980            return false;
981        }
982
983        @Override
984        public String toString() {
985            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
986            if (prefix) result += " [prefix]";
987            return result;
988        }
989
990        public String toSafeString() {
991            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
992            if (prefix) result += " [prefix]";
993            return result;
994        }
995
996        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
997            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
998                    ContentProvider.getUriWithoutUserId(uri), false);
999        }
1000    }
1001
1002    CoreSettingsObserver mCoreSettingsObserver;
1003
1004    FontScaleSettingObserver mFontScaleSettingObserver;
1005
1006    private final class FontScaleSettingObserver extends ContentObserver {
1007        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1008
1009        public FontScaleSettingObserver() {
1010            super(mHandler);
1011            ContentResolver resolver = mContext.getContentResolver();
1012            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1013        }
1014
1015        @Override
1016        public void onChange(boolean selfChange, Uri uri) {
1017            if (mFontScaleUri.equals(uri)) {
1018                updateFontScaleIfNeeded();
1019            }
1020        }
1021    }
1022
1023    /**
1024     * Thread-local storage used to carry caller permissions over through
1025     * indirect content-provider access.
1026     */
1027    private class Identity {
1028        public final IBinder token;
1029        public final int pid;
1030        public final int uid;
1031
1032        Identity(IBinder _token, int _pid, int _uid) {
1033            token = _token;
1034            pid = _pid;
1035            uid = _uid;
1036        }
1037    }
1038
1039    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1040
1041    /**
1042     * All information we have collected about the runtime performance of
1043     * any user id that can impact battery performance.
1044     */
1045    final BatteryStatsService mBatteryStatsService;
1046
1047    /**
1048     * Information about component usage
1049     */
1050    UsageStatsManagerInternal mUsageStatsService;
1051
1052    /**
1053     * Access to DeviceIdleController service.
1054     */
1055    DeviceIdleController.LocalService mLocalDeviceIdleController;
1056
1057    /**
1058     * Information about and control over application operations
1059     */
1060    final AppOpsService mAppOpsService;
1061
1062    /**
1063     * Current configuration information.  HistoryRecord objects are given
1064     * a reference to this object to indicate which configuration they are
1065     * currently running in, so this object must be kept immutable.
1066     */
1067    Configuration mConfiguration = new Configuration();
1068
1069    /**
1070     * Current sequencing integer of the configuration, for skipping old
1071     * configurations.
1072     */
1073    int mConfigurationSeq = 0;
1074
1075    boolean mSuppressResizeConfigChanges = false;
1076
1077    /**
1078     * Hardware-reported OpenGLES version.
1079     */
1080    final int GL_ES_VERSION;
1081
1082    /**
1083     * List of initialization arguments to pass to all processes when binding applications to them.
1084     * For example, references to the commonly used services.
1085     */
1086    HashMap<String, IBinder> mAppBindArgs;
1087
1088    /**
1089     * Temporary to avoid allocations.  Protected by main lock.
1090     */
1091    final StringBuilder mStringBuilder = new StringBuilder(256);
1092
1093    /**
1094     * Used to control how we initialize the service.
1095     */
1096    ComponentName mTopComponent;
1097    String mTopAction = Intent.ACTION_MAIN;
1098    String mTopData;
1099    boolean mProcessesReady = false;
1100    boolean mSystemReady = false;
1101    boolean mBooting = false;
1102    boolean mCallFinishBooting = false;
1103    boolean mBootAnimationComplete = false;
1104    boolean mWaitingUpdate = false;
1105    boolean mDidUpdate = false;
1106    boolean mOnBattery = false;
1107    boolean mLaunchWarningShown = false;
1108
1109    Context mContext;
1110
1111    int mFactoryTest;
1112
1113    boolean mCheckedForSetup;
1114
1115    /**
1116     * The time at which we will allow normal application switches again,
1117     * after a call to {@link #stopAppSwitches()}.
1118     */
1119    long mAppSwitchesAllowedTime;
1120
1121    /**
1122     * This is set to true after the first switch after mAppSwitchesAllowedTime
1123     * is set; any switches after that will clear the time.
1124     */
1125    boolean mDidAppSwitch;
1126
1127    /**
1128     * Last time (in realtime) at which we checked for power usage.
1129     */
1130    long mLastPowerCheckRealtime;
1131
1132    /**
1133     * Last time (in uptime) at which we checked for power usage.
1134     */
1135    long mLastPowerCheckUptime;
1136
1137    /**
1138     * Set while we are wanting to sleep, to prevent any
1139     * activities from being started/resumed.
1140     */
1141    private boolean mSleeping = false;
1142
1143    /**
1144     * The process state used for processes that are running the top activities.
1145     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1146     */
1147    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1148
1149    /**
1150     * Set while we are running a voice interaction.  This overrides
1151     * sleeping while it is active.
1152     */
1153    private IVoiceInteractionSession mRunningVoice;
1154
1155    /**
1156     * For some direct access we need to power manager.
1157     */
1158    PowerManagerInternal mLocalPowerManager;
1159
1160    /**
1161     * We want to hold a wake lock while running a voice interaction session, since
1162     * this may happen with the screen off and we need to keep the CPU running to
1163     * be able to continue to interact with the user.
1164     */
1165    PowerManager.WakeLock mVoiceWakeLock;
1166
1167    /**
1168     * State of external calls telling us if the device is awake or asleep.
1169     */
1170    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1171
1172    /**
1173     * A list of tokens that cause the top activity to be put to sleep.
1174     * They are used by components that may hide and block interaction with underlying
1175     * activities.
1176     */
1177    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1178
1179    static final int LOCK_SCREEN_HIDDEN = 0;
1180    static final int LOCK_SCREEN_LEAVING = 1;
1181    static final int LOCK_SCREEN_SHOWN = 2;
1182    /**
1183     * State of external call telling us if the lock screen is shown.
1184     */
1185    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1186
1187    /**
1188     * Set if we are shutting down the system, similar to sleeping.
1189     */
1190    boolean mShuttingDown = false;
1191
1192    /**
1193     * Current sequence id for oom_adj computation traversal.
1194     */
1195    int mAdjSeq = 0;
1196
1197    /**
1198     * Current sequence id for process LRU updating.
1199     */
1200    int mLruSeq = 0;
1201
1202    /**
1203     * Keep track of the non-cached/empty process we last found, to help
1204     * determine how to distribute cached/empty processes next time.
1205     */
1206    int mNumNonCachedProcs = 0;
1207
1208    /**
1209     * Keep track of the number of cached hidden procs, to balance oom adj
1210     * distribution between those and empty procs.
1211     */
1212    int mNumCachedHiddenProcs = 0;
1213
1214    /**
1215     * Keep track of the number of service processes we last found, to
1216     * determine on the next iteration which should be B services.
1217     */
1218    int mNumServiceProcs = 0;
1219    int mNewNumAServiceProcs = 0;
1220    int mNewNumServiceProcs = 0;
1221
1222    /**
1223     * Allow the current computed overall memory level of the system to go down?
1224     * This is set to false when we are killing processes for reasons other than
1225     * memory management, so that the now smaller process list will not be taken as
1226     * an indication that memory is tighter.
1227     */
1228    boolean mAllowLowerMemLevel = false;
1229
1230    /**
1231     * The last computed memory level, for holding when we are in a state that
1232     * processes are going away for other reasons.
1233     */
1234    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1235
1236    /**
1237     * The last total number of process we have, to determine if changes actually look
1238     * like a shrinking number of process due to lower RAM.
1239     */
1240    int mLastNumProcesses;
1241
1242    /**
1243     * The uptime of the last time we performed idle maintenance.
1244     */
1245    long mLastIdleTime = SystemClock.uptimeMillis();
1246
1247    /**
1248     * Total time spent with RAM that has been added in the past since the last idle time.
1249     */
1250    long mLowRamTimeSinceLastIdle = 0;
1251
1252    /**
1253     * If RAM is currently low, when that horrible situation started.
1254     */
1255    long mLowRamStartTime = 0;
1256
1257    /**
1258     * For reporting to battery stats the current top application.
1259     */
1260    private String mCurResumedPackage = null;
1261    private int mCurResumedUid = -1;
1262
1263    /**
1264     * For reporting to battery stats the apps currently running foreground
1265     * service.  The ProcessMap is package/uid tuples; each of these contain
1266     * an array of the currently foreground processes.
1267     */
1268    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1269            = new ProcessMap<ArrayList<ProcessRecord>>();
1270
1271    /**
1272     * This is set if we had to do a delayed dexopt of an app before launching
1273     * it, to increase the ANR timeouts in that case.
1274     */
1275    boolean mDidDexOpt;
1276
1277    /**
1278     * Set if the systemServer made a call to enterSafeMode.
1279     */
1280    boolean mSafeMode;
1281
1282    /**
1283     * If true, we are running under a test environment so will sample PSS from processes
1284     * much more rapidly to try to collect better data when the tests are rapidly
1285     * running through apps.
1286     */
1287    boolean mTestPssMode = false;
1288
1289    String mDebugApp = null;
1290    boolean mWaitForDebugger = false;
1291    boolean mDebugTransient = false;
1292    String mOrigDebugApp = null;
1293    boolean mOrigWaitForDebugger = false;
1294    boolean mAlwaysFinishActivities = false;
1295    boolean mLenientBackgroundCheck = false;
1296    boolean mForceResizableActivities;
1297    boolean mSupportsMultiWindow;
1298    boolean mSupportsFreeformWindowManagement;
1299    boolean mSupportsPictureInPicture;
1300    Rect mDefaultPinnedStackBounds;
1301    IActivityController mController = null;
1302    boolean mControllerIsAMonkey = false;
1303    String mProfileApp = null;
1304    ProcessRecord mProfileProc = null;
1305    String mProfileFile;
1306    ParcelFileDescriptor mProfileFd;
1307    int mSamplingInterval = 0;
1308    boolean mAutoStopProfiler = false;
1309    int mProfileType = 0;
1310    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1311    String mMemWatchDumpProcName;
1312    String mMemWatchDumpFile;
1313    int mMemWatchDumpPid;
1314    int mMemWatchDumpUid;
1315    String mTrackAllocationApp = null;
1316    String mNativeDebuggingApp = null;
1317
1318    final long[] mTmpLong = new long[2];
1319
1320    static final class ProcessChangeItem {
1321        static final int CHANGE_ACTIVITIES = 1<<0;
1322        static final int CHANGE_PROCESS_STATE = 1<<1;
1323        int changes;
1324        int uid;
1325        int pid;
1326        int processState;
1327        boolean foregroundActivities;
1328    }
1329
1330    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1331    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1332
1333    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1334    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1335
1336    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1337    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1338
1339    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1340    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1341
1342    /**
1343     * Runtime CPU use collection thread.  This object's lock is used to
1344     * perform synchronization with the thread (notifying it to run).
1345     */
1346    final Thread mProcessCpuThread;
1347
1348    /**
1349     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1350     * Must acquire this object's lock when accessing it.
1351     * NOTE: this lock will be held while doing long operations (trawling
1352     * through all processes in /proc), so it should never be acquired by
1353     * any critical paths such as when holding the main activity manager lock.
1354     */
1355    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1356            MONITOR_THREAD_CPU_USAGE);
1357    final AtomicLong mLastCpuTime = new AtomicLong(0);
1358    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1359
1360    long mLastWriteTime = 0;
1361
1362    /**
1363     * Used to retain an update lock when the foreground activity is in
1364     * immersive mode.
1365     */
1366    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1367
1368    /**
1369     * Set to true after the system has finished booting.
1370     */
1371    boolean mBooted = false;
1372
1373    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1374    int mProcessLimitOverride = -1;
1375
1376    WindowManagerService mWindowManager;
1377    final ActivityThread mSystemThread;
1378
1379    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1380        final ProcessRecord mApp;
1381        final int mPid;
1382        final IApplicationThread mAppThread;
1383
1384        AppDeathRecipient(ProcessRecord app, int pid,
1385                IApplicationThread thread) {
1386            if (DEBUG_ALL) Slog.v(
1387                TAG, "New death recipient " + this
1388                + " for thread " + thread.asBinder());
1389            mApp = app;
1390            mPid = pid;
1391            mAppThread = thread;
1392        }
1393
1394        @Override
1395        public void binderDied() {
1396            if (DEBUG_ALL) Slog.v(
1397                TAG, "Death received in " + this
1398                + " for thread " + mAppThread.asBinder());
1399            synchronized(ActivityManagerService.this) {
1400                appDiedLocked(mApp, mPid, mAppThread, true);
1401            }
1402        }
1403    }
1404
1405    static final int SHOW_ERROR_UI_MSG = 1;
1406    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1407    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1408    static final int UPDATE_CONFIGURATION_MSG = 4;
1409    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1410    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1411    static final int SERVICE_TIMEOUT_MSG = 12;
1412    static final int UPDATE_TIME_ZONE = 13;
1413    static final int SHOW_UID_ERROR_UI_MSG = 14;
1414    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1415    static final int PROC_START_TIMEOUT_MSG = 20;
1416    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1417    static final int KILL_APPLICATION_MSG = 22;
1418    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1419    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1420    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1421    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1422    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1423    static final int CLEAR_DNS_CACHE_MSG = 28;
1424    static final int UPDATE_HTTP_PROXY_MSG = 29;
1425    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1426    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1427    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1428    static final int REPORT_MEM_USAGE_MSG = 33;
1429    static final int REPORT_USER_SWITCH_MSG = 34;
1430    static final int CONTINUE_USER_SWITCH_MSG = 35;
1431    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1432    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1433    static final int PERSIST_URI_GRANTS_MSG = 38;
1434    static final int REQUEST_ALL_PSS_MSG = 39;
1435    static final int START_PROFILES_MSG = 40;
1436    static final int UPDATE_TIME = 41;
1437    static final int SYSTEM_USER_START_MSG = 42;
1438    static final int SYSTEM_USER_CURRENT_MSG = 43;
1439    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1440    static final int FINISH_BOOTING_MSG = 45;
1441    static final int START_USER_SWITCH_UI_MSG = 46;
1442    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1443    static final int DISMISS_DIALOG_UI_MSG = 48;
1444    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1445    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1446    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1447    static final int DELETE_DUMPHEAP_MSG = 52;
1448    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1449    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1450    static final int REPORT_TIME_TRACKER_MSG = 55;
1451    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1452    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1453    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1454    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1455    static final int IDLE_UIDS_MSG = 60;
1456    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1457    static final int LOG_STACK_STATE = 62;
1458    static final int VR_MODE_CHANGE_MSG = 63;
1459    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1460    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1461    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1462
1463    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1464    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1465    static final int FIRST_COMPAT_MODE_MSG = 300;
1466    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1467
1468    CompatModeDialog mCompatModeDialog;
1469    long mLastMemUsageReportTime = 0;
1470
1471    /**
1472     * Flag whether the current user is a "monkey", i.e. whether
1473     * the UI is driven by a UI automation tool.
1474     */
1475    private boolean mUserIsMonkey;
1476
1477    /** Flag whether the device has a Recents UI */
1478    boolean mHasRecents;
1479
1480    /** The dimensions of the thumbnails in the Recents UI. */
1481    int mThumbnailWidth;
1482    int mThumbnailHeight;
1483
1484    final ServiceThread mHandlerThread;
1485    final MainHandler mHandler;
1486    final UiHandler mUiHandler;
1487    final ProcessStartLogger mProcessStartLogger;
1488
1489    PackageManagerInternal mPackageManagerInt;
1490
1491    final class UiHandler extends Handler {
1492        public UiHandler() {
1493            super(com.android.server.UiThread.get().getLooper(), null, true);
1494        }
1495
1496        @Override
1497        public void handleMessage(Message msg) {
1498            switch (msg.what) {
1499            case SHOW_ERROR_UI_MSG: {
1500                mAppErrors.handleShowAppErrorUi(msg);
1501                ensureBootCompleted();
1502            } break;
1503            case SHOW_NOT_RESPONDING_UI_MSG: {
1504                mAppErrors.handleShowAnrUi(msg);
1505                ensureBootCompleted();
1506            } break;
1507            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1508                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1509                synchronized (ActivityManagerService.this) {
1510                    ProcessRecord proc = (ProcessRecord) data.get("app");
1511                    if (proc == null) {
1512                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1513                        break;
1514                    }
1515                    if (proc.crashDialog != null) {
1516                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1517                        return;
1518                    }
1519                    AppErrorResult res = (AppErrorResult) data.get("result");
1520                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1521                        Dialog d = new StrictModeViolationDialog(mContext,
1522                                ActivityManagerService.this, res, proc);
1523                        d.show();
1524                        proc.crashDialog = d;
1525                    } else {
1526                        // The device is asleep, so just pretend that the user
1527                        // saw a crash dialog and hit "force quit".
1528                        res.set(0);
1529                    }
1530                }
1531                ensureBootCompleted();
1532            } break;
1533            case SHOW_FACTORY_ERROR_UI_MSG: {
1534                Dialog d = new FactoryErrorDialog(
1535                    mContext, msg.getData().getCharSequence("msg"));
1536                d.show();
1537                ensureBootCompleted();
1538            } break;
1539            case WAIT_FOR_DEBUGGER_UI_MSG: {
1540                synchronized (ActivityManagerService.this) {
1541                    ProcessRecord app = (ProcessRecord)msg.obj;
1542                    if (msg.arg1 != 0) {
1543                        if (!app.waitedForDebugger) {
1544                            Dialog d = new AppWaitingForDebuggerDialog(
1545                                    ActivityManagerService.this,
1546                                    mContext, app);
1547                            app.waitDialog = d;
1548                            app.waitedForDebugger = true;
1549                            d.show();
1550                        }
1551                    } else {
1552                        if (app.waitDialog != null) {
1553                            app.waitDialog.dismiss();
1554                            app.waitDialog = null;
1555                        }
1556                    }
1557                }
1558            } break;
1559            case SHOW_UID_ERROR_UI_MSG: {
1560                if (mShowDialogs) {
1561                    AlertDialog d = new BaseErrorDialog(mContext);
1562                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1563                    d.setCancelable(false);
1564                    d.setTitle(mContext.getText(R.string.android_system_label));
1565                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1566                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1567                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1568                    d.show();
1569                }
1570            } break;
1571            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1572                if (mShowDialogs) {
1573                    AlertDialog d = new BaseErrorDialog(mContext);
1574                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1575                    d.setCancelable(false);
1576                    d.setTitle(mContext.getText(R.string.android_system_label));
1577                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1578                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1579                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1580                    d.show();
1581                }
1582            } break;
1583            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1584                synchronized (ActivityManagerService.this) {
1585                    ActivityRecord ar = (ActivityRecord) msg.obj;
1586                    if (mCompatModeDialog != null) {
1587                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1588                                ar.info.applicationInfo.packageName)) {
1589                            return;
1590                        }
1591                        mCompatModeDialog.dismiss();
1592                        mCompatModeDialog = null;
1593                    }
1594                    if (ar != null && false) {
1595                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1596                                ar.packageName)) {
1597                            int mode = mCompatModePackages.computeCompatModeLocked(
1598                                    ar.info.applicationInfo);
1599                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1600                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1601                                mCompatModeDialog = new CompatModeDialog(
1602                                        ActivityManagerService.this, mContext,
1603                                        ar.info.applicationInfo);
1604                                mCompatModeDialog.show();
1605                            }
1606                        }
1607                    }
1608                }
1609                break;
1610            }
1611            case START_USER_SWITCH_UI_MSG: {
1612                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1613                break;
1614            }
1615            case DISMISS_DIALOG_UI_MSG: {
1616                final Dialog d = (Dialog) msg.obj;
1617                d.dismiss();
1618                break;
1619            }
1620            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1621                dispatchProcessesChanged();
1622                break;
1623            }
1624            case DISPATCH_PROCESS_DIED_UI_MSG: {
1625                final int pid = msg.arg1;
1626                final int uid = msg.arg2;
1627                dispatchProcessDied(pid, uid);
1628                break;
1629            }
1630            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1631                dispatchUidsChanged();
1632            } break;
1633            }
1634        }
1635    }
1636
1637    final class MainHandler extends Handler {
1638        public MainHandler(Looper looper) {
1639            super(looper, null, true);
1640        }
1641
1642        @Override
1643        public void handleMessage(Message msg) {
1644            switch (msg.what) {
1645            case UPDATE_CONFIGURATION_MSG: {
1646                final ContentResolver resolver = mContext.getContentResolver();
1647                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1648                        msg.arg1);
1649            } break;
1650            case GC_BACKGROUND_PROCESSES_MSG: {
1651                synchronized (ActivityManagerService.this) {
1652                    performAppGcsIfAppropriateLocked();
1653                }
1654            } break;
1655            case SERVICE_TIMEOUT_MSG: {
1656                if (mDidDexOpt) {
1657                    mDidDexOpt = false;
1658                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1659                    nmsg.obj = msg.obj;
1660                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1661                    return;
1662                }
1663                mServices.serviceTimeout((ProcessRecord)msg.obj);
1664            } break;
1665            case UPDATE_TIME_ZONE: {
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.updateTimeZone();
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678            } break;
1679            case CLEAR_DNS_CACHE_MSG: {
1680                synchronized (ActivityManagerService.this) {
1681                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1682                        ProcessRecord r = mLruProcesses.get(i);
1683                        if (r.thread != null) {
1684                            try {
1685                                r.thread.clearDnsCache();
1686                            } catch (RemoteException ex) {
1687                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1688                            }
1689                        }
1690                    }
1691                }
1692            } break;
1693            case UPDATE_HTTP_PROXY_MSG: {
1694                ProxyInfo proxy = (ProxyInfo)msg.obj;
1695                String host = "";
1696                String port = "";
1697                String exclList = "";
1698                Uri pacFileUrl = Uri.EMPTY;
1699                if (proxy != null) {
1700                    host = proxy.getHost();
1701                    port = Integer.toString(proxy.getPort());
1702                    exclList = proxy.getExclusionListAsString();
1703                    pacFileUrl = proxy.getPacFileUrl();
1704                }
1705                synchronized (ActivityManagerService.this) {
1706                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1707                        ProcessRecord r = mLruProcesses.get(i);
1708                        if (r.thread != null) {
1709                            try {
1710                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1711                            } catch (RemoteException ex) {
1712                                Slog.w(TAG, "Failed to update http proxy for: " +
1713                                        r.info.processName);
1714                            }
1715                        }
1716                    }
1717                }
1718            } break;
1719            case PROC_START_TIMEOUT_MSG: {
1720                if (mDidDexOpt) {
1721                    mDidDexOpt = false;
1722                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1723                    nmsg.obj = msg.obj;
1724                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1725                    return;
1726                }
1727                ProcessRecord app = (ProcessRecord)msg.obj;
1728                synchronized (ActivityManagerService.this) {
1729                    processStartTimedOutLocked(app);
1730                }
1731            } break;
1732            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1733                ProcessRecord app = (ProcessRecord)msg.obj;
1734                synchronized (ActivityManagerService.this) {
1735                    processContentProviderPublishTimedOutLocked(app);
1736                }
1737            } break;
1738            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1739                synchronized (ActivityManagerService.this) {
1740                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1741                }
1742            } break;
1743            case KILL_APPLICATION_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    int appid = msg.arg1;
1746                    boolean restart = (msg.arg2 == 1);
1747                    Bundle bundle = (Bundle)msg.obj;
1748                    String pkg = bundle.getString("pkg");
1749                    String reason = bundle.getString("reason");
1750                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1751                            false, UserHandle.USER_ALL, reason);
1752                }
1753            } break;
1754            case FINALIZE_PENDING_INTENT_MSG: {
1755                ((PendingIntentRecord)msg.obj).completeFinalize();
1756            } break;
1757            case POST_HEAVY_NOTIFICATION_MSG: {
1758                INotificationManager inm = NotificationManager.getService();
1759                if (inm == null) {
1760                    return;
1761                }
1762
1763                ActivityRecord root = (ActivityRecord)msg.obj;
1764                ProcessRecord process = root.app;
1765                if (process == null) {
1766                    return;
1767                }
1768
1769                try {
1770                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1771                    String text = mContext.getString(R.string.heavy_weight_notification,
1772                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1773                    Notification notification = new Notification.Builder(context)
1774                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1775                            .setWhen(0)
1776                            .setOngoing(true)
1777                            .setTicker(text)
1778                            .setColor(mContext.getColor(
1779                                    com.android.internal.R.color.system_notification_accent_color))
1780                            .setContentTitle(text)
1781                            .setContentText(
1782                                    mContext.getText(R.string.heavy_weight_notification_detail))
1783                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1784                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1785                                    new UserHandle(root.userId)))
1786                            .build();
1787                    try {
1788                        int[] outId = new int[1];
1789                        inm.enqueueNotificationWithTag("android", "android", null,
1790                                R.string.heavy_weight_notification,
1791                                notification, outId, root.userId);
1792                    } catch (RuntimeException e) {
1793                        Slog.w(ActivityManagerService.TAG,
1794                                "Error showing notification for heavy-weight app", e);
1795                    } catch (RemoteException e) {
1796                    }
1797                } catch (NameNotFoundException e) {
1798                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1799                }
1800            } break;
1801            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1802                INotificationManager inm = NotificationManager.getService();
1803                if (inm == null) {
1804                    return;
1805                }
1806                try {
1807                    inm.cancelNotificationWithTag("android", null,
1808                            R.string.heavy_weight_notification,  msg.arg1);
1809                } catch (RuntimeException e) {
1810                    Slog.w(ActivityManagerService.TAG,
1811                            "Error canceling notification for service", e);
1812                } catch (RemoteException e) {
1813                }
1814            } break;
1815            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    checkExcessivePowerUsageLocked(true);
1818                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1819                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1820                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1821                }
1822            } break;
1823            case REPORT_MEM_USAGE_MSG: {
1824                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1825                Thread thread = new Thread() {
1826                    @Override public void run() {
1827                        reportMemUsage(memInfos);
1828                    }
1829                };
1830                thread.start();
1831                break;
1832            }
1833            case REPORT_USER_SWITCH_MSG: {
1834                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1835                break;
1836            }
1837            case CONTINUE_USER_SWITCH_MSG: {
1838                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1839                break;
1840            }
1841            case USER_SWITCH_TIMEOUT_MSG: {
1842                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1843                break;
1844            }
1845            case IMMERSIVE_MODE_LOCK_MSG: {
1846                final boolean nextState = (msg.arg1 != 0);
1847                if (mUpdateLock.isHeld() != nextState) {
1848                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1849                            "Applying new update lock state '" + nextState
1850                            + "' for " + (ActivityRecord)msg.obj);
1851                    if (nextState) {
1852                        mUpdateLock.acquire();
1853                    } else {
1854                        mUpdateLock.release();
1855                    }
1856                }
1857                break;
1858            }
1859            case PERSIST_URI_GRANTS_MSG: {
1860                writeGrantedUriPermissions();
1861                break;
1862            }
1863            case REQUEST_ALL_PSS_MSG: {
1864                synchronized (ActivityManagerService.this) {
1865                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1866                }
1867                break;
1868            }
1869            case START_PROFILES_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    mUserController.startProfilesLocked();
1872                }
1873                break;
1874            }
1875            case UPDATE_TIME: {
1876                synchronized (ActivityManagerService.this) {
1877                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1878                        ProcessRecord r = mLruProcesses.get(i);
1879                        if (r.thread != null) {
1880                            try {
1881                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1882                            } catch (RemoteException ex) {
1883                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1884                            }
1885                        }
1886                    }
1887                }
1888                break;
1889            }
1890            case SYSTEM_USER_START_MSG: {
1891                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1892                        Integer.toString(msg.arg1), msg.arg1);
1893                mSystemServiceManager.startUser(msg.arg1);
1894                break;
1895            }
1896            case SYSTEM_USER_UNLOCK_MSG: {
1897                final int userId = msg.arg1;
1898                mSystemServiceManager.unlockUser(userId);
1899                mRecentTasks.loadUserRecentsLocked(userId);
1900                if (userId == UserHandle.USER_SYSTEM) {
1901                    startPersistentApps(PackageManager.MATCH_ENCRYPTION_UNAWARE);
1902                }
1903                installEncryptionUnawareProviders(userId);
1904                break;
1905            }
1906            case SYSTEM_USER_CURRENT_MSG: {
1907                mBatteryStatsService.noteEvent(
1908                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1909                        Integer.toString(msg.arg2), msg.arg2);
1910                mBatteryStatsService.noteEvent(
1911                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1912                        Integer.toString(msg.arg1), msg.arg1);
1913                mSystemServiceManager.switchUser(msg.arg1);
1914                break;
1915            }
1916            case ENTER_ANIMATION_COMPLETE_MSG: {
1917                synchronized (ActivityManagerService.this) {
1918                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1919                    if (r != null && r.app != null && r.app.thread != null) {
1920                        try {
1921                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1922                        } catch (RemoteException e) {
1923                        }
1924                    }
1925                }
1926                break;
1927            }
1928            case FINISH_BOOTING_MSG: {
1929                if (msg.arg1 != 0) {
1930                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1931                    finishBooting();
1932                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1933                }
1934                if (msg.arg2 != 0) {
1935                    enableScreenAfterBoot();
1936                }
1937                break;
1938            }
1939            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1940                try {
1941                    Locale l = (Locale) msg.obj;
1942                    IBinder service = ServiceManager.getService("mount");
1943                    IMountService mountService = IMountService.Stub.asInterface(service);
1944                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1945                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1946                } catch (RemoteException e) {
1947                    Log.e(TAG, "Error storing locale for decryption UI", e);
1948                }
1949                break;
1950            }
1951            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1954                        try {
1955                            // Make a one-way callback to the listener
1956                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1957                        } catch (RemoteException e){
1958                            // Handled by the RemoteCallbackList
1959                        }
1960                    }
1961                    mTaskStackListeners.finishBroadcast();
1962                }
1963                break;
1964            }
1965            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1966                synchronized (ActivityManagerService.this) {
1967                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1968                        try {
1969                            // Make a one-way callback to the listener
1970                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1971                        } catch (RemoteException e){
1972                            // Handled by the RemoteCallbackList
1973                        }
1974                    }
1975                    mTaskStackListeners.finishBroadcast();
1976                }
1977                break;
1978            }
1979            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1982                        try {
1983                            // Make a one-way callback to the listener
1984                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1985                        } catch (RemoteException e){
1986                            // Handled by the RemoteCallbackList
1987                        }
1988                    }
1989                    mTaskStackListeners.finishBroadcast();
1990                }
1991                break;
1992            }
1993            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
1994                synchronized (ActivityManagerService.this) {
1995                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1996                        try {
1997                            // Make a one-way callback to the listener
1998                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
1999                        } catch (RemoteException e){
2000                            // Handled by the RemoteCallbackList
2001                        }
2002                    }
2003                    mTaskStackListeners.finishBroadcast();
2004                }
2005                break;
2006            }
2007            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2008                final int uid = msg.arg1;
2009                final byte[] firstPacket = (byte[]) msg.obj;
2010
2011                synchronized (mPidsSelfLocked) {
2012                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2013                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2014                        if (p.uid == uid) {
2015                            try {
2016                                p.thread.notifyCleartextNetwork(firstPacket);
2017                            } catch (RemoteException ignored) {
2018                            }
2019                        }
2020                    }
2021                }
2022                break;
2023            }
2024            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2025                final String procName;
2026                final int uid;
2027                final long memLimit;
2028                final String reportPackage;
2029                synchronized (ActivityManagerService.this) {
2030                    procName = mMemWatchDumpProcName;
2031                    uid = mMemWatchDumpUid;
2032                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2033                    if (val == null) {
2034                        val = mMemWatchProcesses.get(procName, 0);
2035                    }
2036                    if (val != null) {
2037                        memLimit = val.first;
2038                        reportPackage = val.second;
2039                    } else {
2040                        memLimit = 0;
2041                        reportPackage = null;
2042                    }
2043                }
2044                if (procName == null) {
2045                    return;
2046                }
2047
2048                if (DEBUG_PSS) Slog.d(TAG_PSS,
2049                        "Showing dump heap notification from " + procName + "/" + uid);
2050
2051                INotificationManager inm = NotificationManager.getService();
2052                if (inm == null) {
2053                    return;
2054                }
2055
2056                String text = mContext.getString(R.string.dump_heap_notification, procName);
2057
2058
2059                Intent deleteIntent = new Intent();
2060                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2061                Intent intent = new Intent();
2062                intent.setClassName("android", DumpHeapActivity.class.getName());
2063                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2064                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2065                if (reportPackage != null) {
2066                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2067                }
2068                int userId = UserHandle.getUserId(uid);
2069                Notification notification = new Notification.Builder(mContext)
2070                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2071                        .setWhen(0)
2072                        .setOngoing(true)
2073                        .setAutoCancel(true)
2074                        .setTicker(text)
2075                        .setColor(mContext.getColor(
2076                                com.android.internal.R.color.system_notification_accent_color))
2077                        .setContentTitle(text)
2078                        .setContentText(
2079                                mContext.getText(R.string.dump_heap_notification_detail))
2080                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2081                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2082                                new UserHandle(userId)))
2083                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2084                                deleteIntent, 0, UserHandle.SYSTEM))
2085                        .build();
2086
2087                try {
2088                    int[] outId = new int[1];
2089                    inm.enqueueNotificationWithTag("android", "android", null,
2090                            R.string.dump_heap_notification,
2091                            notification, outId, userId);
2092                } catch (RuntimeException e) {
2093                    Slog.w(ActivityManagerService.TAG,
2094                            "Error showing notification for dump heap", e);
2095                } catch (RemoteException e) {
2096                }
2097            } break;
2098            case DELETE_DUMPHEAP_MSG: {
2099                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2100                        DumpHeapActivity.JAVA_URI,
2101                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2102                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2103                        UserHandle.myUserId());
2104                synchronized (ActivityManagerService.this) {
2105                    mMemWatchDumpFile = null;
2106                    mMemWatchDumpProcName = null;
2107                    mMemWatchDumpPid = -1;
2108                    mMemWatchDumpUid = -1;
2109                }
2110            } break;
2111            case FOREGROUND_PROFILE_CHANGED_MSG: {
2112                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2113            } break;
2114            case REPORT_TIME_TRACKER_MSG: {
2115                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2116                tracker.deliverResult(mContext);
2117            } break;
2118            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2119                mUserController.dispatchUserSwitchComplete(msg.arg1);
2120            } break;
2121            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2122                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2123                try {
2124                    connection.shutdown();
2125                } catch (RemoteException e) {
2126                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2127                }
2128                // Only a UiAutomation can set this flag and now that
2129                // it is finished we make sure it is reset to its default.
2130                mUserIsMonkey = false;
2131            } break;
2132            case APP_BOOST_DEACTIVATE_MSG: {
2133                synchronized(ActivityManagerService.this) {
2134                    if (mIsBoosted) {
2135                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2136                            nativeMigrateFromBoost();
2137                            mIsBoosted = false;
2138                            mBoostStartTime = 0;
2139                        } else {
2140                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2141                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2142                        }
2143                    }
2144                }
2145            } break;
2146            case IDLE_UIDS_MSG: {
2147                idleUids();
2148            } break;
2149            case LOG_STACK_STATE: {
2150                synchronized (ActivityManagerService.this) {
2151                    mStackSupervisor.logStackState();
2152                }
2153            } break;
2154            case VR_MODE_CHANGE_MSG: {
2155                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2156                final boolean vrMode = msg.arg1 != 0;
2157                vrService.setVrMode(vrMode);
2158
2159                if (mInVrMode != vrMode) {
2160                    synchronized (ActivityManagerService.this) {
2161                        mInVrMode = vrMode;
2162                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2163                    }
2164                }
2165            } break;
2166            }
2167        }
2168    };
2169
2170    static final int COLLECT_PSS_BG_MSG = 1;
2171
2172    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2173        @Override
2174        public void handleMessage(Message msg) {
2175            switch (msg.what) {
2176            case COLLECT_PSS_BG_MSG: {
2177                long start = SystemClock.uptimeMillis();
2178                MemInfoReader memInfo = null;
2179                synchronized (ActivityManagerService.this) {
2180                    if (mFullPssPending) {
2181                        mFullPssPending = false;
2182                        memInfo = new MemInfoReader();
2183                    }
2184                }
2185                if (memInfo != null) {
2186                    updateCpuStatsNow();
2187                    long nativeTotalPss = 0;
2188                    synchronized (mProcessCpuTracker) {
2189                        final int N = mProcessCpuTracker.countStats();
2190                        for (int j=0; j<N; j++) {
2191                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2192                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2193                                // This is definitely an application process; skip it.
2194                                continue;
2195                            }
2196                            synchronized (mPidsSelfLocked) {
2197                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2198                                    // This is one of our own processes; skip it.
2199                                    continue;
2200                                }
2201                            }
2202                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2203                        }
2204                    }
2205                    memInfo.readMemInfo();
2206                    synchronized (ActivityManagerService.this) {
2207                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2208                                + (SystemClock.uptimeMillis()-start) + "ms");
2209                        final long cachedKb = memInfo.getCachedSizeKb();
2210                        final long freeKb = memInfo.getFreeSizeKb();
2211                        final long zramKb = memInfo.getZramTotalSizeKb();
2212                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2213                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2214                                kernelKb*1024, nativeTotalPss*1024);
2215                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2216                                nativeTotalPss);
2217                    }
2218                }
2219
2220                int num = 0;
2221                long[] tmp = new long[2];
2222                do {
2223                    ProcessRecord proc;
2224                    int procState;
2225                    int pid;
2226                    long lastPssTime;
2227                    synchronized (ActivityManagerService.this) {
2228                        if (mPendingPssProcesses.size() <= 0) {
2229                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2230                                    "Collected PSS of " + num + " processes in "
2231                                    + (SystemClock.uptimeMillis() - start) + "ms");
2232                            mPendingPssProcesses.clear();
2233                            return;
2234                        }
2235                        proc = mPendingPssProcesses.remove(0);
2236                        procState = proc.pssProcState;
2237                        lastPssTime = proc.lastPssTime;
2238                        if (proc.thread != null && procState == proc.setProcState
2239                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2240                                        < SystemClock.uptimeMillis()) {
2241                            pid = proc.pid;
2242                        } else {
2243                            proc = null;
2244                            pid = 0;
2245                        }
2246                    }
2247                    if (proc != null) {
2248                        long pss = Debug.getPss(pid, tmp, null);
2249                        synchronized (ActivityManagerService.this) {
2250                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2251                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2252                                num++;
2253                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2254                                        SystemClock.uptimeMillis());
2255                            }
2256                        }
2257                    }
2258                } while (true);
2259            }
2260            }
2261        }
2262    };
2263
2264    public void setSystemProcess() {
2265        try {
2266            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2267            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2268            ServiceManager.addService("meminfo", new MemBinder(this));
2269            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2270            ServiceManager.addService("dbinfo", new DbBinder(this));
2271            if (MONITOR_CPU_USAGE) {
2272                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2273            }
2274            ServiceManager.addService("permission", new PermissionController(this));
2275            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2276
2277            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2278                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2279            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2280
2281            synchronized (this) {
2282                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2283                app.persistent = true;
2284                app.pid = MY_PID;
2285                app.maxAdj = ProcessList.SYSTEM_ADJ;
2286                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2287                synchronized (mPidsSelfLocked) {
2288                    mPidsSelfLocked.put(app.pid, app);
2289                }
2290                updateLruProcessLocked(app, false, null);
2291                updateOomAdjLocked();
2292            }
2293        } catch (PackageManager.NameNotFoundException e) {
2294            throw new RuntimeException(
2295                    "Unable to find android system package", e);
2296        }
2297    }
2298
2299    public void setWindowManager(WindowManagerService wm) {
2300        mWindowManager = wm;
2301        mStackSupervisor.setWindowManager(wm);
2302        mActivityStarter.setWindowManager(wm);
2303    }
2304
2305    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2306        mUsageStatsService = usageStatsManager;
2307    }
2308
2309    public void startObservingNativeCrashes() {
2310        final NativeCrashListener ncl = new NativeCrashListener(this);
2311        ncl.start();
2312    }
2313
2314    public IAppOpsService getAppOpsService() {
2315        return mAppOpsService;
2316    }
2317
2318    static class MemBinder extends Binder {
2319        ActivityManagerService mActivityManagerService;
2320        MemBinder(ActivityManagerService activityManagerService) {
2321            mActivityManagerService = activityManagerService;
2322        }
2323
2324        @Override
2325        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2326            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2327                    != PackageManager.PERMISSION_GRANTED) {
2328                pw.println("Permission Denial: can't dump meminfo from from pid="
2329                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2330                        + " without permission " + android.Manifest.permission.DUMP);
2331                return;
2332            }
2333
2334            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2335        }
2336    }
2337
2338    static class GraphicsBinder extends Binder {
2339        ActivityManagerService mActivityManagerService;
2340        GraphicsBinder(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 gfxinfo from from pid="
2349                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2350                        + " without permission " + android.Manifest.permission.DUMP);
2351                return;
2352            }
2353
2354            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2355        }
2356    }
2357
2358    static class DbBinder extends Binder {
2359        ActivityManagerService mActivityManagerService;
2360        DbBinder(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 dbinfo from from pid="
2369                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2370                        + " without permission " + android.Manifest.permission.DUMP);
2371                return;
2372            }
2373
2374            mActivityManagerService.dumpDbInfo(fd, pw, args);
2375        }
2376    }
2377
2378    static class CpuBinder extends Binder {
2379        ActivityManagerService mActivityManagerService;
2380        CpuBinder(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 cpuinfo from from pid="
2389                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2390                        + " without permission " + android.Manifest.permission.DUMP);
2391                return;
2392            }
2393
2394            synchronized (mActivityManagerService.mProcessCpuTracker) {
2395                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2396                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2397                        SystemClock.uptimeMillis()));
2398            }
2399        }
2400    }
2401
2402    public static final class Lifecycle extends SystemService {
2403        private final ActivityManagerService mService;
2404
2405        public Lifecycle(Context context) {
2406            super(context);
2407            mService = new ActivityManagerService(context);
2408        }
2409
2410        @Override
2411        public void onStart() {
2412            mService.start();
2413        }
2414
2415        public ActivityManagerService getService() {
2416            return mService;
2417        }
2418    }
2419
2420    // Note: This method is invoked on the main thread but may need to attach various
2421    // handlers to other threads.  So take care to be explicit about the looper.
2422    public ActivityManagerService(Context systemContext) {
2423        mContext = systemContext;
2424        mFactoryTest = FactoryTest.getMode();
2425        mSystemThread = ActivityThread.currentActivityThread();
2426
2427        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2428
2429        mHandlerThread = new ServiceThread(TAG,
2430                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2431        mHandlerThread.start();
2432        mHandler = new MainHandler(mHandlerThread.getLooper());
2433        mUiHandler = new UiHandler();
2434
2435        mProcessStartLogger = new ProcessStartLogger();
2436
2437        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2438                "foreground", BROADCAST_FG_TIMEOUT, false);
2439        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2440                "background", BROADCAST_BG_TIMEOUT, true);
2441        mBroadcastQueues[0] = mFgBroadcastQueue;
2442        mBroadcastQueues[1] = mBgBroadcastQueue;
2443
2444        mServices = new ActiveServices(this);
2445        mProviderMap = new ProviderMap(this);
2446        mAppErrors = new AppErrors(mContext, this);
2447
2448        // TODO: Move creation of battery stats service outside of activity manager service.
2449        File dataDir = Environment.getDataDirectory();
2450        File systemDir = new File(dataDir, "system");
2451        systemDir.mkdirs();
2452        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2453        mBatteryStatsService.getActiveStatistics().readLocked();
2454        mBatteryStatsService.scheduleWriteToDisk();
2455        mOnBattery = DEBUG_POWER ? true
2456                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2457        mBatteryStatsService.getActiveStatistics().setCallback(this);
2458
2459        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2460
2461        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2462        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2463                new IAppOpsCallback.Stub() {
2464                    @Override public void opChanged(int op, int uid, String packageName) {
2465                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2466                            if (mAppOpsService.checkOperation(op, uid, packageName)
2467                                    != AppOpsManager.MODE_ALLOWED) {
2468                                runInBackgroundDisabled(uid);
2469                            }
2470                        }
2471                    }
2472                });
2473
2474        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2475
2476        mUserController = new UserController(this);
2477
2478        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2479            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2480
2481        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2482
2483        mConfiguration.setToDefaults();
2484        mConfiguration.setLocales(LocaleList.getDefault());
2485
2486        mConfigurationSeq = mConfiguration.seq = 1;
2487        mProcessCpuTracker.init();
2488
2489        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2490        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2491        mStackSupervisor = new ActivityStackSupervisor(this);
2492        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2493        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2494
2495        mProcessCpuThread = new Thread("CpuTracker") {
2496            @Override
2497            public void run() {
2498                while (true) {
2499                    try {
2500                        try {
2501                            synchronized(this) {
2502                                final long now = SystemClock.uptimeMillis();
2503                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2504                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2505                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2506                                //        + ", write delay=" + nextWriteDelay);
2507                                if (nextWriteDelay < nextCpuDelay) {
2508                                    nextCpuDelay = nextWriteDelay;
2509                                }
2510                                if (nextCpuDelay > 0) {
2511                                    mProcessCpuMutexFree.set(true);
2512                                    this.wait(nextCpuDelay);
2513                                }
2514                            }
2515                        } catch (InterruptedException e) {
2516                        }
2517                        updateCpuStatsNow();
2518                    } catch (Exception e) {
2519                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2520                    }
2521                }
2522            }
2523        };
2524
2525        Watchdog.getInstance().addMonitor(this);
2526        Watchdog.getInstance().addThread(mHandler);
2527    }
2528
2529    public void setSystemServiceManager(SystemServiceManager mgr) {
2530        mSystemServiceManager = mgr;
2531    }
2532
2533    public void setInstaller(Installer installer) {
2534        mInstaller = installer;
2535    }
2536
2537    private void start() {
2538        Process.removeAllProcessGroups();
2539        mProcessCpuThread.start();
2540
2541        mBatteryStatsService.publish(mContext);
2542        mAppOpsService.publish(mContext);
2543        Slog.d("AppOps", "AppOpsService published");
2544        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2545    }
2546
2547    void onUserStoppedLocked(int userId) {
2548        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2549    }
2550
2551    public void initPowerManagement() {
2552        mStackSupervisor.initPowerManagement();
2553        mBatteryStatsService.initPowerManagement();
2554        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2555        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2556        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2557        mVoiceWakeLock.setReferenceCounted(false);
2558    }
2559
2560    @Override
2561    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2562            throws RemoteException {
2563        if (code == SYSPROPS_TRANSACTION) {
2564            // We need to tell all apps about the system property change.
2565            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2566            synchronized(this) {
2567                final int NP = mProcessNames.getMap().size();
2568                for (int ip=0; ip<NP; ip++) {
2569                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2570                    final int NA = apps.size();
2571                    for (int ia=0; ia<NA; ia++) {
2572                        ProcessRecord app = apps.valueAt(ia);
2573                        if (app.thread != null) {
2574                            procs.add(app.thread.asBinder());
2575                        }
2576                    }
2577                }
2578            }
2579
2580            int N = procs.size();
2581            for (int i=0; i<N; i++) {
2582                Parcel data2 = Parcel.obtain();
2583                try {
2584                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2585                } catch (RemoteException e) {
2586                }
2587                data2.recycle();
2588            }
2589        }
2590        try {
2591            return super.onTransact(code, data, reply, flags);
2592        } catch (RuntimeException e) {
2593            // The activity manager only throws security exceptions, so let's
2594            // log all others.
2595            if (!(e instanceof SecurityException)) {
2596                Slog.wtf(TAG, "Activity Manager Crash", e);
2597            }
2598            throw e;
2599        }
2600    }
2601
2602    void updateCpuStats() {
2603        final long now = SystemClock.uptimeMillis();
2604        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2605            return;
2606        }
2607        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2608            synchronized (mProcessCpuThread) {
2609                mProcessCpuThread.notify();
2610            }
2611        }
2612    }
2613
2614    void updateCpuStatsNow() {
2615        synchronized (mProcessCpuTracker) {
2616            mProcessCpuMutexFree.set(false);
2617            final long now = SystemClock.uptimeMillis();
2618            boolean haveNewCpuStats = false;
2619
2620            if (MONITOR_CPU_USAGE &&
2621                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2622                mLastCpuTime.set(now);
2623                mProcessCpuTracker.update();
2624                if (mProcessCpuTracker.hasGoodLastStats()) {
2625                    haveNewCpuStats = true;
2626                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2627                    //Slog.i(TAG, "Total CPU usage: "
2628                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2629
2630                    // Slog the cpu usage if the property is set.
2631                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2632                        int user = mProcessCpuTracker.getLastUserTime();
2633                        int system = mProcessCpuTracker.getLastSystemTime();
2634                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2635                        int irq = mProcessCpuTracker.getLastIrqTime();
2636                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2637                        int idle = mProcessCpuTracker.getLastIdleTime();
2638
2639                        int total = user + system + iowait + irq + softIrq + idle;
2640                        if (total == 0) total = 1;
2641
2642                        EventLog.writeEvent(EventLogTags.CPU,
2643                                ((user+system+iowait+irq+softIrq) * 100) / total,
2644                                (user * 100) / total,
2645                                (system * 100) / total,
2646                                (iowait * 100) / total,
2647                                (irq * 100) / total,
2648                                (softIrq * 100) / total);
2649                    }
2650                }
2651            }
2652
2653            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2654            synchronized(bstats) {
2655                synchronized(mPidsSelfLocked) {
2656                    if (haveNewCpuStats) {
2657                        if (bstats.startAddingCpuLocked()) {
2658                            int totalUTime = 0;
2659                            int totalSTime = 0;
2660                            final int N = mProcessCpuTracker.countStats();
2661                            for (int i=0; i<N; i++) {
2662                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2663                                if (!st.working) {
2664                                    continue;
2665                                }
2666                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2667                                totalUTime += st.rel_utime;
2668                                totalSTime += st.rel_stime;
2669                                if (pr != null) {
2670                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2671                                    if (ps == null || !ps.isActive()) {
2672                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2673                                                pr.info.uid, pr.processName);
2674                                    }
2675                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2676                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2677                                } else {
2678                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2679                                    if (ps == null || !ps.isActive()) {
2680                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2681                                                bstats.mapUid(st.uid), st.name);
2682                                    }
2683                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2684                                }
2685                            }
2686                            final int userTime = mProcessCpuTracker.getLastUserTime();
2687                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2688                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2689                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2690                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2691                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2692                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2693                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2694                        }
2695                    }
2696                }
2697
2698                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2699                    mLastWriteTime = now;
2700                    mBatteryStatsService.scheduleWriteToDisk();
2701                }
2702            }
2703        }
2704    }
2705
2706    @Override
2707    public void batteryNeedsCpuUpdate() {
2708        updateCpuStatsNow();
2709    }
2710
2711    @Override
2712    public void batteryPowerChanged(boolean onBattery) {
2713        // When plugging in, update the CPU stats first before changing
2714        // the plug state.
2715        updateCpuStatsNow();
2716        synchronized (this) {
2717            synchronized(mPidsSelfLocked) {
2718                mOnBattery = DEBUG_POWER ? true : onBattery;
2719            }
2720        }
2721    }
2722
2723    @Override
2724    public void batterySendBroadcast(Intent intent) {
2725        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2726                AppOpsManager.OP_NONE, null, false, false,
2727                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2728    }
2729
2730    /**
2731     * Initialize the application bind args. These are passed to each
2732     * process when the bindApplication() IPC is sent to the process. They're
2733     * lazily setup to make sure the services are running when they're asked for.
2734     */
2735    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2736        if (mAppBindArgs == null) {
2737            mAppBindArgs = new HashMap<>();
2738
2739            // Isolated processes won't get this optimization, so that we don't
2740            // violate the rules about which services they have access to.
2741            if (!isolated) {
2742                // Setup the application init args
2743                mAppBindArgs.put("package", ServiceManager.getService("package"));
2744                mAppBindArgs.put("window", ServiceManager.getService("window"));
2745                mAppBindArgs.put(Context.ALARM_SERVICE,
2746                        ServiceManager.getService(Context.ALARM_SERVICE));
2747            }
2748        }
2749        return mAppBindArgs;
2750    }
2751
2752    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2753        if (r == null || mFocusedActivity == r) {
2754            return false;
2755        }
2756
2757        if (!r.isFocusable()) {
2758            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2759            return false;
2760        }
2761
2762        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2763
2764        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2765        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2766                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2767        mDoingSetFocusedActivity = true;
2768
2769        final ActivityRecord last = mFocusedActivity;
2770        mFocusedActivity = r;
2771        if (r.task.isApplicationTask()) {
2772            if (mCurAppTimeTracker != r.appTimeTracker) {
2773                // We are switching app tracking.  Complete the current one.
2774                if (mCurAppTimeTracker != null) {
2775                    mCurAppTimeTracker.stop();
2776                    mHandler.obtainMessage(
2777                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2778                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2779                    mCurAppTimeTracker = null;
2780                }
2781                if (r.appTimeTracker != null) {
2782                    mCurAppTimeTracker = r.appTimeTracker;
2783                    startTimeTrackingFocusedActivityLocked();
2784                }
2785            } else {
2786                startTimeTrackingFocusedActivityLocked();
2787            }
2788        } else {
2789            r.appTimeTracker = null;
2790        }
2791        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2792        // TODO: Probably not, because we don't want to resume voice on switching
2793        // back to this activity
2794        if (r.task.voiceInteractor != null) {
2795            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2796        } else {
2797            finishRunningVoiceLocked();
2798            IVoiceInteractionSession session;
2799            if (last != null && ((session = last.task.voiceSession) != null
2800                    || (session = last.voiceSession) != null)) {
2801                // We had been in a voice interaction session, but now focused has
2802                // move to something different.  Just finish the session, we can't
2803                // return to it and retain the proper state and synchronization with
2804                // the voice interaction service.
2805                finishVoiceTask(session);
2806            }
2807        }
2808        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2809            mWindowManager.setFocusedApp(r.appToken, true);
2810        }
2811        applyUpdateLockStateLocked(r);
2812        applyUpdateVrModeLocked(r);
2813        if (mFocusedActivity.userId != mLastFocusedUserId) {
2814            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2815            mHandler.obtainMessage(
2816                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2817            mLastFocusedUserId = mFocusedActivity.userId;
2818        }
2819
2820        // Log a warning if the focused app is changed during the process. This could
2821        // indicate a problem of the focus setting logic!
2822        if (mFocusedActivity != r) Slog.w(TAG,
2823                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2824        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2825
2826        EventLogTags.writeAmFocusedActivity(
2827                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2828                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2829                reason);
2830        return true;
2831    }
2832
2833    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2834        if (mFocusedActivity != goingAway) {
2835            return;
2836        }
2837
2838        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2839        if (focusedStack != null) {
2840            final ActivityRecord top = focusedStack.topActivity();
2841            if (top != null && top.userId != mLastFocusedUserId) {
2842                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2843                mHandler.sendMessage(
2844                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2845                mLastFocusedUserId = top.userId;
2846            }
2847        }
2848
2849        // Try to move focus to another activity if possible.
2850        if (setFocusedActivityLocked(
2851                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2852            return;
2853        }
2854
2855        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2856                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2857        mFocusedActivity = null;
2858        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2859    }
2860
2861    @Override
2862    public void setFocusedStack(int stackId) {
2863        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2865        final long callingId = Binder.clearCallingIdentity();
2866        try {
2867            synchronized (this) {
2868                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2869                if (stack == null) {
2870                    return;
2871                }
2872                final ActivityRecord r = stack.topRunningActivityLocked();
2873                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2874                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2875                }
2876            }
2877        } finally {
2878            Binder.restoreCallingIdentity(callingId);
2879        }
2880    }
2881
2882    @Override
2883    public void setFocusedTask(int taskId) {
2884        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2885        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2886        final long callingId = Binder.clearCallingIdentity();
2887        try {
2888            synchronized (this) {
2889                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2890                if (task == null) {
2891                    return;
2892                }
2893                final ActivityRecord r = task.topRunningActivityLocked();
2894                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2895                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2896                }
2897            }
2898        } finally {
2899            Binder.restoreCallingIdentity(callingId);
2900        }
2901    }
2902
2903    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2904    @Override
2905    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2906        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2907        synchronized (this) {
2908            if (listener != null) {
2909                mTaskStackListeners.register(listener);
2910            }
2911        }
2912    }
2913
2914    @Override
2915    public void notifyActivityDrawn(IBinder token) {
2916        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2917        synchronized (this) {
2918            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2919            if (r != null) {
2920                r.task.stack.notifyActivityDrawnLocked(r);
2921            }
2922        }
2923    }
2924
2925    final void applyUpdateLockStateLocked(ActivityRecord r) {
2926        // Modifications to the UpdateLock state are done on our handler, outside
2927        // the activity manager's locks.  The new state is determined based on the
2928        // state *now* of the relevant activity record.  The object is passed to
2929        // the handler solely for logging detail, not to be consulted/modified.
2930        final boolean nextState = r != null && r.immersive;
2931        mHandler.sendMessage(
2932                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2933    }
2934
2935    final void applyUpdateVrModeLocked(ActivityRecord r) {
2936        mHandler.sendMessage(
2937                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2938    }
2939
2940    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2941        Message msg = Message.obtain();
2942        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2943        msg.obj = r.task.askedCompatMode ? null : r;
2944        mUiHandler.sendMessage(msg);
2945    }
2946
2947    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2948            String what, Object obj, ProcessRecord srcApp) {
2949        app.lastActivityTime = now;
2950
2951        if (app.activities.size() > 0) {
2952            // Don't want to touch dependent processes that are hosting activities.
2953            return index;
2954        }
2955
2956        int lrui = mLruProcesses.lastIndexOf(app);
2957        if (lrui < 0) {
2958            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2959                    + what + " " + obj + " from " + srcApp);
2960            return index;
2961        }
2962
2963        if (lrui >= index) {
2964            // Don't want to cause this to move dependent processes *back* in the
2965            // list as if they were less frequently used.
2966            return index;
2967        }
2968
2969        if (lrui >= mLruProcessActivityStart) {
2970            // Don't want to touch dependent processes that are hosting activities.
2971            return index;
2972        }
2973
2974        mLruProcesses.remove(lrui);
2975        if (index > 0) {
2976            index--;
2977        }
2978        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2979                + " in LRU list: " + app);
2980        mLruProcesses.add(index, app);
2981        return index;
2982    }
2983
2984    static void killProcessGroup(int uid, int pid) {
2985        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2986        Process.killProcessGroup(uid, pid);
2987        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2988    }
2989
2990    final void removeLruProcessLocked(ProcessRecord app) {
2991        int lrui = mLruProcesses.lastIndexOf(app);
2992        if (lrui >= 0) {
2993            if (!app.killed) {
2994                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2995                Process.killProcessQuiet(app.pid);
2996                killProcessGroup(app.info.uid, app.pid);
2997            }
2998            if (lrui <= mLruProcessActivityStart) {
2999                mLruProcessActivityStart--;
3000            }
3001            if (lrui <= mLruProcessServiceStart) {
3002                mLruProcessServiceStart--;
3003            }
3004            mLruProcesses.remove(lrui);
3005        }
3006    }
3007
3008    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3009            ProcessRecord client) {
3010        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3011                || app.treatLikeActivity;
3012        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3013        if (!activityChange && hasActivity) {
3014            // The process has activities, so we are only allowing activity-based adjustments
3015            // to move it.  It should be kept in the front of the list with other
3016            // processes that have activities, and we don't want those to change their
3017            // order except due to activity operations.
3018            return;
3019        }
3020
3021        mLruSeq++;
3022        final long now = SystemClock.uptimeMillis();
3023        app.lastActivityTime = now;
3024
3025        // First a quick reject: if the app is already at the position we will
3026        // put it, then there is nothing to do.
3027        if (hasActivity) {
3028            final int N = mLruProcesses.size();
3029            if (N > 0 && mLruProcesses.get(N-1) == app) {
3030                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3031                return;
3032            }
3033        } else {
3034            if (mLruProcessServiceStart > 0
3035                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3036                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3037                return;
3038            }
3039        }
3040
3041        int lrui = mLruProcesses.lastIndexOf(app);
3042
3043        if (app.persistent && lrui >= 0) {
3044            // We don't care about the position of persistent processes, as long as
3045            // they are in the list.
3046            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3047            return;
3048        }
3049
3050        /* In progress: compute new position first, so we can avoid doing work
3051           if the process is not actually going to move.  Not yet working.
3052        int addIndex;
3053        int nextIndex;
3054        boolean inActivity = false, inService = false;
3055        if (hasActivity) {
3056            // Process has activities, put it at the very tipsy-top.
3057            addIndex = mLruProcesses.size();
3058            nextIndex = mLruProcessServiceStart;
3059            inActivity = true;
3060        } else if (hasService) {
3061            // Process has services, put it at the top of the service list.
3062            addIndex = mLruProcessActivityStart;
3063            nextIndex = mLruProcessServiceStart;
3064            inActivity = true;
3065            inService = true;
3066        } else  {
3067            // Process not otherwise of interest, it goes to the top of the non-service area.
3068            addIndex = mLruProcessServiceStart;
3069            if (client != null) {
3070                int clientIndex = mLruProcesses.lastIndexOf(client);
3071                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3072                        + app);
3073                if (clientIndex >= 0 && addIndex > clientIndex) {
3074                    addIndex = clientIndex;
3075                }
3076            }
3077            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3078        }
3079
3080        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3081                + mLruProcessActivityStart + "): " + app);
3082        */
3083
3084        if (lrui >= 0) {
3085            if (lrui < mLruProcessActivityStart) {
3086                mLruProcessActivityStart--;
3087            }
3088            if (lrui < mLruProcessServiceStart) {
3089                mLruProcessServiceStart--;
3090            }
3091            /*
3092            if (addIndex > lrui) {
3093                addIndex--;
3094            }
3095            if (nextIndex > lrui) {
3096                nextIndex--;
3097            }
3098            */
3099            mLruProcesses.remove(lrui);
3100        }
3101
3102        /*
3103        mLruProcesses.add(addIndex, app);
3104        if (inActivity) {
3105            mLruProcessActivityStart++;
3106        }
3107        if (inService) {
3108            mLruProcessActivityStart++;
3109        }
3110        */
3111
3112        int nextIndex;
3113        if (hasActivity) {
3114            final int N = mLruProcesses.size();
3115            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3116                // Process doesn't have activities, but has clients with
3117                // activities...  move it up, but one below the top (the top
3118                // should always have a real activity).
3119                if (DEBUG_LRU) Slog.d(TAG_LRU,
3120                        "Adding to second-top of LRU activity list: " + app);
3121                mLruProcesses.add(N - 1, app);
3122                // To keep it from spamming the LRU list (by making a bunch of clients),
3123                // we will push down any other entries owned by the app.
3124                final int uid = app.info.uid;
3125                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3126                    ProcessRecord subProc = mLruProcesses.get(i);
3127                    if (subProc.info.uid == uid) {
3128                        // We want to push this one down the list.  If the process after
3129                        // it is for the same uid, however, don't do so, because we don't
3130                        // want them internally to be re-ordered.
3131                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3132                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3133                                    "Pushing uid " + uid + " swapping at " + i + ": "
3134                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3135                            ProcessRecord tmp = mLruProcesses.get(i);
3136                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3137                            mLruProcesses.set(i - 1, tmp);
3138                            i--;
3139                        }
3140                    } else {
3141                        // A gap, we can stop here.
3142                        break;
3143                    }
3144                }
3145            } else {
3146                // Process has activities, put it at the very tipsy-top.
3147                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3148                mLruProcesses.add(app);
3149            }
3150            nextIndex = mLruProcessServiceStart;
3151        } else if (hasService) {
3152            // Process has services, put it at the top of the service list.
3153            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3154            mLruProcesses.add(mLruProcessActivityStart, app);
3155            nextIndex = mLruProcessServiceStart;
3156            mLruProcessActivityStart++;
3157        } else  {
3158            // Process not otherwise of interest, it goes to the top of the non-service area.
3159            int index = mLruProcessServiceStart;
3160            if (client != null) {
3161                // If there is a client, don't allow the process to be moved up higher
3162                // in the list than that client.
3163                int clientIndex = mLruProcesses.lastIndexOf(client);
3164                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3165                        + " when updating " + app);
3166                if (clientIndex <= lrui) {
3167                    // Don't allow the client index restriction to push it down farther in the
3168                    // list than it already is.
3169                    clientIndex = lrui;
3170                }
3171                if (clientIndex >= 0 && index > clientIndex) {
3172                    index = clientIndex;
3173                }
3174            }
3175            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3176            mLruProcesses.add(index, app);
3177            nextIndex = index-1;
3178            mLruProcessActivityStart++;
3179            mLruProcessServiceStart++;
3180        }
3181
3182        // If the app is currently using a content provider or service,
3183        // bump those processes as well.
3184        for (int j=app.connections.size()-1; j>=0; j--) {
3185            ConnectionRecord cr = app.connections.valueAt(j);
3186            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3187                    && cr.binding.service.app != null
3188                    && cr.binding.service.app.lruSeq != mLruSeq
3189                    && !cr.binding.service.app.persistent) {
3190                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3191                        "service connection", cr, app);
3192            }
3193        }
3194        for (int j=app.conProviders.size()-1; j>=0; j--) {
3195            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3196            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3197                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3198                        "provider reference", cpr, app);
3199            }
3200        }
3201    }
3202
3203    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3204        if (uid == Process.SYSTEM_UID) {
3205            // The system gets to run in any process.  If there are multiple
3206            // processes with the same uid, just pick the first (this
3207            // should never happen).
3208            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3209            if (procs == null) return null;
3210            final int procCount = procs.size();
3211            for (int i = 0; i < procCount; i++) {
3212                final int procUid = procs.keyAt(i);
3213                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3214                    // Don't use an app process or different user process for system component.
3215                    continue;
3216                }
3217                return procs.valueAt(i);
3218            }
3219        }
3220        ProcessRecord proc = mProcessNames.get(processName, uid);
3221        if (false && proc != null && !keepIfLarge
3222                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3223                && proc.lastCachedPss >= 4000) {
3224            // Turn this condition on to cause killing to happen regularly, for testing.
3225            if (proc.baseProcessTracker != null) {
3226                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3227            }
3228            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3229        } else if (proc != null && !keepIfLarge
3230                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3231                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3232            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3233            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3234                if (proc.baseProcessTracker != null) {
3235                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3236                }
3237                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3238            }
3239        }
3240        return proc;
3241    }
3242
3243    void notifyPackageUse(String packageName) {
3244        IPackageManager pm = AppGlobals.getPackageManager();
3245        try {
3246            pm.notifyPackageUse(packageName);
3247        } catch (RemoteException e) {
3248        }
3249    }
3250
3251    boolean isNextTransitionForward() {
3252        int transit = mWindowManager.getPendingAppTransition();
3253        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3254                || transit == AppTransition.TRANSIT_TASK_OPEN
3255                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3256    }
3257
3258    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3259            String processName, String abiOverride, int uid, Runnable crashHandler) {
3260        synchronized(this) {
3261            ApplicationInfo info = new ApplicationInfo();
3262            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3263            // For isolated processes, the former contains the parent's uid and the latter the
3264            // actual uid of the isolated process.
3265            // In the special case introduced by this method (which is, starting an isolated
3266            // process directly from the SystemServer without an actual parent app process) the
3267            // closest thing to a parent's uid is SYSTEM_UID.
3268            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3269            // the |isolated| logic in the ProcessRecord constructor.
3270            info.uid = Process.SYSTEM_UID;
3271            info.processName = processName;
3272            info.className = entryPoint;
3273            info.packageName = "android";
3274            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3275                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3276                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3277                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3278                    crashHandler);
3279            return proc != null ? proc.pid : 0;
3280        }
3281    }
3282
3283    final ProcessRecord startProcessLocked(String processName,
3284            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3285            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3286            boolean isolated, boolean keepIfLarge) {
3287        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3288                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3289                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3290                null /* crashHandler */);
3291    }
3292
3293    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3294            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3295            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3296            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3297        long startTime = SystemClock.elapsedRealtime();
3298        ProcessRecord app;
3299        if (!isolated) {
3300            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3301            checkTime(startTime, "startProcess: after getProcessRecord");
3302
3303            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3304                // If we are in the background, then check to see if this process
3305                // is bad.  If so, we will just silently fail.
3306                if (mAppErrors.isBadProcessLocked(info)) {
3307                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3308                            + "/" + info.processName);
3309                    return null;
3310                }
3311            } else {
3312                // When the user is explicitly starting a process, then clear its
3313                // crash count so that we won't make it bad until they see at
3314                // least one crash dialog again, and make the process good again
3315                // if it had been bad.
3316                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3317                        + "/" + info.processName);
3318                mAppErrors.resetProcessCrashTimeLocked(info);
3319                if (mAppErrors.isBadProcessLocked(info)) {
3320                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3321                            UserHandle.getUserId(info.uid), info.uid,
3322                            info.processName);
3323                    mAppErrors.clearBadProcessLocked(info);
3324                    if (app != null) {
3325                        app.bad = false;
3326                    }
3327                }
3328            }
3329        } else {
3330            // If this is an isolated process, it can't re-use an existing process.
3331            app = null;
3332        }
3333
3334        // app launch boost for big.little configurations
3335        // use cpusets to migrate freshly launched tasks to big cores
3336        synchronized(ActivityManagerService.this) {
3337            nativeMigrateToBoost();
3338            mIsBoosted = true;
3339            mBoostStartTime = SystemClock.uptimeMillis();
3340            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3341            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3342        }
3343
3344        // We don't have to do anything more if:
3345        // (1) There is an existing application record; and
3346        // (2) The caller doesn't think it is dead, OR there is no thread
3347        //     object attached to it so we know it couldn't have crashed; and
3348        // (3) There is a pid assigned to it, so it is either starting or
3349        //     already running.
3350        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3351                + " app=" + app + " knownToBeDead=" + knownToBeDead
3352                + " thread=" + (app != null ? app.thread : null)
3353                + " pid=" + (app != null ? app.pid : -1));
3354        if (app != null && app.pid > 0) {
3355            if (!knownToBeDead || app.thread == null) {
3356                // We already have the app running, or are waiting for it to
3357                // come up (we have a pid but not yet its thread), so keep it.
3358                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3359                // If this is a new package in the process, add the package to the list
3360                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3361                checkTime(startTime, "startProcess: done, added package to proc");
3362                return app;
3363            }
3364
3365            // An application record is attached to a previous process,
3366            // clean it up now.
3367            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3368            checkTime(startTime, "startProcess: bad proc running, killing");
3369            killProcessGroup(app.info.uid, app.pid);
3370            handleAppDiedLocked(app, true, true);
3371            checkTime(startTime, "startProcess: done killing old proc");
3372        }
3373
3374        String hostingNameStr = hostingName != null
3375                ? hostingName.flattenToShortString() : null;
3376
3377        if (app == null) {
3378            checkTime(startTime, "startProcess: creating new process record");
3379            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3380            if (app == null) {
3381                Slog.w(TAG, "Failed making new process record for "
3382                        + processName + "/" + info.uid + " isolated=" + isolated);
3383                return null;
3384            }
3385            app.crashHandler = crashHandler;
3386            checkTime(startTime, "startProcess: done creating new process record");
3387        } else {
3388            // If this is a new package in the process, add the package to the list
3389            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3390            checkTime(startTime, "startProcess: added package to existing proc");
3391        }
3392
3393        // If the system is not ready yet, then hold off on starting this
3394        // process until it is.
3395        if (!mProcessesReady
3396                && !isAllowedWhileBooting(info)
3397                && !allowWhileBooting) {
3398            if (!mProcessesOnHold.contains(app)) {
3399                mProcessesOnHold.add(app);
3400            }
3401            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3402                    "System not ready, putting on hold: " + app);
3403            checkTime(startTime, "startProcess: returning with proc on hold");
3404            return app;
3405        }
3406
3407        checkTime(startTime, "startProcess: stepping in to startProcess");
3408        startProcessLocked(
3409                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3410        checkTime(startTime, "startProcess: done starting proc!");
3411        return (app.pid != 0) ? app : null;
3412    }
3413
3414    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3415        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3416    }
3417
3418    private final void startProcessLocked(ProcessRecord app,
3419            String hostingType, String hostingNameStr) {
3420        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3421                null /* entryPoint */, null /* entryPointArgs */);
3422    }
3423
3424    private final void startProcessLocked(ProcessRecord app, String hostingType,
3425            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3426        long startTime = SystemClock.elapsedRealtime();
3427        if (app.pid > 0 && app.pid != MY_PID) {
3428            checkTime(startTime, "startProcess: removing from pids map");
3429            synchronized (mPidsSelfLocked) {
3430                mPidsSelfLocked.remove(app.pid);
3431                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3432            }
3433            checkTime(startTime, "startProcess: done removing from pids map");
3434            app.setPid(0);
3435        }
3436
3437        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3438                "startProcessLocked removing on hold: " + app);
3439        mProcessesOnHold.remove(app);
3440
3441        checkTime(startTime, "startProcess: starting to update cpu stats");
3442        updateCpuStats();
3443        checkTime(startTime, "startProcess: done updating cpu stats");
3444
3445        try {
3446            try {
3447                final int userId = UserHandle.getUserId(app.uid);
3448                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3449            } catch (RemoteException e) {
3450                throw e.rethrowAsRuntimeException();
3451            }
3452
3453            int uid = app.uid;
3454            int[] gids = null;
3455            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3456            if (!app.isolated) {
3457                int[] permGids = null;
3458                try {
3459                    checkTime(startTime, "startProcess: getting gids from package manager");
3460                    final IPackageManager pm = AppGlobals.getPackageManager();
3461                    permGids = pm.getPackageGids(app.info.packageName,
3462                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3463                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3464                            MountServiceInternal.class);
3465                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3466                            app.info.packageName);
3467                } catch (RemoteException e) {
3468                    throw e.rethrowAsRuntimeException();
3469                }
3470
3471                /*
3472                 * Add shared application and profile GIDs so applications can share some
3473                 * resources like shared libraries and access user-wide resources
3474                 */
3475                if (ArrayUtils.isEmpty(permGids)) {
3476                    gids = new int[2];
3477                } else {
3478                    gids = new int[permGids.length + 2];
3479                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3480                }
3481                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3482                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3483            }
3484            checkTime(startTime, "startProcess: building args");
3485            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3486                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3487                        && mTopComponent != null
3488                        && app.processName.equals(mTopComponent.getPackageName())) {
3489                    uid = 0;
3490                }
3491                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3492                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3493                    uid = 0;
3494                }
3495            }
3496            int debugFlags = 0;
3497            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3498                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3499                // Also turn on CheckJNI for debuggable apps. It's quite
3500                // awkward to turn on otherwise.
3501                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3502            }
3503            // Run the app in safe mode if its manifest requests so or the
3504            // system is booted in safe mode.
3505            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3506                mSafeMode == true) {
3507                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3508            }
3509            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3510                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3511            }
3512            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3513            if ("true".equals(genDebugInfoProperty)) {
3514                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3515            }
3516            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3517                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3518            }
3519            if ("1".equals(SystemProperties.get("debug.assert"))) {
3520                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3521            }
3522            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3523                // Enable all debug flags required by the native debugger.
3524                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3525                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3526                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3527                mNativeDebuggingApp = null;
3528            }
3529
3530            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3531            if (requiredAbi == null) {
3532                requiredAbi = Build.SUPPORTED_ABIS[0];
3533            }
3534
3535            String instructionSet = null;
3536            if (app.info.primaryCpuAbi != null) {
3537                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3538            }
3539
3540            app.gids = gids;
3541            app.requiredAbi = requiredAbi;
3542            app.instructionSet = instructionSet;
3543
3544            // Start the process.  It will either succeed and return a result containing
3545            // the PID of the new process, or else throw a RuntimeException.
3546            boolean isActivityProcess = (entryPoint == null);
3547            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3548            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3549                    app.processName);
3550            checkTime(startTime, "startProcess: asking zygote to start proc");
3551            Process.ProcessStartResult startResult = Process.start(entryPoint,
3552                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3553                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3554                    app.info.dataDir, entryPointArgs);
3555            checkTime(startTime, "startProcess: returned from zygote!");
3556            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3557
3558            if (app.isolated) {
3559                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3560            }
3561            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3562            checkTime(startTime, "startProcess: done updating battery stats");
3563
3564            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3565                    UserHandle.getUserId(uid), startResult.pid, uid,
3566                    app.processName, hostingType,
3567                    hostingNameStr != null ? hostingNameStr : "");
3568
3569            mProcessStartLogger.logIfNeededLocked(app, startResult);
3570
3571            if (app.persistent) {
3572                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3573            }
3574
3575            if (DEBUG_PROCESSES) {
3576                checkTime(startTime, "startProcess: building log message");
3577                StringBuilder buf = mStringBuilder;
3578                buf.setLength(0);
3579                buf.append("Start proc ");
3580                buf.append(startResult.pid);
3581                buf.append(':');
3582                buf.append(app.processName);
3583                buf.append('/');
3584                UserHandle.formatUid(buf, uid);
3585                if (!isActivityProcess) {
3586                    buf.append(" [");
3587                    buf.append(entryPoint);
3588                    buf.append("]");
3589                }
3590                buf.append(" for ");
3591                buf.append(hostingType);
3592                if (hostingNameStr != null) {
3593                    buf.append(" ");
3594                    buf.append(hostingNameStr);
3595                }
3596                Slog.i(TAG, buf.toString());
3597            }
3598            app.setPid(startResult.pid);
3599            app.usingWrapper = startResult.usingWrapper;
3600            app.removed = false;
3601            app.killed = false;
3602            app.killedByAm = false;
3603            checkTime(startTime, "startProcess: starting to update pids map");
3604            synchronized (mPidsSelfLocked) {
3605                this.mPidsSelfLocked.put(startResult.pid, app);
3606                if (isActivityProcess) {
3607                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3608                    msg.obj = app;
3609                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3610                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3611                }
3612            }
3613            checkTime(startTime, "startProcess: done updating pids map");
3614        } catch (RuntimeException e) {
3615            // XXX do better error recovery.
3616            app.setPid(0);
3617            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3618            if (app.isolated) {
3619                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3620            }
3621            Slog.e(TAG, "Failure starting process " + app.processName, e);
3622        }
3623    }
3624
3625    void updateUsageStats(ActivityRecord component, boolean resumed) {
3626        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3627                "updateUsageStats: comp=" + component + "res=" + resumed);
3628        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3629        if (resumed) {
3630            if (mUsageStatsService != null) {
3631                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3632                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3633            }
3634            synchronized (stats) {
3635                stats.noteActivityResumedLocked(component.app.uid);
3636            }
3637        } else {
3638            if (mUsageStatsService != null) {
3639                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3640                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3641            }
3642            synchronized (stats) {
3643                stats.noteActivityPausedLocked(component.app.uid);
3644            }
3645        }
3646    }
3647
3648    Intent getHomeIntent() {
3649        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3650        intent.setComponent(mTopComponent);
3651        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3652        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3653            intent.addCategory(Intent.CATEGORY_HOME);
3654        }
3655        return intent;
3656    }
3657
3658    boolean startHomeActivityLocked(int userId, String reason) {
3659        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3660                && mTopAction == null) {
3661            // We are running in factory test mode, but unable to find
3662            // the factory test app, so just sit around displaying the
3663            // error message and don't try to start anything.
3664            return false;
3665        }
3666        Intent intent = getHomeIntent();
3667        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3668        if (aInfo != null) {
3669            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3670            // Don't do this if the home app is currently being
3671            // instrumented.
3672            aInfo = new ActivityInfo(aInfo);
3673            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3674            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3675                    aInfo.applicationInfo.uid, true);
3676            if (app == null || app.instrumentationClass == null) {
3677                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3678                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3679            }
3680        }
3681
3682        return true;
3683    }
3684
3685    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3686        ActivityInfo ai = null;
3687        ComponentName comp = intent.getComponent();
3688        try {
3689            if (comp != null) {
3690                // Factory test.
3691                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3692            } else {
3693                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3694                        intent,
3695                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3696                        flags, userId);
3697
3698                if (info != null) {
3699                    ai = info.activityInfo;
3700                }
3701            }
3702        } catch (RemoteException e) {
3703            // ignore
3704        }
3705
3706        return ai;
3707    }
3708
3709    /**
3710     * Starts the "new version setup screen" if appropriate.
3711     */
3712    void startSetupActivityLocked() {
3713        // Only do this once per boot.
3714        if (mCheckedForSetup) {
3715            return;
3716        }
3717
3718        // We will show this screen if the current one is a different
3719        // version than the last one shown, and we are not running in
3720        // low-level factory test mode.
3721        final ContentResolver resolver = mContext.getContentResolver();
3722        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3723                Settings.Global.getInt(resolver,
3724                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3725            mCheckedForSetup = true;
3726
3727            // See if we should be showing the platform update setup UI.
3728            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3729            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3730                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3731            if (!ris.isEmpty()) {
3732                final ResolveInfo ri = ris.get(0);
3733                String vers = ri.activityInfo.metaData != null
3734                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3735                        : null;
3736                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3737                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3738                            Intent.METADATA_SETUP_VERSION);
3739                }
3740                String lastVers = Settings.Secure.getString(
3741                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3742                if (vers != null && !vers.equals(lastVers)) {
3743                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3744                    intent.setComponent(new ComponentName(
3745                            ri.activityInfo.packageName, ri.activityInfo.name));
3746                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3747                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3748                            null, 0, 0, 0, null, false, false, null, null, null);
3749                }
3750            }
3751        }
3752    }
3753
3754    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3755        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3756    }
3757
3758    void enforceNotIsolatedCaller(String caller) {
3759        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3760            throw new SecurityException("Isolated process not allowed to call " + caller);
3761        }
3762    }
3763
3764    void enforceShellRestriction(String restriction, int userHandle) {
3765        if (Binder.getCallingUid() == Process.SHELL_UID) {
3766            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3767                throw new SecurityException("Shell does not have permission to access user "
3768                        + userHandle);
3769            }
3770        }
3771    }
3772
3773    @Override
3774    public int getFrontActivityScreenCompatMode() {
3775        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3776        synchronized (this) {
3777            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3778        }
3779    }
3780
3781    @Override
3782    public void setFrontActivityScreenCompatMode(int mode) {
3783        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3784                "setFrontActivityScreenCompatMode");
3785        synchronized (this) {
3786            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3787        }
3788    }
3789
3790    @Override
3791    public int getPackageScreenCompatMode(String packageName) {
3792        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3793        synchronized (this) {
3794            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3795        }
3796    }
3797
3798    @Override
3799    public void setPackageScreenCompatMode(String packageName, int mode) {
3800        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3801                "setPackageScreenCompatMode");
3802        synchronized (this) {
3803            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3804        }
3805    }
3806
3807    @Override
3808    public boolean getPackageAskScreenCompat(String packageName) {
3809        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3810        synchronized (this) {
3811            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3812        }
3813    }
3814
3815    @Override
3816    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3817        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3818                "setPackageAskScreenCompat");
3819        synchronized (this) {
3820            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3821        }
3822    }
3823
3824    private boolean hasUsageStatsPermission(String callingPackage) {
3825        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3826                Binder.getCallingUid(), callingPackage);
3827        if (mode == AppOpsManager.MODE_DEFAULT) {
3828            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3829                    == PackageManager.PERMISSION_GRANTED;
3830        }
3831        return mode == AppOpsManager.MODE_ALLOWED;
3832    }
3833
3834    @Override
3835    public int getPackageProcessState(String packageName, String callingPackage) {
3836        if (!hasUsageStatsPermission(callingPackage)) {
3837            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3838                    "getPackageProcessState");
3839        }
3840
3841        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3842        synchronized (this) {
3843            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3844                final ProcessRecord proc = mLruProcesses.get(i);
3845                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3846                        || procState > proc.setProcState) {
3847                    boolean found = false;
3848                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3849                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3850                            procState = proc.setProcState;
3851                            found = true;
3852                        }
3853                    }
3854                    if (proc.pkgDeps != null && !found) {
3855                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3856                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3857                                procState = proc.setProcState;
3858                                break;
3859                            }
3860                        }
3861                    }
3862                }
3863            }
3864        }
3865        return procState;
3866    }
3867
3868    @Override
3869    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3870        synchronized (this) {
3871            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3872            if (app == null) {
3873                return false;
3874            }
3875            if (app.trimMemoryLevel < level && app.thread != null &&
3876                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3877                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3878                try {
3879                    app.thread.scheduleTrimMemory(level);
3880                    app.trimMemoryLevel = level;
3881                    return true;
3882                } catch (RemoteException e) {
3883                    // Fallthrough to failure case.
3884                }
3885            }
3886        }
3887        return false;
3888    }
3889
3890    private void dispatchProcessesChanged() {
3891        int N;
3892        synchronized (this) {
3893            N = mPendingProcessChanges.size();
3894            if (mActiveProcessChanges.length < N) {
3895                mActiveProcessChanges = new ProcessChangeItem[N];
3896            }
3897            mPendingProcessChanges.toArray(mActiveProcessChanges);
3898            mPendingProcessChanges.clear();
3899            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3900                    "*** Delivering " + N + " process changes");
3901        }
3902
3903        int i = mProcessObservers.beginBroadcast();
3904        while (i > 0) {
3905            i--;
3906            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3907            if (observer != null) {
3908                try {
3909                    for (int j=0; j<N; j++) {
3910                        ProcessChangeItem item = mActiveProcessChanges[j];
3911                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3912                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3913                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3914                                    + item.uid + ": " + item.foregroundActivities);
3915                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3916                                    item.foregroundActivities);
3917                        }
3918                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3919                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3920                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3921                                    + ": " + item.processState);
3922                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3923                        }
3924                    }
3925                } catch (RemoteException e) {
3926                }
3927            }
3928        }
3929        mProcessObservers.finishBroadcast();
3930
3931        synchronized (this) {
3932            for (int j=0; j<N; j++) {
3933                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3934            }
3935        }
3936    }
3937
3938    private void dispatchProcessDied(int pid, int uid) {
3939        int i = mProcessObservers.beginBroadcast();
3940        while (i > 0) {
3941            i--;
3942            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3943            if (observer != null) {
3944                try {
3945                    observer.onProcessDied(pid, uid);
3946                } catch (RemoteException e) {
3947                }
3948            }
3949        }
3950        mProcessObservers.finishBroadcast();
3951    }
3952
3953    private void dispatchUidsChanged() {
3954        int N;
3955        synchronized (this) {
3956            N = mPendingUidChanges.size();
3957            if (mActiveUidChanges.length < N) {
3958                mActiveUidChanges = new UidRecord.ChangeItem[N];
3959            }
3960            for (int i=0; i<N; i++) {
3961                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3962                mActiveUidChanges[i] = change;
3963                if (change.uidRecord != null) {
3964                    change.uidRecord.pendingChange = null;
3965                    change.uidRecord = null;
3966                }
3967            }
3968            mPendingUidChanges.clear();
3969            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3970                    "*** Delivering " + N + " uid changes");
3971        }
3972
3973        if (mLocalPowerManager != null) {
3974            for (int j=0; j<N; j++) {
3975                UidRecord.ChangeItem item = mActiveUidChanges[j];
3976                if (item.change == UidRecord.CHANGE_GONE
3977                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3978                    mLocalPowerManager.uidGone(item.uid);
3979                } else {
3980                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3981                }
3982            }
3983        }
3984
3985        int i = mUidObservers.beginBroadcast();
3986        while (i > 0) {
3987            i--;
3988            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3989            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3990            if (observer != null) {
3991                try {
3992                    for (int j=0; j<N; j++) {
3993                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3994                        final int change = item.change;
3995                        UidRecord validateUid = null;
3996                        if (VALIDATE_UID_STATES && i == 0) {
3997                            validateUid = mValidateUids.get(item.uid);
3998                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3999                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4000                                validateUid = new UidRecord(item.uid);
4001                                mValidateUids.put(item.uid, validateUid);
4002                            }
4003                        }
4004                        if (change == UidRecord.CHANGE_IDLE
4005                                || change == UidRecord.CHANGE_GONE_IDLE) {
4006                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4007                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4008                                        "UID idle uid=" + item.uid);
4009                                observer.onUidIdle(item.uid);
4010                            }
4011                            if (VALIDATE_UID_STATES && i == 0) {
4012                                if (validateUid != null) {
4013                                    validateUid.idle = true;
4014                                }
4015                            }
4016                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4017                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4018                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4019                                        "UID active uid=" + item.uid);
4020                                observer.onUidActive(item.uid);
4021                            }
4022                            if (VALIDATE_UID_STATES && i == 0) {
4023                                validateUid.idle = false;
4024                            }
4025                        }
4026                        if (change == UidRecord.CHANGE_GONE
4027                                || change == UidRecord.CHANGE_GONE_IDLE) {
4028                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4029                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4030                                        "UID gone uid=" + item.uid);
4031                                observer.onUidGone(item.uid);
4032                            }
4033                            if (VALIDATE_UID_STATES && i == 0) {
4034                                if (validateUid != null) {
4035                                    mValidateUids.remove(item.uid);
4036                                }
4037                            }
4038                        } else {
4039                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4040                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4041                                        "UID CHANGED uid=" + item.uid
4042                                                + ": " + item.processState);
4043                                observer.onUidStateChanged(item.uid, item.processState);
4044                            }
4045                            if (VALIDATE_UID_STATES && i == 0) {
4046                                validateUid.curProcState = validateUid.setProcState
4047                                        = item.processState;
4048                            }
4049                        }
4050                    }
4051                } catch (RemoteException e) {
4052                }
4053            }
4054        }
4055        mUidObservers.finishBroadcast();
4056
4057        synchronized (this) {
4058            for (int j=0; j<N; j++) {
4059                mAvailUidChanges.add(mActiveUidChanges[j]);
4060            }
4061        }
4062    }
4063
4064    @Override
4065    public final int startActivity(IApplicationThread caller, String callingPackage,
4066            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4067            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4068        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4069                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4070                UserHandle.getCallingUserId());
4071    }
4072
4073    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4074        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4075        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4076                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4077                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4078
4079        // TODO: Switch to user app stacks here.
4080        String mimeType = intent.getType();
4081        final Uri data = intent.getData();
4082        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4083            mimeType = getProviderMimeType(data, userId);
4084        }
4085        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4086
4087        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4088        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4089                null, 0, 0, null, null, null, null, false, userId, container, null);
4090    }
4091
4092    @Override
4093    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4094            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4095            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4096        enforceNotIsolatedCaller("startActivity");
4097        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4098                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4099        // TODO: Switch to user app stacks here.
4100        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4101                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4102                profilerInfo, null, null, bOptions, false, userId, null, null);
4103    }
4104
4105    @Override
4106    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4107            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4108            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4109            int userId) {
4110
4111        // This is very dangerous -- it allows you to perform a start activity (including
4112        // permission grants) as any app that may launch one of your own activities.  So
4113        // we will only allow this to be done from activities that are part of the core framework,
4114        // and then only when they are running as the system.
4115        final ActivityRecord sourceRecord;
4116        final int targetUid;
4117        final String targetPackage;
4118        synchronized (this) {
4119            if (resultTo == null) {
4120                throw new SecurityException("Must be called from an activity");
4121            }
4122            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4123            if (sourceRecord == null) {
4124                throw new SecurityException("Called with bad activity token: " + resultTo);
4125            }
4126            if (!sourceRecord.info.packageName.equals("android")) {
4127                throw new SecurityException(
4128                        "Must be called from an activity that is declared in the android package");
4129            }
4130            if (sourceRecord.app == null) {
4131                throw new SecurityException("Called without a process attached to activity");
4132            }
4133            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4134                // This is still okay, as long as this activity is running under the
4135                // uid of the original calling activity.
4136                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4137                    throw new SecurityException(
4138                            "Calling activity in uid " + sourceRecord.app.uid
4139                                    + " must be system uid or original calling uid "
4140                                    + sourceRecord.launchedFromUid);
4141                }
4142            }
4143            if (ignoreTargetSecurity) {
4144                if (intent.getComponent() == null) {
4145                    throw new SecurityException(
4146                            "Component must be specified with ignoreTargetSecurity");
4147                }
4148                if (intent.getSelector() != null) {
4149                    throw new SecurityException(
4150                            "Selector not allowed with ignoreTargetSecurity");
4151                }
4152            }
4153            targetUid = sourceRecord.launchedFromUid;
4154            targetPackage = sourceRecord.launchedFromPackage;
4155        }
4156
4157        if (userId == UserHandle.USER_NULL) {
4158            userId = UserHandle.getUserId(sourceRecord.app.uid);
4159        }
4160
4161        // TODO: Switch to user app stacks here.
4162        try {
4163            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4164                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4165                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4166            return ret;
4167        } catch (SecurityException e) {
4168            // XXX need to figure out how to propagate to original app.
4169            // A SecurityException here is generally actually a fault of the original
4170            // calling activity (such as a fairly granting permissions), so propagate it
4171            // back to them.
4172            /*
4173            StringBuilder msg = new StringBuilder();
4174            msg.append("While launching");
4175            msg.append(intent.toString());
4176            msg.append(": ");
4177            msg.append(e.getMessage());
4178            */
4179            throw e;
4180        }
4181    }
4182
4183    @Override
4184    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4185            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4186            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4187        enforceNotIsolatedCaller("startActivityAndWait");
4188        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4189                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4190        WaitResult res = new WaitResult();
4191        // TODO: Switch to user app stacks here.
4192        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4193                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4194                bOptions, false, userId, null, null);
4195        return res;
4196    }
4197
4198    @Override
4199    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4200            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4201            int startFlags, Configuration config, Bundle bOptions, int userId) {
4202        enforceNotIsolatedCaller("startActivityWithConfig");
4203        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4204                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4205        // TODO: Switch to user app stacks here.
4206        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4207                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4208                null, null, config, bOptions, false, userId, null, null);
4209        return ret;
4210    }
4211
4212    @Override
4213    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4214            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4215            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4216            throws TransactionTooLargeException {
4217        enforceNotIsolatedCaller("startActivityIntentSender");
4218        // Refuse possible leaked file descriptors
4219        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4220            throw new IllegalArgumentException("File descriptors passed in Intent");
4221        }
4222
4223        IIntentSender sender = intent.getTarget();
4224        if (!(sender instanceof PendingIntentRecord)) {
4225            throw new IllegalArgumentException("Bad PendingIntent object");
4226        }
4227
4228        PendingIntentRecord pir = (PendingIntentRecord)sender;
4229
4230        synchronized (this) {
4231            // If this is coming from the currently resumed activity, it is
4232            // effectively saying that app switches are allowed at this point.
4233            final ActivityStack stack = getFocusedStack();
4234            if (stack.mResumedActivity != null &&
4235                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4236                mAppSwitchesAllowedTime = 0;
4237            }
4238        }
4239        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4240                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4241        return ret;
4242    }
4243
4244    @Override
4245    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4246            Intent intent, String resolvedType, IVoiceInteractionSession session,
4247            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4248            Bundle bOptions, int userId) {
4249        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4250                != PackageManager.PERMISSION_GRANTED) {
4251            String msg = "Permission Denial: startVoiceActivity() from pid="
4252                    + Binder.getCallingPid()
4253                    + ", uid=" + Binder.getCallingUid()
4254                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4255            Slog.w(TAG, msg);
4256            throw new SecurityException(msg);
4257        }
4258        if (session == null || interactor == null) {
4259            throw new NullPointerException("null session or interactor");
4260        }
4261        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4262                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4263        // TODO: Switch to user app stacks here.
4264        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4265                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4266                null, bOptions, false, userId, null, null);
4267    }
4268
4269    @Override
4270    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4271            throws RemoteException {
4272        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4273        synchronized (this) {
4274            ActivityRecord activity = getFocusedStack().topActivity();
4275            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4276                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4277            }
4278            if (mRunningVoice != null || activity.task.voiceSession != null
4279                    || activity.voiceSession != null) {
4280                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4281                return;
4282            }
4283            if (activity.pendingVoiceInteractionStart) {
4284                Slog.w(TAG, "Pending start of voice interaction already.");
4285                return;
4286            }
4287            activity.pendingVoiceInteractionStart = true;
4288        }
4289        LocalServices.getService(VoiceInteractionManagerInternal.class)
4290                .startLocalVoiceInteraction(callingActivity, options);
4291    }
4292
4293    @Override
4294    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4295        LocalServices.getService(VoiceInteractionManagerInternal.class)
4296                .stopLocalVoiceInteraction(callingActivity);
4297    }
4298
4299    @Override
4300    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4301        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4302                .supportsLocalVoiceInteraction();
4303    }
4304
4305    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4306            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4307        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4308        if (activityToCallback == null) return;
4309        activityToCallback.setVoiceSessionLocked(voiceSession);
4310
4311        // Inform the activity
4312        try {
4313            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4314                    voiceInteractor);
4315            long token = Binder.clearCallingIdentity();
4316            try {
4317                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4318            } finally {
4319                Binder.restoreCallingIdentity(token);
4320            }
4321            // TODO: VI Should we cache the activity so that it's easier to find later
4322            // rather than scan through all the stacks and activities?
4323        } catch (RemoteException re) {
4324            activityToCallback.clearVoiceSessionLocked();
4325            // TODO: VI Should this terminate the voice session?
4326        }
4327    }
4328
4329    @Override
4330    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4331        synchronized (this) {
4332            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4333                if (keepAwake) {
4334                    mVoiceWakeLock.acquire();
4335                } else {
4336                    mVoiceWakeLock.release();
4337                }
4338            }
4339        }
4340    }
4341
4342    @Override
4343    public boolean startNextMatchingActivity(IBinder callingActivity,
4344            Intent intent, Bundle bOptions) {
4345        // Refuse possible leaked file descriptors
4346        if (intent != null && intent.hasFileDescriptors() == true) {
4347            throw new IllegalArgumentException("File descriptors passed in Intent");
4348        }
4349        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4350
4351        synchronized (this) {
4352            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4353            if (r == null) {
4354                ActivityOptions.abort(options);
4355                return false;
4356            }
4357            if (r.app == null || r.app.thread == null) {
4358                // The caller is not running...  d'oh!
4359                ActivityOptions.abort(options);
4360                return false;
4361            }
4362            intent = new Intent(intent);
4363            // The caller is not allowed to change the data.
4364            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4365            // And we are resetting to find the next component...
4366            intent.setComponent(null);
4367
4368            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4369
4370            ActivityInfo aInfo = null;
4371            try {
4372                List<ResolveInfo> resolves =
4373                    AppGlobals.getPackageManager().queryIntentActivities(
4374                            intent, r.resolvedType,
4375                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4376                            UserHandle.getCallingUserId());
4377
4378                // Look for the original activity in the list...
4379                final int N = resolves != null ? resolves.size() : 0;
4380                for (int i=0; i<N; i++) {
4381                    ResolveInfo rInfo = resolves.get(i);
4382                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4383                            && rInfo.activityInfo.name.equals(r.info.name)) {
4384                        // We found the current one...  the next matching is
4385                        // after it.
4386                        i++;
4387                        if (i<N) {
4388                            aInfo = resolves.get(i).activityInfo;
4389                        }
4390                        if (debug) {
4391                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4392                                    + "/" + r.info.name);
4393                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4394                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4395                        }
4396                        break;
4397                    }
4398                }
4399            } catch (RemoteException e) {
4400            }
4401
4402            if (aInfo == null) {
4403                // Nobody who is next!
4404                ActivityOptions.abort(options);
4405                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4406                return false;
4407            }
4408
4409            intent.setComponent(new ComponentName(
4410                    aInfo.applicationInfo.packageName, aInfo.name));
4411            intent.setFlags(intent.getFlags()&~(
4412                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4413                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4414                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4415                    Intent.FLAG_ACTIVITY_NEW_TASK));
4416
4417            // Okay now we need to start the new activity, replacing the
4418            // currently running activity.  This is a little tricky because
4419            // we want to start the new one as if the current one is finished,
4420            // but not finish the current one first so that there is no flicker.
4421            // And thus...
4422            final boolean wasFinishing = r.finishing;
4423            r.finishing = true;
4424
4425            // Propagate reply information over to the new activity.
4426            final ActivityRecord resultTo = r.resultTo;
4427            final String resultWho = r.resultWho;
4428            final int requestCode = r.requestCode;
4429            r.resultTo = null;
4430            if (resultTo != null) {
4431                resultTo.removeResultsLocked(r, resultWho, requestCode);
4432            }
4433
4434            final long origId = Binder.clearCallingIdentity();
4435            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4436                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4437                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4438                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4439                    false, false, null, null, null);
4440            Binder.restoreCallingIdentity(origId);
4441
4442            r.finishing = wasFinishing;
4443            if (res != ActivityManager.START_SUCCESS) {
4444                return false;
4445            }
4446            return true;
4447        }
4448    }
4449
4450    @Override
4451    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4452        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4453            String msg = "Permission Denial: startActivityFromRecents called without " +
4454                    START_TASKS_FROM_RECENTS;
4455            Slog.w(TAG, msg);
4456            throw new SecurityException(msg);
4457        }
4458        final long origId = Binder.clearCallingIdentity();
4459        try {
4460            return startActivityFromRecentsInner(taskId, bOptions);
4461        } finally {
4462            Binder.restoreCallingIdentity(origId);
4463        }
4464    }
4465
4466    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4467        final TaskRecord task;
4468        final int callingUid;
4469        final String callingPackage;
4470        final Intent intent;
4471        final int userId;
4472        synchronized (this) {
4473            final ActivityOptions activityOptions = (bOptions != null)
4474                    ? new ActivityOptions(bOptions) : null;
4475            final int launchStackId = (activityOptions != null)
4476                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4477
4478            if (launchStackId == HOME_STACK_ID) {
4479                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4480                        + taskId + " can't be launch in the home stack.");
4481            }
4482            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4483            if (task == null) {
4484                throw new IllegalArgumentException(
4485                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4486            }
4487
4488            if (launchStackId != INVALID_STACK_ID) {
4489                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4490                    mWindowManager.setDockedStackCreateState(
4491                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4492                }
4493                if (task.stack.mStackId != launchStackId) {
4494                    mStackSupervisor.moveTaskToStackLocked(
4495                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4496                            ANIMATE);
4497                }
4498            }
4499
4500            // If the user must confirm credentials (e.g. when first launching a work app and the
4501            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4502            if (!mUserController.shouldConfirmCredentials(task.userId)
4503                    && task.getRootActivity() != null) {
4504                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4505                return ActivityManager.START_TASK_TO_FRONT;
4506            }
4507            callingUid = task.mCallingUid;
4508            callingPackage = task.mCallingPackage;
4509            intent = task.intent;
4510            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4511            userId = task.userId;
4512        }
4513        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4514                bOptions, userId, null, task);
4515    }
4516
4517    final int startActivityInPackage(int uid, String callingPackage,
4518            Intent intent, String resolvedType, IBinder resultTo,
4519            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4520            IActivityContainer container, TaskRecord inTask) {
4521
4522        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4523                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4524
4525        // TODO: Switch to user app stacks here.
4526        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4527                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4528                null, null, null, bOptions, false, userId, container, inTask);
4529        return ret;
4530    }
4531
4532    @Override
4533    public final int startActivities(IApplicationThread caller, String callingPackage,
4534            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4535            int userId) {
4536        enforceNotIsolatedCaller("startActivities");
4537        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4538                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4539        // TODO: Switch to user app stacks here.
4540        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4541                resolvedTypes, resultTo, bOptions, userId);
4542        return ret;
4543    }
4544
4545    final int startActivitiesInPackage(int uid, String callingPackage,
4546            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4547            Bundle bOptions, int userId) {
4548
4549        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4550                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4551        // TODO: Switch to user app stacks here.
4552        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4553                resultTo, bOptions, userId);
4554        return ret;
4555    }
4556
4557    @Override
4558    public void reportActivityFullyDrawn(IBinder token) {
4559        synchronized (this) {
4560            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4561            if (r == null) {
4562                return;
4563            }
4564            r.reportFullyDrawnLocked();
4565        }
4566    }
4567
4568    @Override
4569    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4570        synchronized (this) {
4571            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4572            if (r == null) {
4573                return;
4574            }
4575            TaskRecord task = r.task;
4576            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4577                // Fixed screen orientation isn't supported when activities aren't in full screen
4578                // mode.
4579                return;
4580            }
4581            final long origId = Binder.clearCallingIdentity();
4582            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4583            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4584                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4585            if (config != null) {
4586                r.frozenBeforeDestroy = true;
4587                if (!updateConfigurationLocked(config, r, false)) {
4588                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4589                }
4590            }
4591            Binder.restoreCallingIdentity(origId);
4592        }
4593    }
4594
4595    @Override
4596    public int getRequestedOrientation(IBinder token) {
4597        synchronized (this) {
4598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4599            if (r == null) {
4600                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4601            }
4602            return mWindowManager.getAppOrientation(r.appToken);
4603        }
4604    }
4605
4606    /**
4607     * This is the internal entry point for handling Activity.finish().
4608     *
4609     * @param token The Binder token referencing the Activity we want to finish.
4610     * @param resultCode Result code, if any, from this Activity.
4611     * @param resultData Result data (Intent), if any, from this Activity.
4612     * @param finishTask Whether to finish the task associated with this Activity.
4613     *
4614     * @return Returns true if the activity successfully finished, or false if it is still running.
4615     */
4616    @Override
4617    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4618            int finishTask) {
4619        // Refuse possible leaked file descriptors
4620        if (resultData != null && resultData.hasFileDescriptors() == true) {
4621            throw new IllegalArgumentException("File descriptors passed in Intent");
4622        }
4623
4624        synchronized(this) {
4625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4626            if (r == null) {
4627                return true;
4628            }
4629            // Keep track of the root activity of the task before we finish it
4630            TaskRecord tr = r.task;
4631            ActivityRecord rootR = tr.getRootActivity();
4632            if (rootR == null) {
4633                Slog.w(TAG, "Finishing task with all activities already finished");
4634            }
4635            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4636            // finish.
4637            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4638                    mStackSupervisor.isLastLockedTask(tr)) {
4639                Slog.i(TAG, "Not finishing task in lock task mode");
4640                mStackSupervisor.showLockTaskToast();
4641                return false;
4642            }
4643            if (mController != null) {
4644                // Find the first activity that is not finishing.
4645                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4646                if (next != null) {
4647                    // ask watcher if this is allowed
4648                    boolean resumeOK = true;
4649                    try {
4650                        resumeOK = mController.activityResuming(next.packageName);
4651                    } catch (RemoteException e) {
4652                        mController = null;
4653                        Watchdog.getInstance().setActivityController(null);
4654                    }
4655
4656                    if (!resumeOK) {
4657                        Slog.i(TAG, "Not finishing activity because controller resumed");
4658                        return false;
4659                    }
4660                }
4661            }
4662            final long origId = Binder.clearCallingIdentity();
4663            try {
4664                boolean res;
4665                final boolean finishWithRootActivity =
4666                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4667                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4668                        || (finishWithRootActivity && r == rootR)) {
4669                    // If requested, remove the task that is associated to this activity only if it
4670                    // was the root activity in the task. The result code and data is ignored
4671                    // because we don't support returning them across task boundaries. Also, to
4672                    // keep backwards compatibility we remove the task from recents when finishing
4673                    // task with root activity.
4674                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4675                    if (!res) {
4676                        Slog.i(TAG, "Removing task failed to finish activity");
4677                    }
4678                } else {
4679                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4680                            resultData, "app-request", true);
4681                    if (!res) {
4682                        Slog.i(TAG, "Failed to finish by app-request");
4683                    }
4684                }
4685                return res;
4686            } finally {
4687                Binder.restoreCallingIdentity(origId);
4688            }
4689        }
4690    }
4691
4692    @Override
4693    public final void finishHeavyWeightApp() {
4694        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4695                != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703
4704        synchronized(this) {
4705            if (mHeavyWeightProcess == null) {
4706                return;
4707            }
4708
4709            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4710            for (int i = 0; i < activities.size(); i++) {
4711                ActivityRecord r = activities.get(i);
4712                if (!r.finishing && r.isInStackLocked()) {
4713                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4714                            null, "finish-heavy", true);
4715                }
4716            }
4717
4718            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4719                    mHeavyWeightProcess.userId, 0));
4720            mHeavyWeightProcess = null;
4721        }
4722    }
4723
4724    @Override
4725    public void crashApplication(int uid, int initialPid, String packageName,
4726            String message) {
4727        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4728                != PackageManager.PERMISSION_GRANTED) {
4729            String msg = "Permission Denial: crashApplication() from pid="
4730                    + Binder.getCallingPid()
4731                    + ", uid=" + Binder.getCallingUid()
4732                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4733            Slog.w(TAG, msg);
4734            throw new SecurityException(msg);
4735        }
4736
4737        synchronized(this) {
4738            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4739        }
4740    }
4741
4742    @Override
4743    public final void finishSubActivity(IBinder token, String resultWho,
4744            int requestCode) {
4745        synchronized(this) {
4746            final long origId = Binder.clearCallingIdentity();
4747            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4748            if (r != null) {
4749                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4750            }
4751            Binder.restoreCallingIdentity(origId);
4752        }
4753    }
4754
4755    @Override
4756    public boolean finishActivityAffinity(IBinder token) {
4757        synchronized(this) {
4758            final long origId = Binder.clearCallingIdentity();
4759            try {
4760                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4761                if (r == null) {
4762                    return false;
4763                }
4764
4765                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4766                // can finish.
4767                final TaskRecord task = r.task;
4768                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4769                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4770                    mStackSupervisor.showLockTaskToast();
4771                    return false;
4772                }
4773                return task.stack.finishActivityAffinityLocked(r);
4774            } finally {
4775                Binder.restoreCallingIdentity(origId);
4776            }
4777        }
4778    }
4779
4780    @Override
4781    public void finishVoiceTask(IVoiceInteractionSession session) {
4782        synchronized (this) {
4783            final long origId = Binder.clearCallingIdentity();
4784            try {
4785                // TODO: VI Consider treating local voice interactions and voice tasks
4786                // differently here
4787                mStackSupervisor.finishVoiceTask(session);
4788            } finally {
4789                Binder.restoreCallingIdentity(origId);
4790            }
4791        }
4792
4793    }
4794
4795    @Override
4796    public boolean releaseActivityInstance(IBinder token) {
4797        synchronized(this) {
4798            final long origId = Binder.clearCallingIdentity();
4799            try {
4800                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4801                if (r == null) {
4802                    return false;
4803                }
4804                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4805            } finally {
4806                Binder.restoreCallingIdentity(origId);
4807            }
4808        }
4809    }
4810
4811    @Override
4812    public void releaseSomeActivities(IApplicationThread appInt) {
4813        synchronized(this) {
4814            final long origId = Binder.clearCallingIdentity();
4815            try {
4816                ProcessRecord app = getRecordForAppLocked(appInt);
4817                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4818            } finally {
4819                Binder.restoreCallingIdentity(origId);
4820            }
4821        }
4822    }
4823
4824    @Override
4825    public boolean willActivityBeVisible(IBinder token) {
4826        synchronized(this) {
4827            ActivityStack stack = ActivityRecord.getStackLocked(token);
4828            if (stack != null) {
4829                return stack.willActivityBeVisibleLocked(token);
4830            }
4831            return false;
4832        }
4833    }
4834
4835    @Override
4836    public void overridePendingTransition(IBinder token, String packageName,
4837            int enterAnim, int exitAnim) {
4838        synchronized(this) {
4839            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4840            if (self == null) {
4841                return;
4842            }
4843
4844            final long origId = Binder.clearCallingIdentity();
4845
4846            if (self.state == ActivityState.RESUMED
4847                    || self.state == ActivityState.PAUSING) {
4848                mWindowManager.overridePendingAppTransition(packageName,
4849                        enterAnim, exitAnim, null);
4850            }
4851
4852            Binder.restoreCallingIdentity(origId);
4853        }
4854    }
4855
4856    /**
4857     * Main function for removing an existing process from the activity manager
4858     * as a result of that process going away.  Clears out all connections
4859     * to the process.
4860     */
4861    private final void handleAppDiedLocked(ProcessRecord app,
4862            boolean restarting, boolean allowRestart) {
4863        int pid = app.pid;
4864        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4865        if (!kept && !restarting) {
4866            removeLruProcessLocked(app);
4867            if (pid > 0) {
4868                ProcessList.remove(pid);
4869            }
4870        }
4871
4872        if (mProfileProc == app) {
4873            clearProfilerLocked();
4874        }
4875
4876        // Remove this application's activities from active lists.
4877        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4878
4879        app.activities.clear();
4880
4881        if (app.instrumentationClass != null) {
4882            Slog.w(TAG, "Crash of app " + app.processName
4883                  + " running instrumentation " + app.instrumentationClass);
4884            Bundle info = new Bundle();
4885            info.putString("shortMsg", "Process crashed.");
4886            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4887        }
4888
4889        if (!restarting && hasVisibleActivities
4890                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4891            // If there was nothing to resume, and we are not already restarting this process, but
4892            // there is a visible activity that is hosted by the process...  then make sure all
4893            // visible activities are running, taking care of restarting this process.
4894            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4895        }
4896    }
4897
4898    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4899        IBinder threadBinder = thread.asBinder();
4900        // Find the application record.
4901        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4902            ProcessRecord rec = mLruProcesses.get(i);
4903            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4904                return i;
4905            }
4906        }
4907        return -1;
4908    }
4909
4910    final ProcessRecord getRecordForAppLocked(
4911            IApplicationThread thread) {
4912        if (thread == null) {
4913            return null;
4914        }
4915
4916        int appIndex = getLRURecordIndexForAppLocked(thread);
4917        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4918    }
4919
4920    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4921        // If there are no longer any background processes running,
4922        // and the app that died was not running instrumentation,
4923        // then tell everyone we are now low on memory.
4924        boolean haveBg = false;
4925        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4926            ProcessRecord rec = mLruProcesses.get(i);
4927            if (rec.thread != null
4928                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4929                haveBg = true;
4930                break;
4931            }
4932        }
4933
4934        if (!haveBg) {
4935            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4936            if (doReport) {
4937                long now = SystemClock.uptimeMillis();
4938                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4939                    doReport = false;
4940                } else {
4941                    mLastMemUsageReportTime = now;
4942                }
4943            }
4944            final ArrayList<ProcessMemInfo> memInfos
4945                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4946            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4947            long now = SystemClock.uptimeMillis();
4948            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4949                ProcessRecord rec = mLruProcesses.get(i);
4950                if (rec == dyingProc || rec.thread == null) {
4951                    continue;
4952                }
4953                if (doReport) {
4954                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4955                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4956                }
4957                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4958                    // The low memory report is overriding any current
4959                    // state for a GC request.  Make sure to do
4960                    // heavy/important/visible/foreground processes first.
4961                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4962                        rec.lastRequestedGc = 0;
4963                    } else {
4964                        rec.lastRequestedGc = rec.lastLowMemory;
4965                    }
4966                    rec.reportLowMemory = true;
4967                    rec.lastLowMemory = now;
4968                    mProcessesToGc.remove(rec);
4969                    addProcessToGcListLocked(rec);
4970                }
4971            }
4972            if (doReport) {
4973                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4974                mHandler.sendMessage(msg);
4975            }
4976            scheduleAppGcsLocked();
4977        }
4978    }
4979
4980    final void appDiedLocked(ProcessRecord app) {
4981       appDiedLocked(app, app.pid, app.thread, false);
4982    }
4983
4984    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4985            boolean fromBinderDied) {
4986        // First check if this ProcessRecord is actually active for the pid.
4987        synchronized (mPidsSelfLocked) {
4988            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4989            if (curProc != app) {
4990                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4991                return;
4992            }
4993        }
4994
4995        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4996        synchronized (stats) {
4997            stats.noteProcessDiedLocked(app.info.uid, pid);
4998        }
4999
5000        if (!app.killed) {
5001            if (!fromBinderDied) {
5002                Process.killProcessQuiet(pid);
5003            }
5004            killProcessGroup(app.info.uid, pid);
5005            app.killed = true;
5006        }
5007
5008        // Clean up already done if the process has been re-started.
5009        if (app.pid == pid && app.thread != null &&
5010                app.thread.asBinder() == thread.asBinder()) {
5011            boolean doLowMem = app.instrumentationClass == null;
5012            boolean doOomAdj = doLowMem;
5013            if (!app.killedByAm) {
5014                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5015                        + ") has died");
5016                mAllowLowerMemLevel = true;
5017            } else {
5018                // Note that we always want to do oom adj to update our state with the
5019                // new number of procs.
5020                mAllowLowerMemLevel = false;
5021                doLowMem = false;
5022            }
5023            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5024            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5025                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5026            handleAppDiedLocked(app, false, true);
5027
5028            if (doOomAdj) {
5029                updateOomAdjLocked();
5030            }
5031            if (doLowMem) {
5032                doLowMemReportIfNeededLocked(app);
5033            }
5034        } else if (app.pid != pid) {
5035            // A new process has already been started.
5036            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5037                    + ") has died and restarted (pid " + app.pid + ").");
5038            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5039        } else if (DEBUG_PROCESSES) {
5040            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5041                    + thread.asBinder());
5042        }
5043    }
5044
5045    /**
5046     * If a stack trace dump file is configured, dump process stack traces.
5047     * @param clearTraces causes the dump file to be erased prior to the new
5048     *    traces being written, if true; when false, the new traces will be
5049     *    appended to any existing file content.
5050     * @param firstPids of dalvik VM processes to dump stack traces for first
5051     * @param lastPids of dalvik VM processes to dump stack traces for last
5052     * @param nativeProcs optional list of native process names to dump stack crawls
5053     * @return file containing stack traces, or null if no dump file is configured
5054     */
5055    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5056            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5057        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5058        if (tracesPath == null || tracesPath.length() == 0) {
5059            return null;
5060        }
5061
5062        File tracesFile = new File(tracesPath);
5063        try {
5064            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5065            tracesFile.createNewFile();
5066            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5067        } catch (IOException e) {
5068            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5069            return null;
5070        }
5071
5072        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5073        return tracesFile;
5074    }
5075
5076    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5077            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5078        // Use a FileObserver to detect when traces finish writing.
5079        // The order of traces is considered important to maintain for legibility.
5080        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5081            @Override
5082            public synchronized void onEvent(int event, String path) { notify(); }
5083        };
5084
5085        try {
5086            observer.startWatching();
5087
5088            // First collect all of the stacks of the most important pids.
5089            if (firstPids != null) {
5090                try {
5091                    int num = firstPids.size();
5092                    for (int i = 0; i < num; i++) {
5093                        synchronized (observer) {
5094                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5095                            observer.wait(200);  // Wait for write-close, give up after 200msec
5096                        }
5097                    }
5098                } catch (InterruptedException e) {
5099                    Slog.wtf(TAG, e);
5100                }
5101            }
5102
5103            // Next collect the stacks of the native pids
5104            if (nativeProcs != null) {
5105                int[] pids = Process.getPidsForCommands(nativeProcs);
5106                if (pids != null) {
5107                    for (int pid : pids) {
5108                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5109                    }
5110                }
5111            }
5112
5113            // Lastly, measure CPU usage.
5114            if (processCpuTracker != null) {
5115                processCpuTracker.init();
5116                System.gc();
5117                processCpuTracker.update();
5118                try {
5119                    synchronized (processCpuTracker) {
5120                        processCpuTracker.wait(500); // measure over 1/2 second.
5121                    }
5122                } catch (InterruptedException e) {
5123                }
5124                processCpuTracker.update();
5125
5126                // We'll take the stack crawls of just the top apps using CPU.
5127                final int N = processCpuTracker.countWorkingStats();
5128                int numProcs = 0;
5129                for (int i=0; i<N && numProcs<5; i++) {
5130                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5131                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5132                        numProcs++;
5133                        try {
5134                            synchronized (observer) {
5135                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5136                                observer.wait(200);  // Wait for write-close, give up after 200msec
5137                            }
5138                        } catch (InterruptedException e) {
5139                            Slog.wtf(TAG, e);
5140                        }
5141
5142                    }
5143                }
5144            }
5145        } finally {
5146            observer.stopWatching();
5147        }
5148    }
5149
5150    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5151        if (true || IS_USER_BUILD) {
5152            return;
5153        }
5154        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5155        if (tracesPath == null || tracesPath.length() == 0) {
5156            return;
5157        }
5158
5159        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5160        StrictMode.allowThreadDiskWrites();
5161        try {
5162            final File tracesFile = new File(tracesPath);
5163            final File tracesDir = tracesFile.getParentFile();
5164            final File tracesTmp = new File(tracesDir, "__tmp__");
5165            try {
5166                if (tracesFile.exists()) {
5167                    tracesTmp.delete();
5168                    tracesFile.renameTo(tracesTmp);
5169                }
5170                StringBuilder sb = new StringBuilder();
5171                Time tobj = new Time();
5172                tobj.set(System.currentTimeMillis());
5173                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5174                sb.append(": ");
5175                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5176                sb.append(" since ");
5177                sb.append(msg);
5178                FileOutputStream fos = new FileOutputStream(tracesFile);
5179                fos.write(sb.toString().getBytes());
5180                if (app == null) {
5181                    fos.write("\n*** No application process!".getBytes());
5182                }
5183                fos.close();
5184                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5185            } catch (IOException e) {
5186                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5187                return;
5188            }
5189
5190            if (app != null) {
5191                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5192                firstPids.add(app.pid);
5193                dumpStackTraces(tracesPath, firstPids, null, null, null);
5194            }
5195
5196            File lastTracesFile = null;
5197            File curTracesFile = null;
5198            for (int i=9; i>=0; i--) {
5199                String name = String.format(Locale.US, "slow%02d.txt", i);
5200                curTracesFile = new File(tracesDir, name);
5201                if (curTracesFile.exists()) {
5202                    if (lastTracesFile != null) {
5203                        curTracesFile.renameTo(lastTracesFile);
5204                    } else {
5205                        curTracesFile.delete();
5206                    }
5207                }
5208                lastTracesFile = curTracesFile;
5209            }
5210            tracesFile.renameTo(curTracesFile);
5211            if (tracesTmp.exists()) {
5212                tracesTmp.renameTo(tracesFile);
5213            }
5214        } finally {
5215            StrictMode.setThreadPolicy(oldPolicy);
5216        }
5217    }
5218
5219    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5220        if (!mLaunchWarningShown) {
5221            mLaunchWarningShown = true;
5222            mUiHandler.post(new Runnable() {
5223                @Override
5224                public void run() {
5225                    synchronized (ActivityManagerService.this) {
5226                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5227                        d.show();
5228                        mUiHandler.postDelayed(new Runnable() {
5229                            @Override
5230                            public void run() {
5231                                synchronized (ActivityManagerService.this) {
5232                                    d.dismiss();
5233                                    mLaunchWarningShown = false;
5234                                }
5235                            }
5236                        }, 4000);
5237                    }
5238                }
5239            });
5240        }
5241    }
5242
5243    @Override
5244    public boolean clearApplicationUserData(final String packageName,
5245            final IPackageDataObserver observer, int userId) {
5246        enforceNotIsolatedCaller("clearApplicationUserData");
5247        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5248            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5249        }
5250        int uid = Binder.getCallingUid();
5251        int pid = Binder.getCallingPid();
5252        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5253                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5254        long callingId = Binder.clearCallingIdentity();
5255        try {
5256            IPackageManager pm = AppGlobals.getPackageManager();
5257            int pkgUid = -1;
5258            synchronized(this) {
5259                try {
5260                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5261                } catch (RemoteException e) {
5262                }
5263                if (pkgUid == -1) {
5264                    Slog.w(TAG, "Invalid packageName: " + packageName);
5265                    if (observer != null) {
5266                        try {
5267                            observer.onRemoveCompleted(packageName, false);
5268                        } catch (RemoteException e) {
5269                            Slog.i(TAG, "Observer no longer exists.");
5270                        }
5271                    }
5272                    return false;
5273                }
5274                if (uid == pkgUid || checkComponentPermission(
5275                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5276                        pid, uid, -1, true)
5277                        == PackageManager.PERMISSION_GRANTED) {
5278                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5279                } else {
5280                    throw new SecurityException("PID " + pid + " does not have permission "
5281                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5282                                    + " of package " + packageName);
5283                }
5284
5285                // Remove all tasks match the cleared application package and user
5286                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5287                    final TaskRecord tr = mRecentTasks.get(i);
5288                    final String taskPackageName =
5289                            tr.getBaseIntent().getComponent().getPackageName();
5290                    if (tr.userId != userId) continue;
5291                    if (!taskPackageName.equals(packageName)) continue;
5292                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5293                }
5294            }
5295
5296            try {
5297                // Clear application user data
5298                pm.clearApplicationUserData(packageName, observer, userId);
5299
5300                synchronized(this) {
5301                    // Remove all permissions granted from/to this package
5302                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5303                }
5304
5305                // Remove all zen rules created by this package; revoke it's zen access.
5306                INotificationManager inm = NotificationManager.getService();
5307                inm.removeAutomaticZenRules(packageName);
5308                inm.setNotificationPolicyAccessGranted(packageName, false);
5309
5310                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5311                        Uri.fromParts("package", packageName, null));
5312                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5313                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5314                        null, null, 0, null, null, null, null, false, false, userId);
5315            } catch (RemoteException e) {
5316            }
5317        } finally {
5318            Binder.restoreCallingIdentity(callingId);
5319        }
5320        return true;
5321    }
5322
5323    @Override
5324    public void killBackgroundProcesses(final String packageName, int userId) {
5325        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5326                != PackageManager.PERMISSION_GRANTED &&
5327                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5328                        != PackageManager.PERMISSION_GRANTED) {
5329            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5330                    + Binder.getCallingPid()
5331                    + ", uid=" + Binder.getCallingUid()
5332                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5333            Slog.w(TAG, msg);
5334            throw new SecurityException(msg);
5335        }
5336
5337        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5338                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            synchronized(this) {
5343                int appId = -1;
5344                try {
5345                    appId = UserHandle.getAppId(
5346                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5347                } catch (RemoteException e) {
5348                }
5349                if (appId == -1) {
5350                    Slog.w(TAG, "Invalid packageName: " + packageName);
5351                    return;
5352                }
5353                killPackageProcessesLocked(packageName, appId, userId,
5354                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(callingId);
5358        }
5359    }
5360
5361    @Override
5362    public void killAllBackgroundProcesses() {
5363        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5364                != PackageManager.PERMISSION_GRANTED) {
5365            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5366                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5367                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5368            Slog.w(TAG, msg);
5369            throw new SecurityException(msg);
5370        }
5371
5372        final long callingId = Binder.clearCallingIdentity();
5373        try {
5374            synchronized (this) {
5375                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5376                final int NP = mProcessNames.getMap().size();
5377                for (int ip = 0; ip < NP; ip++) {
5378                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5379                    final int NA = apps.size();
5380                    for (int ia = 0; ia < NA; ia++) {
5381                        final ProcessRecord app = apps.valueAt(ia);
5382                        if (app.persistent) {
5383                            // We don't kill persistent processes.
5384                            continue;
5385                        }
5386                        if (app.removed) {
5387                            procs.add(app);
5388                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5389                            app.removed = true;
5390                            procs.add(app);
5391                        }
5392                    }
5393                }
5394
5395                final int N = procs.size();
5396                for (int i = 0; i < N; i++) {
5397                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5398                }
5399
5400                mAllowLowerMemLevel = true;
5401
5402                updateOomAdjLocked();
5403                doLowMemReportIfNeededLocked(null);
5404            }
5405        } finally {
5406            Binder.restoreCallingIdentity(callingId);
5407        }
5408    }
5409
5410    /**
5411     * Kills all background processes, except those matching any of the
5412     * specified properties.
5413     *
5414     * @param minTargetSdk the target SDK version at or above which to preserve
5415     *                     processes, or {@code -1} to ignore the target SDK
5416     * @param maxProcState the process state at or below which to preserve
5417     *                     processes, or {@code -1} to ignore the process state
5418     */
5419    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5420        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5421                != PackageManager.PERMISSION_GRANTED) {
5422            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5423                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5425            Slog.w(TAG, msg);
5426            throw new SecurityException(msg);
5427        }
5428
5429        final long callingId = Binder.clearCallingIdentity();
5430        try {
5431            synchronized (this) {
5432                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5433                final int NP = mProcessNames.getMap().size();
5434                for (int ip = 0; ip < NP; ip++) {
5435                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5436                    final int NA = apps.size();
5437                    for (int ia = 0; ia < NA; ia++) {
5438                        final ProcessRecord app = apps.valueAt(ia);
5439                        if (app.removed) {
5440                            procs.add(app);
5441                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5442                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5443                            app.removed = true;
5444                            procs.add(app);
5445                        }
5446                    }
5447                }
5448
5449                final int N = procs.size();
5450                for (int i = 0; i < N; i++) {
5451                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5452                }
5453            }
5454        } finally {
5455            Binder.restoreCallingIdentity(callingId);
5456        }
5457    }
5458
5459    @Override
5460    public void forceStopPackage(final String packageName, int userId) {
5461        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5462                != PackageManager.PERMISSION_GRANTED) {
5463            String msg = "Permission Denial: forceStopPackage() from pid="
5464                    + Binder.getCallingPid()
5465                    + ", uid=" + Binder.getCallingUid()
5466                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5467            Slog.w(TAG, msg);
5468            throw new SecurityException(msg);
5469        }
5470        final int callingPid = Binder.getCallingPid();
5471        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5472                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5473        long callingId = Binder.clearCallingIdentity();
5474        try {
5475            IPackageManager pm = AppGlobals.getPackageManager();
5476            synchronized(this) {
5477                int[] users = userId == UserHandle.USER_ALL
5478                        ? mUserController.getUsers() : new int[] { userId };
5479                for (int user : users) {
5480                    int pkgUid = -1;
5481                    try {
5482                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5483                                user);
5484                    } catch (RemoteException e) {
5485                    }
5486                    if (pkgUid == -1) {
5487                        Slog.w(TAG, "Invalid packageName: " + packageName);
5488                        continue;
5489                    }
5490                    try {
5491                        pm.setPackageStoppedState(packageName, true, user);
5492                    } catch (RemoteException e) {
5493                    } catch (IllegalArgumentException e) {
5494                        Slog.w(TAG, "Failed trying to unstop package "
5495                                + packageName + ": " + e);
5496                    }
5497                    if (mUserController.isUserRunningLocked(user, 0)) {
5498                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5499                    }
5500                }
5501            }
5502        } finally {
5503            Binder.restoreCallingIdentity(callingId);
5504        }
5505    }
5506
5507    @Override
5508    public void addPackageDependency(String packageName) {
5509        synchronized (this) {
5510            int callingPid = Binder.getCallingPid();
5511            if (callingPid == Process.myPid()) {
5512                //  Yeah, um, no.
5513                return;
5514            }
5515            ProcessRecord proc;
5516            synchronized (mPidsSelfLocked) {
5517                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5518            }
5519            if (proc != null) {
5520                if (proc.pkgDeps == null) {
5521                    proc.pkgDeps = new ArraySet<String>(1);
5522                }
5523                proc.pkgDeps.add(packageName);
5524            }
5525        }
5526    }
5527
5528    /*
5529     * The pkg name and app id have to be specified.
5530     */
5531    @Override
5532    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5533        if (pkg == null) {
5534            return;
5535        }
5536        // Make sure the uid is valid.
5537        if (appid < 0) {
5538            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5539            return;
5540        }
5541        int callerUid = Binder.getCallingUid();
5542        // Only the system server can kill an application
5543        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5544            // Post an aysnc message to kill the application
5545            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5546            msg.arg1 = appid;
5547            msg.arg2 = 0;
5548            Bundle bundle = new Bundle();
5549            bundle.putString("pkg", pkg);
5550            bundle.putString("reason", reason);
5551            msg.obj = bundle;
5552            mHandler.sendMessage(msg);
5553        } else {
5554            throw new SecurityException(callerUid + " cannot kill pkg: " +
5555                    pkg);
5556        }
5557    }
5558
5559    @Override
5560    public void closeSystemDialogs(String reason) {
5561        enforceNotIsolatedCaller("closeSystemDialogs");
5562
5563        final int pid = Binder.getCallingPid();
5564        final int uid = Binder.getCallingUid();
5565        final long origId = Binder.clearCallingIdentity();
5566        try {
5567            synchronized (this) {
5568                // Only allow this from foreground processes, so that background
5569                // applications can't abuse it to prevent system UI from being shown.
5570                if (uid >= Process.FIRST_APPLICATION_UID) {
5571                    ProcessRecord proc;
5572                    synchronized (mPidsSelfLocked) {
5573                        proc = mPidsSelfLocked.get(pid);
5574                    }
5575                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5576                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5577                                + " from background process " + proc);
5578                        return;
5579                    }
5580                }
5581                closeSystemDialogsLocked(reason);
5582            }
5583        } finally {
5584            Binder.restoreCallingIdentity(origId);
5585        }
5586    }
5587
5588    void closeSystemDialogsLocked(String reason) {
5589        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5590        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5591                | Intent.FLAG_RECEIVER_FOREGROUND);
5592        if (reason != null) {
5593            intent.putExtra("reason", reason);
5594        }
5595        mWindowManager.closeSystemDialogs(reason);
5596
5597        mStackSupervisor.closeSystemDialogsLocked();
5598
5599        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5600                AppOpsManager.OP_NONE, null, false, false,
5601                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5602    }
5603
5604    @Override
5605    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5606        enforceNotIsolatedCaller("getProcessMemoryInfo");
5607        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5608        for (int i=pids.length-1; i>=0; i--) {
5609            ProcessRecord proc;
5610            int oomAdj;
5611            synchronized (this) {
5612                synchronized (mPidsSelfLocked) {
5613                    proc = mPidsSelfLocked.get(pids[i]);
5614                    oomAdj = proc != null ? proc.setAdj : 0;
5615                }
5616            }
5617            infos[i] = new Debug.MemoryInfo();
5618            Debug.getMemoryInfo(pids[i], infos[i]);
5619            if (proc != null) {
5620                synchronized (this) {
5621                    if (proc.thread != null && proc.setAdj == oomAdj) {
5622                        // Record this for posterity if the process has been stable.
5623                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5624                                infos[i].getTotalUss(), false, proc.pkgList);
5625                    }
5626                }
5627            }
5628        }
5629        return infos;
5630    }
5631
5632    @Override
5633    public long[] getProcessPss(int[] pids) {
5634        enforceNotIsolatedCaller("getProcessPss");
5635        long[] pss = new long[pids.length];
5636        for (int i=pids.length-1; i>=0; i--) {
5637            ProcessRecord proc;
5638            int oomAdj;
5639            synchronized (this) {
5640                synchronized (mPidsSelfLocked) {
5641                    proc = mPidsSelfLocked.get(pids[i]);
5642                    oomAdj = proc != null ? proc.setAdj : 0;
5643                }
5644            }
5645            long[] tmpUss = new long[1];
5646            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5647            if (proc != null) {
5648                synchronized (this) {
5649                    if (proc.thread != null && proc.setAdj == oomAdj) {
5650                        // Record this for posterity if the process has been stable.
5651                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5652                    }
5653                }
5654            }
5655        }
5656        return pss;
5657    }
5658
5659    @Override
5660    public void killApplicationProcess(String processName, int uid) {
5661        if (processName == null) {
5662            return;
5663        }
5664
5665        int callerUid = Binder.getCallingUid();
5666        // Only the system server can kill an application
5667        if (callerUid == Process.SYSTEM_UID) {
5668            synchronized (this) {
5669                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5670                if (app != null && app.thread != null) {
5671                    try {
5672                        app.thread.scheduleSuicide();
5673                    } catch (RemoteException e) {
5674                        // If the other end already died, then our work here is done.
5675                    }
5676                } else {
5677                    Slog.w(TAG, "Process/uid not found attempting kill of "
5678                            + processName + " / " + uid);
5679                }
5680            }
5681        } else {
5682            throw new SecurityException(callerUid + " cannot kill app process: " +
5683                    processName);
5684        }
5685    }
5686
5687    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5688        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5689                false, true, false, false, UserHandle.getUserId(uid), reason);
5690        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5691                Uri.fromParts("package", packageName, null));
5692        if (!mProcessesReady) {
5693            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5694                    | Intent.FLAG_RECEIVER_FOREGROUND);
5695        }
5696        intent.putExtra(Intent.EXTRA_UID, uid);
5697        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5698        broadcastIntentLocked(null, null, intent,
5699                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5700                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5701    }
5702
5703
5704    private final boolean killPackageProcessesLocked(String packageName, int appId,
5705            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5706            boolean doit, boolean evenPersistent, String reason) {
5707        ArrayList<ProcessRecord> procs = new ArrayList<>();
5708
5709        // Remove all processes this package may have touched: all with the
5710        // same UID (except for the system or root user), and all whose name
5711        // matches the package name.
5712        final int NP = mProcessNames.getMap().size();
5713        for (int ip=0; ip<NP; ip++) {
5714            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5715            final int NA = apps.size();
5716            for (int ia=0; ia<NA; ia++) {
5717                ProcessRecord app = apps.valueAt(ia);
5718                if (app.persistent && !evenPersistent) {
5719                    // we don't kill persistent processes
5720                    continue;
5721                }
5722                if (app.removed) {
5723                    if (doit) {
5724                        procs.add(app);
5725                    }
5726                    continue;
5727                }
5728
5729                // Skip process if it doesn't meet our oom adj requirement.
5730                if (app.setAdj < minOomAdj) {
5731                    continue;
5732                }
5733
5734                // If no package is specified, we call all processes under the
5735                // give user id.
5736                if (packageName == null) {
5737                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5738                        continue;
5739                    }
5740                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5741                        continue;
5742                    }
5743                // Package has been specified, we want to hit all processes
5744                // that match it.  We need to qualify this by the processes
5745                // that are running under the specified app and user ID.
5746                } else {
5747                    final boolean isDep = app.pkgDeps != null
5748                            && app.pkgDeps.contains(packageName);
5749                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5750                        continue;
5751                    }
5752                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5753                        continue;
5754                    }
5755                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5756                        continue;
5757                    }
5758                }
5759
5760                // Process has passed all conditions, kill it!
5761                if (!doit) {
5762                    return true;
5763                }
5764                app.removed = true;
5765                procs.add(app);
5766            }
5767        }
5768
5769        int N = procs.size();
5770        for (int i=0; i<N; i++) {
5771            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5772        }
5773        updateOomAdjLocked();
5774        return N > 0;
5775    }
5776
5777    private void cleanupDisabledPackageComponentsLocked(
5778            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5779
5780        Set<String> disabledClasses = null;
5781        boolean packageDisabled = false;
5782        IPackageManager pm = AppGlobals.getPackageManager();
5783
5784        if (changedClasses == null) {
5785            // Nothing changed...
5786            return;
5787        }
5788
5789        // Determine enable/disable state of the package and its components.
5790        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5791        for (int i = changedClasses.length - 1; i >= 0; i--) {
5792            final String changedClass = changedClasses[i];
5793
5794            if (changedClass.equals(packageName)) {
5795                try {
5796                    // Entire package setting changed
5797                    enabled = pm.getApplicationEnabledSetting(packageName,
5798                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5799                } catch (Exception e) {
5800                    // No such package/component; probably racing with uninstall.  In any
5801                    // event it means we have nothing further to do here.
5802                    return;
5803                }
5804                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5805                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5806                if (packageDisabled) {
5807                    // Entire package is disabled.
5808                    // No need to continue to check component states.
5809                    disabledClasses = null;
5810                    break;
5811                }
5812            } else {
5813                try {
5814                    enabled = pm.getComponentEnabledSetting(
5815                            new ComponentName(packageName, changedClass),
5816                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5817                } catch (Exception e) {
5818                    // As above, probably racing with uninstall.
5819                    return;
5820                }
5821                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5822                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5823                    if (disabledClasses == null) {
5824                        disabledClasses = new ArraySet<>(changedClasses.length);
5825                    }
5826                    disabledClasses.add(changedClass);
5827                }
5828            }
5829        }
5830
5831        if (!packageDisabled && disabledClasses == null) {
5832            // Nothing to do here...
5833            return;
5834        }
5835
5836        // Clean-up disabled activities.
5837        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5838                packageName, disabledClasses, true, false, userId) && mBooted) {
5839            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5840            mStackSupervisor.scheduleIdleLocked();
5841        }
5842
5843        // Clean-up disabled tasks
5844        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5845
5846        // Clean-up disabled services.
5847        mServices.bringDownDisabledPackageServicesLocked(
5848                packageName, disabledClasses, userId, false, killProcess, true);
5849
5850        // Clean-up disabled providers.
5851        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5852        mProviderMap.collectPackageProvidersLocked(
5853                packageName, disabledClasses, true, false, userId, providers);
5854        for (int i = providers.size() - 1; i >= 0; i--) {
5855            removeDyingProviderLocked(null, providers.get(i), true);
5856        }
5857
5858        // Clean-up disabled broadcast receivers.
5859        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5860            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5861                    packageName, disabledClasses, userId, true);
5862        }
5863
5864    }
5865
5866    final boolean forceStopPackageLocked(String packageName, int appId,
5867            boolean callerWillRestart, boolean purgeCache, boolean doit,
5868            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5869        int i;
5870
5871        if (userId == UserHandle.USER_ALL && packageName == null) {
5872            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5873        }
5874
5875        if (appId < 0 && packageName != null) {
5876            try {
5877                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5878                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5879            } catch (RemoteException e) {
5880            }
5881        }
5882
5883        if (doit) {
5884            if (packageName != null) {
5885                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5886                        + " user=" + userId + ": " + reason);
5887            } else {
5888                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5889            }
5890
5891            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5892        }
5893
5894        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5895                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5896                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5897
5898        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5899                packageName, null, doit, evenPersistent, userId)) {
5900            if (!doit) {
5901                return true;
5902            }
5903            didSomething = true;
5904        }
5905
5906        if (mServices.bringDownDisabledPackageServicesLocked(
5907                packageName, null, userId, evenPersistent, true, doit)) {
5908            if (!doit) {
5909                return true;
5910            }
5911            didSomething = true;
5912        }
5913
5914        if (packageName == null) {
5915            // Remove all sticky broadcasts from this user.
5916            mStickyBroadcasts.remove(userId);
5917        }
5918
5919        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5920        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5921                userId, providers)) {
5922            if (!doit) {
5923                return true;
5924            }
5925            didSomething = true;
5926        }
5927        for (i = providers.size() - 1; i >= 0; i--) {
5928            removeDyingProviderLocked(null, providers.get(i), true);
5929        }
5930
5931        // Remove transient permissions granted from/to this package/user
5932        removeUriPermissionsForPackageLocked(packageName, userId, false);
5933
5934        if (doit) {
5935            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5936                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5937                        packageName, null, userId, doit);
5938            }
5939        }
5940
5941        if (packageName == null || uninstalling) {
5942            // Remove pending intents.  For now we only do this when force
5943            // stopping users, because we have some problems when doing this
5944            // for packages -- app widgets are not currently cleaned up for
5945            // such packages, so they can be left with bad pending intents.
5946            if (mIntentSenderRecords.size() > 0) {
5947                Iterator<WeakReference<PendingIntentRecord>> it
5948                        = mIntentSenderRecords.values().iterator();
5949                while (it.hasNext()) {
5950                    WeakReference<PendingIntentRecord> wpir = it.next();
5951                    if (wpir == null) {
5952                        it.remove();
5953                        continue;
5954                    }
5955                    PendingIntentRecord pir = wpir.get();
5956                    if (pir == null) {
5957                        it.remove();
5958                        continue;
5959                    }
5960                    if (packageName == null) {
5961                        // Stopping user, remove all objects for the user.
5962                        if (pir.key.userId != userId) {
5963                            // Not the same user, skip it.
5964                            continue;
5965                        }
5966                    } else {
5967                        if (UserHandle.getAppId(pir.uid) != appId) {
5968                            // Different app id, skip it.
5969                            continue;
5970                        }
5971                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5972                            // Different user, skip it.
5973                            continue;
5974                        }
5975                        if (!pir.key.packageName.equals(packageName)) {
5976                            // Different package, skip it.
5977                            continue;
5978                        }
5979                    }
5980                    if (!doit) {
5981                        return true;
5982                    }
5983                    didSomething = true;
5984                    it.remove();
5985                    pir.canceled = true;
5986                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5987                        pir.key.activity.pendingResults.remove(pir.ref);
5988                    }
5989                }
5990            }
5991        }
5992
5993        if (doit) {
5994            if (purgeCache && packageName != null) {
5995                AttributeCache ac = AttributeCache.instance();
5996                if (ac != null) {
5997                    ac.removePackage(packageName);
5998                }
5999            }
6000            if (mBooted) {
6001                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6002                mStackSupervisor.scheduleIdleLocked();
6003            }
6004        }
6005
6006        return didSomething;
6007    }
6008
6009    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6010        ProcessRecord old = mProcessNames.remove(name, uid);
6011        if (old != null) {
6012            old.uidRecord.numProcs--;
6013            if (old.uidRecord.numProcs == 0) {
6014                // No more processes using this uid, tell clients it is gone.
6015                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6016                        "No more processes in " + old.uidRecord);
6017                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6018                mActiveUids.remove(uid);
6019                mBatteryStatsService.noteUidProcessState(uid,
6020                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6021            }
6022            old.uidRecord = null;
6023        }
6024        mIsolatedProcesses.remove(uid);
6025        return old;
6026    }
6027
6028    private final void addProcessNameLocked(ProcessRecord proc) {
6029        // We shouldn't already have a process under this name, but just in case we
6030        // need to clean up whatever may be there now.
6031        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6032        if (old == proc && proc.persistent) {
6033            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6034            Slog.w(TAG, "Re-adding persistent process " + proc);
6035        } else if (old != null) {
6036            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6037        }
6038        UidRecord uidRec = mActiveUids.get(proc.uid);
6039        if (uidRec == null) {
6040            uidRec = new UidRecord(proc.uid);
6041            // This is the first appearance of the uid, report it now!
6042            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6043                    "Creating new process uid: " + uidRec);
6044            mActiveUids.put(proc.uid, uidRec);
6045            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6046            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6047        }
6048        proc.uidRecord = uidRec;
6049        uidRec.numProcs++;
6050        mProcessNames.put(proc.processName, proc.uid, proc);
6051        if (proc.isolated) {
6052            mIsolatedProcesses.put(proc.uid, proc);
6053        }
6054    }
6055
6056    boolean removeProcessLocked(ProcessRecord app,
6057            boolean callerWillRestart, boolean allowRestart, String reason) {
6058        final String name = app.processName;
6059        final int uid = app.uid;
6060        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6061            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6062
6063        removeProcessNameLocked(name, uid);
6064        if (mHeavyWeightProcess == app) {
6065            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6066                    mHeavyWeightProcess.userId, 0));
6067            mHeavyWeightProcess = null;
6068        }
6069        boolean needRestart = false;
6070        if (app.pid > 0 && app.pid != MY_PID) {
6071            int pid = app.pid;
6072            synchronized (mPidsSelfLocked) {
6073                mPidsSelfLocked.remove(pid);
6074                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6075            }
6076            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6077            if (app.isolated) {
6078                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6079            }
6080            boolean willRestart = false;
6081            if (app.persistent && !app.isolated) {
6082                if (!callerWillRestart) {
6083                    willRestart = true;
6084                } else {
6085                    needRestart = true;
6086                }
6087            }
6088            app.kill(reason, true);
6089            handleAppDiedLocked(app, willRestart, allowRestart);
6090            if (willRestart) {
6091                removeLruProcessLocked(app);
6092                addAppLocked(app.info, false, null /* ABI override */);
6093            }
6094        } else {
6095            mRemovedProcesses.add(app);
6096        }
6097
6098        return needRestart;
6099    }
6100
6101    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6102        cleanupAppInLaunchingProvidersLocked(app, true);
6103        removeProcessLocked(app, false, true, "timeout publishing content providers");
6104    }
6105
6106    private final void processStartTimedOutLocked(ProcessRecord app) {
6107        final int pid = app.pid;
6108        boolean gone = false;
6109        synchronized (mPidsSelfLocked) {
6110            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6111            if (knownApp != null && knownApp.thread == null) {
6112                mPidsSelfLocked.remove(pid);
6113                gone = true;
6114            }
6115        }
6116
6117        if (gone) {
6118            Slog.w(TAG, "Process " + app + " failed to attach");
6119            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6120                    pid, app.uid, app.processName);
6121            removeProcessNameLocked(app.processName, app.uid);
6122            if (mHeavyWeightProcess == app) {
6123                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6124                        mHeavyWeightProcess.userId, 0));
6125                mHeavyWeightProcess = null;
6126            }
6127            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6128            if (app.isolated) {
6129                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6130            }
6131            // Take care of any launching providers waiting for this process.
6132            cleanupAppInLaunchingProvidersLocked(app, true);
6133            // Take care of any services that are waiting for the process.
6134            mServices.processStartTimedOutLocked(app);
6135            app.kill("start timeout", true);
6136            removeLruProcessLocked(app);
6137            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6138                Slog.w(TAG, "Unattached app died before backup, skipping");
6139                try {
6140                    IBackupManager bm = IBackupManager.Stub.asInterface(
6141                            ServiceManager.getService(Context.BACKUP_SERVICE));
6142                    bm.agentDisconnected(app.info.packageName);
6143                } catch (RemoteException e) {
6144                    // Can't happen; the backup manager is local
6145                }
6146            }
6147            if (isPendingBroadcastProcessLocked(pid)) {
6148                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6149                skipPendingBroadcastLocked(pid);
6150            }
6151        } else {
6152            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6153        }
6154    }
6155
6156    private final boolean attachApplicationLocked(IApplicationThread thread,
6157            int pid) {
6158
6159        // Find the application record that is being attached...  either via
6160        // the pid if we are running in multiple processes, or just pull the
6161        // next app record if we are emulating process with anonymous threads.
6162        ProcessRecord app;
6163        if (pid != MY_PID && pid >= 0) {
6164            synchronized (mPidsSelfLocked) {
6165                app = mPidsSelfLocked.get(pid);
6166            }
6167        } else {
6168            app = null;
6169        }
6170
6171        if (app == null) {
6172            Slog.w(TAG, "No pending application record for pid " + pid
6173                    + " (IApplicationThread " + thread + "); dropping process");
6174            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6175            if (pid > 0 && pid != MY_PID) {
6176                Process.killProcessQuiet(pid);
6177                //TODO: killProcessGroup(app.info.uid, pid);
6178            } else {
6179                try {
6180                    thread.scheduleExit();
6181                } catch (Exception e) {
6182                    // Ignore exceptions.
6183                }
6184            }
6185            return false;
6186        }
6187
6188        // If this application record is still attached to a previous
6189        // process, clean it up now.
6190        if (app.thread != null) {
6191            handleAppDiedLocked(app, true, true);
6192        }
6193
6194        // Tell the process all about itself.
6195
6196        if (DEBUG_ALL) Slog.v(
6197                TAG, "Binding process pid " + pid + " to record " + app);
6198
6199        final String processName = app.processName;
6200        try {
6201            AppDeathRecipient adr = new AppDeathRecipient(
6202                    app, pid, thread);
6203            thread.asBinder().linkToDeath(adr, 0);
6204            app.deathRecipient = adr;
6205        } catch (RemoteException e) {
6206            app.resetPackageList(mProcessStats);
6207            startProcessLocked(app, "link fail", processName);
6208            return false;
6209        }
6210
6211        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6212
6213        app.makeActive(thread, mProcessStats);
6214        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6215        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6216        app.forcingToForeground = null;
6217        updateProcessForegroundLocked(app, false, false);
6218        app.hasShownUi = false;
6219        app.debugging = false;
6220        app.cached = false;
6221        app.killedByAm = false;
6222
6223        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6224
6225        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6226        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6227
6228        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6229            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6230            msg.obj = app;
6231            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6232        }
6233
6234        if (!normalMode) {
6235            Slog.i(TAG, "Launching preboot mode app: " + app);
6236        }
6237
6238        if (DEBUG_ALL) Slog.v(
6239            TAG, "New app record " + app
6240            + " thread=" + thread.asBinder() + " pid=" + pid);
6241        try {
6242            int testMode = IApplicationThread.DEBUG_OFF;
6243            if (mDebugApp != null && mDebugApp.equals(processName)) {
6244                testMode = mWaitForDebugger
6245                    ? IApplicationThread.DEBUG_WAIT
6246                    : IApplicationThread.DEBUG_ON;
6247                app.debugging = true;
6248                if (mDebugTransient) {
6249                    mDebugApp = mOrigDebugApp;
6250                    mWaitForDebugger = mOrigWaitForDebugger;
6251                }
6252            }
6253            String profileFile = app.instrumentationProfileFile;
6254            ParcelFileDescriptor profileFd = null;
6255            int samplingInterval = 0;
6256            boolean profileAutoStop = false;
6257            if (mProfileApp != null && mProfileApp.equals(processName)) {
6258                mProfileProc = app;
6259                profileFile = mProfileFile;
6260                profileFd = mProfileFd;
6261                samplingInterval = mSamplingInterval;
6262                profileAutoStop = mAutoStopProfiler;
6263            }
6264            boolean enableTrackAllocation = false;
6265            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6266                enableTrackAllocation = true;
6267                mTrackAllocationApp = null;
6268            }
6269
6270            // If the app is being launched for restore or full backup, set it up specially
6271            boolean isRestrictedBackupMode = false;
6272            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6273                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6274                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6275                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6276            }
6277
6278            notifyPackageUse(app.instrumentationInfo != null
6279                    ? app.instrumentationInfo.packageName
6280                    : app.info.packageName);
6281            if (app.instrumentationClass != null) {
6282                notifyPackageUse(app.instrumentationClass.getPackageName());
6283            }
6284            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6285                    + processName + " with config " + mConfiguration);
6286            ApplicationInfo appInfo = app.instrumentationInfo != null
6287                    ? app.instrumentationInfo : app.info;
6288            app.compat = compatibilityInfoForPackageLocked(appInfo);
6289            if (profileFd != null) {
6290                profileFd = profileFd.dup();
6291            }
6292            ProfilerInfo profilerInfo = profileFile == null ? null
6293                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6294            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6295                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6296                    app.instrumentationUiAutomationConnection, testMode,
6297                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6298                    isRestrictedBackupMode || !normalMode, app.persistent,
6299                    new Configuration(mConfiguration), app.compat,
6300                    getCommonServicesLocked(app.isolated),
6301                    mCoreSettingsObserver.getCoreSettingsLocked());
6302            updateLruProcessLocked(app, false, null);
6303            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6304        } catch (Exception e) {
6305            // todo: Yikes!  What should we do?  For now we will try to
6306            // start another process, but that could easily get us in
6307            // an infinite loop of restarting processes...
6308            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6309
6310            app.resetPackageList(mProcessStats);
6311            app.unlinkDeathRecipient();
6312            startProcessLocked(app, "bind fail", processName);
6313            return false;
6314        }
6315
6316        // Remove this record from the list of starting applications.
6317        mPersistentStartingProcesses.remove(app);
6318        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6319                "Attach application locked removing on hold: " + app);
6320        mProcessesOnHold.remove(app);
6321
6322        boolean badApp = false;
6323        boolean didSomething = false;
6324
6325        // See if the top visible activity is waiting to run in this process...
6326        if (normalMode) {
6327            try {
6328                if (mStackSupervisor.attachApplicationLocked(app)) {
6329                    didSomething = true;
6330                }
6331            } catch (Exception e) {
6332                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6333                badApp = true;
6334            }
6335        }
6336
6337        // Find any services that should be running in this process...
6338        if (!badApp) {
6339            try {
6340                didSomething |= mServices.attachApplicationLocked(app, processName);
6341            } catch (Exception e) {
6342                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6343                badApp = true;
6344            }
6345        }
6346
6347        // Check if a next-broadcast receiver is in this process...
6348        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6349            try {
6350                didSomething |= sendPendingBroadcastsLocked(app);
6351            } catch (Exception e) {
6352                // If the app died trying to launch the receiver we declare it 'bad'
6353                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6354                badApp = true;
6355            }
6356        }
6357
6358        // Check whether the next backup agent is in this process...
6359        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6360            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6361                    "New app is backup target, launching agent for " + app);
6362            notifyPackageUse(mBackupTarget.appInfo.packageName);
6363            try {
6364                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6365                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6366                        mBackupTarget.backupMode);
6367            } catch (Exception e) {
6368                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6369                badApp = true;
6370            }
6371        }
6372
6373        if (badApp) {
6374            app.kill("error during init", true);
6375            handleAppDiedLocked(app, false, true);
6376            return false;
6377        }
6378
6379        if (!didSomething) {
6380            updateOomAdjLocked();
6381        }
6382
6383        return true;
6384    }
6385
6386    @Override
6387    public final void attachApplication(IApplicationThread thread) {
6388        synchronized (this) {
6389            int callingPid = Binder.getCallingPid();
6390            final long origId = Binder.clearCallingIdentity();
6391            attachApplicationLocked(thread, callingPid);
6392            Binder.restoreCallingIdentity(origId);
6393        }
6394    }
6395
6396    @Override
6397    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6398        final long origId = Binder.clearCallingIdentity();
6399        synchronized (this) {
6400            ActivityStack stack = ActivityRecord.getStackLocked(token);
6401            if (stack != null) {
6402                ActivityRecord r =
6403                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6404                if (stopProfiling) {
6405                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6406                        try {
6407                            mProfileFd.close();
6408                        } catch (IOException e) {
6409                        }
6410                        clearProfilerLocked();
6411                    }
6412                }
6413            }
6414        }
6415        Binder.restoreCallingIdentity(origId);
6416    }
6417
6418    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6419        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6420                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6421    }
6422
6423    void enableScreenAfterBoot() {
6424        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6425                SystemClock.uptimeMillis());
6426        mWindowManager.enableScreenAfterBoot();
6427
6428        synchronized (this) {
6429            updateEventDispatchingLocked();
6430        }
6431    }
6432
6433    @Override
6434    public void showBootMessage(final CharSequence msg, final boolean always) {
6435        if (Binder.getCallingUid() != Process.myUid()) {
6436            // These days only the core system can call this, so apps can't get in
6437            // the way of what we show about running them.
6438        }
6439        mWindowManager.showBootMessage(msg, always);
6440    }
6441
6442    @Override
6443    public void keyguardWaitingForActivityDrawn() {
6444        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6445        final long token = Binder.clearCallingIdentity();
6446        try {
6447            synchronized (this) {
6448                if (DEBUG_LOCKSCREEN) logLockScreen("");
6449                mWindowManager.keyguardWaitingForActivityDrawn();
6450                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6451                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6452                    updateSleepIfNeededLocked();
6453                }
6454            }
6455        } finally {
6456            Binder.restoreCallingIdentity(token);
6457        }
6458    }
6459
6460    @Override
6461    public void keyguardGoingAway(boolean disableWindowAnimations,
6462            boolean keyguardGoingToNotificationShade) {
6463        enforceNotIsolatedCaller("keyguardGoingAway");
6464        final long token = Binder.clearCallingIdentity();
6465        try {
6466            synchronized (this) {
6467                if (DEBUG_LOCKSCREEN) logLockScreen("");
6468                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6469                        keyguardGoingToNotificationShade);
6470                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6471                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6472                    updateSleepIfNeededLocked();
6473
6474                    // Some stack visibility might change (e.g. docked stack)
6475                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6476                }
6477            }
6478        } finally {
6479            Binder.restoreCallingIdentity(token);
6480        }
6481    }
6482
6483    final void finishBooting() {
6484        synchronized (this) {
6485            if (!mBootAnimationComplete) {
6486                mCallFinishBooting = true;
6487                return;
6488            }
6489            mCallFinishBooting = false;
6490        }
6491
6492        ArraySet<String> completedIsas = new ArraySet<String>();
6493        for (String abi : Build.SUPPORTED_ABIS) {
6494            Process.establishZygoteConnectionForAbi(abi);
6495            final String instructionSet = VMRuntime.getInstructionSet(abi);
6496            if (!completedIsas.contains(instructionSet)) {
6497                try {
6498                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6499                } catch (InstallerException e) {
6500                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6501                }
6502                completedIsas.add(instructionSet);
6503            }
6504        }
6505
6506        IntentFilter pkgFilter = new IntentFilter();
6507        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6508        pkgFilter.addDataScheme("package");
6509        mContext.registerReceiver(new BroadcastReceiver() {
6510            @Override
6511            public void onReceive(Context context, Intent intent) {
6512                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6513                if (pkgs != null) {
6514                    for (String pkg : pkgs) {
6515                        synchronized (ActivityManagerService.this) {
6516                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6517                                    0, "query restart")) {
6518                                setResultCode(Activity.RESULT_OK);
6519                                return;
6520                            }
6521                        }
6522                    }
6523                }
6524            }
6525        }, pkgFilter);
6526
6527        IntentFilter dumpheapFilter = new IntentFilter();
6528        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6529        mContext.registerReceiver(new BroadcastReceiver() {
6530            @Override
6531            public void onReceive(Context context, Intent intent) {
6532                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6533                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6534                } else {
6535                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6536                }
6537            }
6538        }, dumpheapFilter);
6539
6540        mProcessStartLogger.registerListener(mContext);
6541
6542        // Let system services know.
6543        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6544
6545        synchronized (this) {
6546            // Ensure that any processes we had put on hold are now started
6547            // up.
6548            final int NP = mProcessesOnHold.size();
6549            if (NP > 0) {
6550                ArrayList<ProcessRecord> procs =
6551                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6552                for (int ip=0; ip<NP; ip++) {
6553                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6554                            + procs.get(ip));
6555                    startProcessLocked(procs.get(ip), "on-hold", null);
6556                }
6557            }
6558
6559            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6560                // Start looking for apps that are abusing wake locks.
6561                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6562                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6563                // Tell anyone interested that we are done booting!
6564                SystemProperties.set("sys.boot_completed", "1");
6565
6566                // And trigger dev.bootcomplete if we are not showing encryption progress
6567                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6568                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6569                    SystemProperties.set("dev.bootcomplete", "1");
6570                }
6571                mUserController.sendBootCompletedLocked(
6572                        new IIntentReceiver.Stub() {
6573                            @Override
6574                            public void performReceive(Intent intent, int resultCode,
6575                                    String data, Bundle extras, boolean ordered,
6576                                    boolean sticky, int sendingUser) {
6577                                synchronized (ActivityManagerService.this) {
6578                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6579                                            true, false);
6580                                }
6581                            }
6582                        });
6583                scheduleStartProfilesLocked();
6584            }
6585        }
6586    }
6587
6588    @Override
6589    public void bootAnimationComplete() {
6590        final boolean callFinishBooting;
6591        synchronized (this) {
6592            callFinishBooting = mCallFinishBooting;
6593            mBootAnimationComplete = true;
6594        }
6595        if (callFinishBooting) {
6596            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6597            finishBooting();
6598            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6599        }
6600    }
6601
6602    final void ensureBootCompleted() {
6603        boolean booting;
6604        boolean enableScreen;
6605        synchronized (this) {
6606            booting = mBooting;
6607            mBooting = false;
6608            enableScreen = !mBooted;
6609            mBooted = true;
6610        }
6611
6612        if (booting) {
6613            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6614            finishBooting();
6615            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6616        }
6617
6618        if (enableScreen) {
6619            enableScreenAfterBoot();
6620        }
6621    }
6622
6623    @Override
6624    public final void activityResumed(IBinder token) {
6625        final long origId = Binder.clearCallingIdentity();
6626        synchronized(this) {
6627            ActivityStack stack = ActivityRecord.getStackLocked(token);
6628            if (stack != null) {
6629                ActivityRecord.activityResumedLocked(token);
6630            }
6631        }
6632        Binder.restoreCallingIdentity(origId);
6633    }
6634
6635    @Override
6636    public final void activityPaused(IBinder token) {
6637        final long origId = Binder.clearCallingIdentity();
6638        synchronized(this) {
6639            ActivityStack stack = ActivityRecord.getStackLocked(token);
6640            if (stack != null) {
6641                stack.activityPausedLocked(token, false);
6642            }
6643        }
6644        Binder.restoreCallingIdentity(origId);
6645    }
6646
6647    @Override
6648    public final void activityStopped(IBinder token, Bundle icicle,
6649            PersistableBundle persistentState, CharSequence description) {
6650        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6651
6652        // Refuse possible leaked file descriptors
6653        if (icicle != null && icicle.hasFileDescriptors()) {
6654            throw new IllegalArgumentException("File descriptors passed in Bundle");
6655        }
6656
6657        final long origId = Binder.clearCallingIdentity();
6658
6659        synchronized (this) {
6660            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6661            if (r != null) {
6662                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6663            }
6664        }
6665
6666        trimApplications();
6667
6668        Binder.restoreCallingIdentity(origId);
6669    }
6670
6671    @Override
6672    public final void activityDestroyed(IBinder token) {
6673        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6674        synchronized (this) {
6675            ActivityStack stack = ActivityRecord.getStackLocked(token);
6676            if (stack != null) {
6677                stack.activityDestroyedLocked(token, "activityDestroyed");
6678            }
6679        }
6680    }
6681
6682    @Override
6683    public final void activityRelaunched(IBinder token) {
6684        final long origId = Binder.clearCallingIdentity();
6685        synchronized (this) {
6686            mStackSupervisor.activityRelaunchedLocked(token);
6687        }
6688        Binder.restoreCallingIdentity(origId);
6689    }
6690
6691    @Override
6692    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6693            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6694        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6695                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6696        synchronized (this) {
6697            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6698            if (record == null) {
6699                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6700                        + "found for: " + token);
6701            }
6702            record.setSizeConfigurations(horizontalSizeConfiguration,
6703                    verticalSizeConfigurations, smallestSizeConfigurations);
6704        }
6705    }
6706
6707    @Override
6708    public final void backgroundResourcesReleased(IBinder token) {
6709        final long origId = Binder.clearCallingIdentity();
6710        try {
6711            synchronized (this) {
6712                ActivityStack stack = ActivityRecord.getStackLocked(token);
6713                if (stack != null) {
6714                    stack.backgroundResourcesReleased();
6715                }
6716            }
6717        } finally {
6718            Binder.restoreCallingIdentity(origId);
6719        }
6720    }
6721
6722    @Override
6723    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6724        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6725    }
6726
6727    @Override
6728    public final void notifyEnterAnimationComplete(IBinder token) {
6729        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6730    }
6731
6732    @Override
6733    public String getCallingPackage(IBinder token) {
6734        synchronized (this) {
6735            ActivityRecord r = getCallingRecordLocked(token);
6736            return r != null ? r.info.packageName : null;
6737        }
6738    }
6739
6740    @Override
6741    public ComponentName getCallingActivity(IBinder token) {
6742        synchronized (this) {
6743            ActivityRecord r = getCallingRecordLocked(token);
6744            return r != null ? r.intent.getComponent() : null;
6745        }
6746    }
6747
6748    private ActivityRecord getCallingRecordLocked(IBinder token) {
6749        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6750        if (r == null) {
6751            return null;
6752        }
6753        return r.resultTo;
6754    }
6755
6756    @Override
6757    public ComponentName getActivityClassForToken(IBinder token) {
6758        synchronized(this) {
6759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6760            if (r == null) {
6761                return null;
6762            }
6763            return r.intent.getComponent();
6764        }
6765    }
6766
6767    @Override
6768    public String getPackageForToken(IBinder token) {
6769        synchronized(this) {
6770            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6771            if (r == null) {
6772                return null;
6773            }
6774            return r.packageName;
6775        }
6776    }
6777
6778    @Override
6779    public boolean isRootVoiceInteraction(IBinder token) {
6780        synchronized(this) {
6781            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6782            if (r == null) {
6783                return false;
6784            }
6785            return r.rootVoiceInteraction;
6786        }
6787    }
6788
6789    @Override
6790    public IIntentSender getIntentSender(int type,
6791            String packageName, IBinder token, String resultWho,
6792            int requestCode, Intent[] intents, String[] resolvedTypes,
6793            int flags, Bundle bOptions, int userId) {
6794        enforceNotIsolatedCaller("getIntentSender");
6795        // Refuse possible leaked file descriptors
6796        if (intents != null) {
6797            if (intents.length < 1) {
6798                throw new IllegalArgumentException("Intents array length must be >= 1");
6799            }
6800            for (int i=0; i<intents.length; i++) {
6801                Intent intent = intents[i];
6802                if (intent != null) {
6803                    if (intent.hasFileDescriptors()) {
6804                        throw new IllegalArgumentException("File descriptors passed in Intent");
6805                    }
6806                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6807                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6808                        throw new IllegalArgumentException(
6809                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6810                    }
6811                    intents[i] = new Intent(intent);
6812                }
6813            }
6814            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6815                throw new IllegalArgumentException(
6816                        "Intent array length does not match resolvedTypes length");
6817            }
6818        }
6819        if (bOptions != null) {
6820            if (bOptions.hasFileDescriptors()) {
6821                throw new IllegalArgumentException("File descriptors passed in options");
6822            }
6823        }
6824
6825        synchronized(this) {
6826            int callingUid = Binder.getCallingUid();
6827            int origUserId = userId;
6828            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6829                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6830                    ALLOW_NON_FULL, "getIntentSender", null);
6831            if (origUserId == UserHandle.USER_CURRENT) {
6832                // We don't want to evaluate this until the pending intent is
6833                // actually executed.  However, we do want to always do the
6834                // security checking for it above.
6835                userId = UserHandle.USER_CURRENT;
6836            }
6837            try {
6838                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6839                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6840                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6841                    if (!UserHandle.isSameApp(callingUid, uid)) {
6842                        String msg = "Permission Denial: getIntentSender() from pid="
6843                            + Binder.getCallingPid()
6844                            + ", uid=" + Binder.getCallingUid()
6845                            + ", (need uid=" + uid + ")"
6846                            + " is not allowed to send as package " + packageName;
6847                        Slog.w(TAG, msg);
6848                        throw new SecurityException(msg);
6849                    }
6850                }
6851
6852                return getIntentSenderLocked(type, packageName, callingUid, userId,
6853                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6854
6855            } catch (RemoteException e) {
6856                throw new SecurityException(e);
6857            }
6858        }
6859    }
6860
6861    IIntentSender getIntentSenderLocked(int type, String packageName,
6862            int callingUid, int userId, IBinder token, String resultWho,
6863            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6864            Bundle bOptions) {
6865        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6866        ActivityRecord activity = null;
6867        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6868            activity = ActivityRecord.isInStackLocked(token);
6869            if (activity == null) {
6870                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6871                return null;
6872            }
6873            if (activity.finishing) {
6874                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6875                return null;
6876            }
6877        }
6878
6879        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6880        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6881        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6882        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6883                |PendingIntent.FLAG_UPDATE_CURRENT);
6884
6885        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6886                type, packageName, activity, resultWho,
6887                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6888        WeakReference<PendingIntentRecord> ref;
6889        ref = mIntentSenderRecords.get(key);
6890        PendingIntentRecord rec = ref != null ? ref.get() : null;
6891        if (rec != null) {
6892            if (!cancelCurrent) {
6893                if (updateCurrent) {
6894                    if (rec.key.requestIntent != null) {
6895                        rec.key.requestIntent.replaceExtras(intents != null ?
6896                                intents[intents.length - 1] : null);
6897                    }
6898                    if (intents != null) {
6899                        intents[intents.length-1] = rec.key.requestIntent;
6900                        rec.key.allIntents = intents;
6901                        rec.key.allResolvedTypes = resolvedTypes;
6902                    } else {
6903                        rec.key.allIntents = null;
6904                        rec.key.allResolvedTypes = null;
6905                    }
6906                }
6907                return rec;
6908            }
6909            rec.canceled = true;
6910            mIntentSenderRecords.remove(key);
6911        }
6912        if (noCreate) {
6913            return rec;
6914        }
6915        rec = new PendingIntentRecord(this, key, callingUid);
6916        mIntentSenderRecords.put(key, rec.ref);
6917        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6918            if (activity.pendingResults == null) {
6919                activity.pendingResults
6920                        = new HashSet<WeakReference<PendingIntentRecord>>();
6921            }
6922            activity.pendingResults.add(rec.ref);
6923        }
6924        return rec;
6925    }
6926
6927    @Override
6928    public void cancelIntentSender(IIntentSender sender) {
6929        if (!(sender instanceof PendingIntentRecord)) {
6930            return;
6931        }
6932        synchronized(this) {
6933            PendingIntentRecord rec = (PendingIntentRecord)sender;
6934            try {
6935                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6936                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6937                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6938                    String msg = "Permission Denial: cancelIntentSender() from pid="
6939                        + Binder.getCallingPid()
6940                        + ", uid=" + Binder.getCallingUid()
6941                        + " is not allowed to cancel packges "
6942                        + rec.key.packageName;
6943                    Slog.w(TAG, msg);
6944                    throw new SecurityException(msg);
6945                }
6946            } catch (RemoteException e) {
6947                throw new SecurityException(e);
6948            }
6949            cancelIntentSenderLocked(rec, true);
6950        }
6951    }
6952
6953    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6954        rec.canceled = true;
6955        mIntentSenderRecords.remove(rec.key);
6956        if (cleanActivity && rec.key.activity != null) {
6957            rec.key.activity.pendingResults.remove(rec.ref);
6958        }
6959    }
6960
6961    @Override
6962    public String getPackageForIntentSender(IIntentSender pendingResult) {
6963        if (!(pendingResult instanceof PendingIntentRecord)) {
6964            return null;
6965        }
6966        try {
6967            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6968            return res.key.packageName;
6969        } catch (ClassCastException e) {
6970        }
6971        return null;
6972    }
6973
6974    @Override
6975    public int getUidForIntentSender(IIntentSender sender) {
6976        if (sender instanceof PendingIntentRecord) {
6977            try {
6978                PendingIntentRecord res = (PendingIntentRecord)sender;
6979                return res.uid;
6980            } catch (ClassCastException e) {
6981            }
6982        }
6983        return -1;
6984    }
6985
6986    @Override
6987    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6988        if (!(pendingResult instanceof PendingIntentRecord)) {
6989            return false;
6990        }
6991        try {
6992            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6993            if (res.key.allIntents == null) {
6994                return false;
6995            }
6996            for (int i=0; i<res.key.allIntents.length; i++) {
6997                Intent intent = res.key.allIntents[i];
6998                if (intent.getPackage() != null && intent.getComponent() != null) {
6999                    return false;
7000                }
7001            }
7002            return true;
7003        } catch (ClassCastException e) {
7004        }
7005        return false;
7006    }
7007
7008    @Override
7009    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7010        if (!(pendingResult instanceof PendingIntentRecord)) {
7011            return false;
7012        }
7013        try {
7014            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7015            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7016                return true;
7017            }
7018            return false;
7019        } catch (ClassCastException e) {
7020        }
7021        return false;
7022    }
7023
7024    @Override
7025    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7026        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7027                "getIntentForIntentSender()");
7028        if (!(pendingResult instanceof PendingIntentRecord)) {
7029            return null;
7030        }
7031        try {
7032            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7033            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7034        } catch (ClassCastException e) {
7035        }
7036        return null;
7037    }
7038
7039    @Override
7040    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7041        if (!(pendingResult instanceof PendingIntentRecord)) {
7042            return null;
7043        }
7044        try {
7045            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7046            synchronized (this) {
7047                return getTagForIntentSenderLocked(res, prefix);
7048            }
7049        } catch (ClassCastException e) {
7050        }
7051        return null;
7052    }
7053
7054    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7055        final Intent intent = res.key.requestIntent;
7056        if (intent != null) {
7057            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7058                    || res.lastTagPrefix.equals(prefix))) {
7059                return res.lastTag;
7060            }
7061            res.lastTagPrefix = prefix;
7062            final StringBuilder sb = new StringBuilder(128);
7063            if (prefix != null) {
7064                sb.append(prefix);
7065            }
7066            if (intent.getAction() != null) {
7067                sb.append(intent.getAction());
7068            } else if (intent.getComponent() != null) {
7069                intent.getComponent().appendShortString(sb);
7070            } else {
7071                sb.append("?");
7072            }
7073            return res.lastTag = sb.toString();
7074        }
7075        return null;
7076    }
7077
7078    @Override
7079    public void setProcessLimit(int max) {
7080        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7081                "setProcessLimit()");
7082        synchronized (this) {
7083            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7084            mProcessLimitOverride = max;
7085        }
7086        trimApplications();
7087    }
7088
7089    @Override
7090    public int getProcessLimit() {
7091        synchronized (this) {
7092            return mProcessLimitOverride;
7093        }
7094    }
7095
7096    void foregroundTokenDied(ForegroundToken token) {
7097        synchronized (ActivityManagerService.this) {
7098            synchronized (mPidsSelfLocked) {
7099                ForegroundToken cur
7100                    = mForegroundProcesses.get(token.pid);
7101                if (cur != token) {
7102                    return;
7103                }
7104                mForegroundProcesses.remove(token.pid);
7105                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7106                if (pr == null) {
7107                    return;
7108                }
7109                pr.forcingToForeground = null;
7110                updateProcessForegroundLocked(pr, false, false);
7111            }
7112            updateOomAdjLocked();
7113        }
7114    }
7115
7116    @Override
7117    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7118        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7119                "setProcessForeground()");
7120        synchronized(this) {
7121            boolean changed = false;
7122
7123            synchronized (mPidsSelfLocked) {
7124                ProcessRecord pr = mPidsSelfLocked.get(pid);
7125                if (pr == null && isForeground) {
7126                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7127                    return;
7128                }
7129                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7130                if (oldToken != null) {
7131                    oldToken.token.unlinkToDeath(oldToken, 0);
7132                    mForegroundProcesses.remove(pid);
7133                    if (pr != null) {
7134                        pr.forcingToForeground = null;
7135                    }
7136                    changed = true;
7137                }
7138                if (isForeground && token != null) {
7139                    ForegroundToken newToken = new ForegroundToken() {
7140                        @Override
7141                        public void binderDied() {
7142                            foregroundTokenDied(this);
7143                        }
7144                    };
7145                    newToken.pid = pid;
7146                    newToken.token = token;
7147                    try {
7148                        token.linkToDeath(newToken, 0);
7149                        mForegroundProcesses.put(pid, newToken);
7150                        pr.forcingToForeground = token;
7151                        changed = true;
7152                    } catch (RemoteException e) {
7153                        // If the process died while doing this, we will later
7154                        // do the cleanup with the process death link.
7155                    }
7156                }
7157            }
7158
7159            if (changed) {
7160                updateOomAdjLocked();
7161            }
7162        }
7163    }
7164
7165    @Override
7166    public boolean isAppForeground(int uid) throws RemoteException {
7167        synchronized (this) {
7168            UidRecord uidRec = mActiveUids.get(uid);
7169            if (uidRec == null || uidRec.idle) {
7170                return false;
7171            }
7172            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7173        }
7174    }
7175
7176    @Override
7177    public boolean inMultiWindow(IBinder token) {
7178        final long origId = Binder.clearCallingIdentity();
7179        try {
7180            synchronized(this) {
7181                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7182                if (r == null) {
7183                    return false;
7184                }
7185                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7186                return !r.task.mFullscreen;
7187            }
7188        } finally {
7189            Binder.restoreCallingIdentity(origId);
7190        }
7191    }
7192
7193    @Override
7194    public boolean inPictureInPicture(IBinder token) {
7195        final long origId = Binder.clearCallingIdentity();
7196        try {
7197            synchronized(this) {
7198                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7199                if (stack == null) {
7200                    return false;
7201                }
7202                return stack.mStackId == PINNED_STACK_ID;
7203            }
7204        } finally {
7205            Binder.restoreCallingIdentity(origId);
7206        }
7207    }
7208
7209    @Override
7210    public void enterPictureInPicture(IBinder token) {
7211        final long origId = Binder.clearCallingIdentity();
7212        try {
7213            synchronized(this) {
7214                if (!mSupportsPictureInPicture) {
7215                    throw new IllegalStateException("enterPictureInPicture: "
7216                            + "Device doesn't support picture-in-picture mode.");
7217                }
7218
7219                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7220
7221                if (r == null) {
7222                    throw new IllegalStateException("enterPictureInPicture: "
7223                            + "Can't find activity for token=" + token);
7224                }
7225
7226                if (!r.supportsPictureInPicture()) {
7227                    throw new IllegalArgumentException("enterPictureInPicture: "
7228                            + "Picture-In-Picture not supported for r=" + r);
7229                }
7230
7231                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7232                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7233                        ? mDefaultPinnedStackBounds : null;
7234
7235                mStackSupervisor.moveActivityToPinnedStackLocked(
7236                        r, "enterPictureInPicture", bounds);
7237            }
7238        } finally {
7239            Binder.restoreCallingIdentity(origId);
7240        }
7241    }
7242
7243    // =========================================================
7244    // PROCESS INFO
7245    // =========================================================
7246
7247    static class ProcessInfoService extends IProcessInfoService.Stub {
7248        final ActivityManagerService mActivityManagerService;
7249        ProcessInfoService(ActivityManagerService activityManagerService) {
7250            mActivityManagerService = activityManagerService;
7251        }
7252
7253        @Override
7254        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7255            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7256                    /*in*/ pids, /*out*/ states, null);
7257        }
7258
7259        @Override
7260        public void getProcessStatesAndOomScoresFromPids(
7261                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7262            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7263                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7264        }
7265    }
7266
7267    /**
7268     * For each PID in the given input array, write the current process state
7269     * for that process into the states array, or -1 to indicate that no
7270     * process with the given PID exists. If scores array is provided, write
7271     * the oom score for the process into the scores array, with INVALID_ADJ
7272     * indicating the PID doesn't exist.
7273     */
7274    public void getProcessStatesAndOomScoresForPIDs(
7275            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7276        if (scores != null) {
7277            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7278                    "getProcessStatesAndOomScoresForPIDs()");
7279        }
7280
7281        if (pids == null) {
7282            throw new NullPointerException("pids");
7283        } else if (states == null) {
7284            throw new NullPointerException("states");
7285        } else if (pids.length != states.length) {
7286            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7287        } else if (scores != null && pids.length != scores.length) {
7288            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7289        }
7290
7291        synchronized (mPidsSelfLocked) {
7292            for (int i = 0; i < pids.length; i++) {
7293                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7294                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7295                        pr.curProcState;
7296                if (scores != null) {
7297                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7298                }
7299            }
7300        }
7301    }
7302
7303    // =========================================================
7304    // PERMISSIONS
7305    // =========================================================
7306
7307    static class PermissionController extends IPermissionController.Stub {
7308        ActivityManagerService mActivityManagerService;
7309        PermissionController(ActivityManagerService activityManagerService) {
7310            mActivityManagerService = activityManagerService;
7311        }
7312
7313        @Override
7314        public boolean checkPermission(String permission, int pid, int uid) {
7315            return mActivityManagerService.checkPermission(permission, pid,
7316                    uid) == PackageManager.PERMISSION_GRANTED;
7317        }
7318
7319        @Override
7320        public String[] getPackagesForUid(int uid) {
7321            return mActivityManagerService.mContext.getPackageManager()
7322                    .getPackagesForUid(uid);
7323        }
7324
7325        @Override
7326        public boolean isRuntimePermission(String permission) {
7327            try {
7328                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7329                        .getPermissionInfo(permission, 0);
7330                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7331            } catch (NameNotFoundException nnfe) {
7332                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7333            }
7334            return false;
7335        }
7336    }
7337
7338    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7339        @Override
7340        public int checkComponentPermission(String permission, int pid, int uid,
7341                int owningUid, boolean exported) {
7342            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7343                    owningUid, exported);
7344        }
7345
7346        @Override
7347        public Object getAMSLock() {
7348            return ActivityManagerService.this;
7349        }
7350    }
7351
7352    /**
7353     * This can be called with or without the global lock held.
7354     */
7355    int checkComponentPermission(String permission, int pid, int uid,
7356            int owningUid, boolean exported) {
7357        if (pid == MY_PID) {
7358            return PackageManager.PERMISSION_GRANTED;
7359        }
7360        return ActivityManager.checkComponentPermission(permission, uid,
7361                owningUid, exported);
7362    }
7363
7364    /**
7365     * As the only public entry point for permissions checking, this method
7366     * can enforce the semantic that requesting a check on a null global
7367     * permission is automatically denied.  (Internally a null permission
7368     * string is used when calling {@link #checkComponentPermission} in cases
7369     * when only uid-based security is needed.)
7370     *
7371     * This can be called with or without the global lock held.
7372     */
7373    @Override
7374    public int checkPermission(String permission, int pid, int uid) {
7375        if (permission == null) {
7376            return PackageManager.PERMISSION_DENIED;
7377        }
7378        return checkComponentPermission(permission, pid, uid, -1, true);
7379    }
7380
7381    @Override
7382    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7383        if (permission == null) {
7384            return PackageManager.PERMISSION_DENIED;
7385        }
7386
7387        // We might be performing an operation on behalf of an indirect binder
7388        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7389        // client identity accordingly before proceeding.
7390        Identity tlsIdentity = sCallerIdentity.get();
7391        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7392            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7393                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7394            uid = tlsIdentity.uid;
7395            pid = tlsIdentity.pid;
7396        }
7397
7398        return checkComponentPermission(permission, pid, uid, -1, true);
7399    }
7400
7401    /**
7402     * Binder IPC calls go through the public entry point.
7403     * This can be called with or without the global lock held.
7404     */
7405    int checkCallingPermission(String permission) {
7406        return checkPermission(permission,
7407                Binder.getCallingPid(),
7408                UserHandle.getAppId(Binder.getCallingUid()));
7409    }
7410
7411    /**
7412     * This can be called with or without the global lock held.
7413     */
7414    void enforceCallingPermission(String permission, String func) {
7415        if (checkCallingPermission(permission)
7416                == PackageManager.PERMISSION_GRANTED) {
7417            return;
7418        }
7419
7420        String msg = "Permission Denial: " + func + " from pid="
7421                + Binder.getCallingPid()
7422                + ", uid=" + Binder.getCallingUid()
7423                + " requires " + permission;
7424        Slog.w(TAG, msg);
7425        throw new SecurityException(msg);
7426    }
7427
7428    /**
7429     * Determine if UID is holding permissions required to access {@link Uri} in
7430     * the given {@link ProviderInfo}. Final permission checking is always done
7431     * in {@link ContentProvider}.
7432     */
7433    private final boolean checkHoldingPermissionsLocked(
7434            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7435        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7436                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7437        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7438            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7439                    != PERMISSION_GRANTED) {
7440                return false;
7441            }
7442        }
7443        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7444    }
7445
7446    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7447            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7448        if (pi.applicationInfo.uid == uid) {
7449            return true;
7450        } else if (!pi.exported) {
7451            return false;
7452        }
7453
7454        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7455        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7456        try {
7457            // check if target holds top-level <provider> permissions
7458            if (!readMet && pi.readPermission != null && considerUidPermissions
7459                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7460                readMet = true;
7461            }
7462            if (!writeMet && pi.writePermission != null && considerUidPermissions
7463                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7464                writeMet = true;
7465            }
7466
7467            // track if unprotected read/write is allowed; any denied
7468            // <path-permission> below removes this ability
7469            boolean allowDefaultRead = pi.readPermission == null;
7470            boolean allowDefaultWrite = pi.writePermission == null;
7471
7472            // check if target holds any <path-permission> that match uri
7473            final PathPermission[] pps = pi.pathPermissions;
7474            if (pps != null) {
7475                final String path = grantUri.uri.getPath();
7476                int i = pps.length;
7477                while (i > 0 && (!readMet || !writeMet)) {
7478                    i--;
7479                    PathPermission pp = pps[i];
7480                    if (pp.match(path)) {
7481                        if (!readMet) {
7482                            final String pprperm = pp.getReadPermission();
7483                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7484                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7485                                    + ": match=" + pp.match(path)
7486                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7487                            if (pprperm != null) {
7488                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7489                                        == PERMISSION_GRANTED) {
7490                                    readMet = true;
7491                                } else {
7492                                    allowDefaultRead = false;
7493                                }
7494                            }
7495                        }
7496                        if (!writeMet) {
7497                            final String ppwperm = pp.getWritePermission();
7498                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7499                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7500                                    + ": match=" + pp.match(path)
7501                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7502                            if (ppwperm != null) {
7503                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7504                                        == PERMISSION_GRANTED) {
7505                                    writeMet = true;
7506                                } else {
7507                                    allowDefaultWrite = false;
7508                                }
7509                            }
7510                        }
7511                    }
7512                }
7513            }
7514
7515            // grant unprotected <provider> read/write, if not blocked by
7516            // <path-permission> above
7517            if (allowDefaultRead) readMet = true;
7518            if (allowDefaultWrite) writeMet = true;
7519
7520        } catch (RemoteException e) {
7521            return false;
7522        }
7523
7524        return readMet && writeMet;
7525    }
7526
7527    public int getAppStartMode(int uid, String packageName) {
7528        synchronized (this) {
7529            return checkAllowBackgroundLocked(uid, packageName, -1);
7530        }
7531    }
7532
7533    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7534        UidRecord uidRec = mActiveUids.get(uid);
7535        if (!mLenientBackgroundCheck) {
7536            if (uidRec == null
7537                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7538                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7539                        packageName) != AppOpsManager.MODE_ALLOWED) {
7540                    return ActivityManager.APP_START_MODE_DELAYED;
7541                }
7542            }
7543
7544        } else if (uidRec == null || uidRec.idle) {
7545            if (callingPid >= 0) {
7546                ProcessRecord proc;
7547                synchronized (mPidsSelfLocked) {
7548                    proc = mPidsSelfLocked.get(callingPid);
7549                }
7550                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7551                    // Whoever is instigating this is in the foreground, so we will allow it
7552                    // to go through.
7553                    return ActivityManager.APP_START_MODE_NORMAL;
7554                }
7555            }
7556            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7557                    != AppOpsManager.MODE_ALLOWED) {
7558                return ActivityManager.APP_START_MODE_DELAYED;
7559            }
7560        }
7561        return ActivityManager.APP_START_MODE_NORMAL;
7562    }
7563
7564    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7565        ProviderInfo pi = null;
7566        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7567        if (cpr != null) {
7568            pi = cpr.info;
7569        } else {
7570            try {
7571                pi = AppGlobals.getPackageManager().resolveContentProvider(
7572                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7573            } catch (RemoteException ex) {
7574            }
7575        }
7576        return pi;
7577    }
7578
7579    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7580        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7581        if (targetUris != null) {
7582            return targetUris.get(grantUri);
7583        }
7584        return null;
7585    }
7586
7587    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7588            String targetPkg, int targetUid, GrantUri grantUri) {
7589        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7590        if (targetUris == null) {
7591            targetUris = Maps.newArrayMap();
7592            mGrantedUriPermissions.put(targetUid, targetUris);
7593        }
7594
7595        UriPermission perm = targetUris.get(grantUri);
7596        if (perm == null) {
7597            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7598            targetUris.put(grantUri, perm);
7599        }
7600
7601        return perm;
7602    }
7603
7604    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7605            final int modeFlags) {
7606        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7607        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7608                : UriPermission.STRENGTH_OWNED;
7609
7610        // Root gets to do everything.
7611        if (uid == 0) {
7612            return true;
7613        }
7614
7615        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7616        if (perms == null) return false;
7617
7618        // First look for exact match
7619        final UriPermission exactPerm = perms.get(grantUri);
7620        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7621            return true;
7622        }
7623
7624        // No exact match, look for prefixes
7625        final int N = perms.size();
7626        for (int i = 0; i < N; i++) {
7627            final UriPermission perm = perms.valueAt(i);
7628            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7629                    && perm.getStrength(modeFlags) >= minStrength) {
7630                return true;
7631            }
7632        }
7633
7634        return false;
7635    }
7636
7637    /**
7638     * @param uri This uri must NOT contain an embedded userId.
7639     * @param userId The userId in which the uri is to be resolved.
7640     */
7641    @Override
7642    public int checkUriPermission(Uri uri, int pid, int uid,
7643            final int modeFlags, int userId, IBinder callerToken) {
7644        enforceNotIsolatedCaller("checkUriPermission");
7645
7646        // Another redirected-binder-call permissions check as in
7647        // {@link checkPermissionWithToken}.
7648        Identity tlsIdentity = sCallerIdentity.get();
7649        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7650            uid = tlsIdentity.uid;
7651            pid = tlsIdentity.pid;
7652        }
7653
7654        // Our own process gets to do everything.
7655        if (pid == MY_PID) {
7656            return PackageManager.PERMISSION_GRANTED;
7657        }
7658        synchronized (this) {
7659            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7660                    ? PackageManager.PERMISSION_GRANTED
7661                    : PackageManager.PERMISSION_DENIED;
7662        }
7663    }
7664
7665    /**
7666     * Check if the targetPkg can be granted permission to access uri by
7667     * the callingUid using the given modeFlags.  Throws a security exception
7668     * if callingUid is not allowed to do this.  Returns the uid of the target
7669     * if the URI permission grant should be performed; returns -1 if it is not
7670     * needed (for example targetPkg already has permission to access the URI).
7671     * If you already know the uid of the target, you can supply it in
7672     * lastTargetUid else set that to -1.
7673     */
7674    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7675            final int modeFlags, int lastTargetUid) {
7676        if (!Intent.isAccessUriMode(modeFlags)) {
7677            return -1;
7678        }
7679
7680        if (targetPkg != null) {
7681            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7682                    "Checking grant " + targetPkg + " permission to " + grantUri);
7683        }
7684
7685        final IPackageManager pm = AppGlobals.getPackageManager();
7686
7687        // If this is not a content: uri, we can't do anything with it.
7688        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7689            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7690                    "Can't grant URI permission for non-content URI: " + grantUri);
7691            return -1;
7692        }
7693
7694        final String authority = grantUri.uri.getAuthority();
7695        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7696        if (pi == null) {
7697            Slog.w(TAG, "No content provider found for permission check: " +
7698                    grantUri.uri.toSafeString());
7699            return -1;
7700        }
7701
7702        int targetUid = lastTargetUid;
7703        if (targetUid < 0 && targetPkg != null) {
7704            try {
7705                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7706                        UserHandle.getUserId(callingUid));
7707                if (targetUid < 0) {
7708                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7709                            "Can't grant URI permission no uid for: " + targetPkg);
7710                    return -1;
7711                }
7712            } catch (RemoteException ex) {
7713                return -1;
7714            }
7715        }
7716
7717        if (targetUid >= 0) {
7718            // First...  does the target actually need this permission?
7719            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7720                // No need to grant the target this permission.
7721                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722                        "Target " + targetPkg + " already has full permission to " + grantUri);
7723                return -1;
7724            }
7725        } else {
7726            // First...  there is no target package, so can anyone access it?
7727            boolean allowed = pi.exported;
7728            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7729                if (pi.readPermission != null) {
7730                    allowed = false;
7731                }
7732            }
7733            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7734                if (pi.writePermission != null) {
7735                    allowed = false;
7736                }
7737            }
7738            if (allowed) {
7739                return -1;
7740            }
7741        }
7742
7743        /* There is a special cross user grant if:
7744         * - The target is on another user.
7745         * - Apps on the current user can access the uri without any uid permissions.
7746         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7747         * grant uri permissions.
7748         */
7749        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7750                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7751                modeFlags, false /*without considering the uid permissions*/);
7752
7753        // Second...  is the provider allowing granting of URI permissions?
7754        if (!specialCrossUserGrant) {
7755            if (!pi.grantUriPermissions) {
7756                throw new SecurityException("Provider " + pi.packageName
7757                        + "/" + pi.name
7758                        + " does not allow granting of Uri permissions (uri "
7759                        + grantUri + ")");
7760            }
7761            if (pi.uriPermissionPatterns != null) {
7762                final int N = pi.uriPermissionPatterns.length;
7763                boolean allowed = false;
7764                for (int i=0; i<N; i++) {
7765                    if (pi.uriPermissionPatterns[i] != null
7766                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7767                        allowed = true;
7768                        break;
7769                    }
7770                }
7771                if (!allowed) {
7772                    throw new SecurityException("Provider " + pi.packageName
7773                            + "/" + pi.name
7774                            + " does not allow granting of permission to path of Uri "
7775                            + grantUri);
7776                }
7777            }
7778        }
7779
7780        // Third...  does the caller itself have permission to access
7781        // this uri?
7782        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7783            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7784                // Require they hold a strong enough Uri permission
7785                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7786                    throw new SecurityException("Uid " + callingUid
7787                            + " does not have permission to uri " + grantUri);
7788                }
7789            }
7790        }
7791        return targetUid;
7792    }
7793
7794    /**
7795     * @param uri This uri must NOT contain an embedded userId.
7796     * @param userId The userId in which the uri is to be resolved.
7797     */
7798    @Override
7799    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7800            final int modeFlags, int userId) {
7801        enforceNotIsolatedCaller("checkGrantUriPermission");
7802        synchronized(this) {
7803            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7804                    new GrantUri(userId, uri, false), modeFlags, -1);
7805        }
7806    }
7807
7808    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7809            final int modeFlags, UriPermissionOwner owner) {
7810        if (!Intent.isAccessUriMode(modeFlags)) {
7811            return;
7812        }
7813
7814        // So here we are: the caller has the assumed permission
7815        // to the uri, and the target doesn't.  Let's now give this to
7816        // the target.
7817
7818        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7819                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7820
7821        final String authority = grantUri.uri.getAuthority();
7822        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7823        if (pi == null) {
7824            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7825            return;
7826        }
7827
7828        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7829            grantUri.prefix = true;
7830        }
7831        final UriPermission perm = findOrCreateUriPermissionLocked(
7832                pi.packageName, targetPkg, targetUid, grantUri);
7833        perm.grantModes(modeFlags, owner);
7834    }
7835
7836    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7837            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7838        if (targetPkg == null) {
7839            throw new NullPointerException("targetPkg");
7840        }
7841        int targetUid;
7842        final IPackageManager pm = AppGlobals.getPackageManager();
7843        try {
7844            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7845        } catch (RemoteException ex) {
7846            return;
7847        }
7848
7849        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7850                targetUid);
7851        if (targetUid < 0) {
7852            return;
7853        }
7854
7855        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7856                owner);
7857    }
7858
7859    static class NeededUriGrants extends ArrayList<GrantUri> {
7860        final String targetPkg;
7861        final int targetUid;
7862        final int flags;
7863
7864        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7865            this.targetPkg = targetPkg;
7866            this.targetUid = targetUid;
7867            this.flags = flags;
7868        }
7869    }
7870
7871    /**
7872     * Like checkGrantUriPermissionLocked, but takes an Intent.
7873     */
7874    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7875            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7876        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7877                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7878                + " clip=" + (intent != null ? intent.getClipData() : null)
7879                + " from " + intent + "; flags=0x"
7880                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7881
7882        if (targetPkg == null) {
7883            throw new NullPointerException("targetPkg");
7884        }
7885
7886        if (intent == null) {
7887            return null;
7888        }
7889        Uri data = intent.getData();
7890        ClipData clip = intent.getClipData();
7891        if (data == null && clip == null) {
7892            return null;
7893        }
7894        // Default userId for uris in the intent (if they don't specify it themselves)
7895        int contentUserHint = intent.getContentUserHint();
7896        if (contentUserHint == UserHandle.USER_CURRENT) {
7897            contentUserHint = UserHandle.getUserId(callingUid);
7898        }
7899        final IPackageManager pm = AppGlobals.getPackageManager();
7900        int targetUid;
7901        if (needed != null) {
7902            targetUid = needed.targetUid;
7903        } else {
7904            try {
7905                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7906                        targetUserId);
7907            } catch (RemoteException ex) {
7908                return null;
7909            }
7910            if (targetUid < 0) {
7911                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7912                        "Can't grant URI permission no uid for: " + targetPkg
7913                        + " on user " + targetUserId);
7914                return null;
7915            }
7916        }
7917        if (data != null) {
7918            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7919            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7920                    targetUid);
7921            if (targetUid > 0) {
7922                if (needed == null) {
7923                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7924                }
7925                needed.add(grantUri);
7926            }
7927        }
7928        if (clip != null) {
7929            for (int i=0; i<clip.getItemCount(); i++) {
7930                Uri uri = clip.getItemAt(i).getUri();
7931                if (uri != null) {
7932                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7933                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7934                            targetUid);
7935                    if (targetUid > 0) {
7936                        if (needed == null) {
7937                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7938                        }
7939                        needed.add(grantUri);
7940                    }
7941                } else {
7942                    Intent clipIntent = clip.getItemAt(i).getIntent();
7943                    if (clipIntent != null) {
7944                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7945                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7946                        if (newNeeded != null) {
7947                            needed = newNeeded;
7948                        }
7949                    }
7950                }
7951            }
7952        }
7953
7954        return needed;
7955    }
7956
7957    /**
7958     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7959     */
7960    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7961            UriPermissionOwner owner) {
7962        if (needed != null) {
7963            for (int i=0; i<needed.size(); i++) {
7964                GrantUri grantUri = needed.get(i);
7965                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7966                        grantUri, needed.flags, owner);
7967            }
7968        }
7969    }
7970
7971    void grantUriPermissionFromIntentLocked(int callingUid,
7972            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7973        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7974                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7975        if (needed == null) {
7976            return;
7977        }
7978
7979        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7980    }
7981
7982    /**
7983     * @param uri This uri must NOT contain an embedded userId.
7984     * @param userId The userId in which the uri is to be resolved.
7985     */
7986    @Override
7987    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7988            final int modeFlags, int userId) {
7989        enforceNotIsolatedCaller("grantUriPermission");
7990        GrantUri grantUri = new GrantUri(userId, uri, false);
7991        synchronized(this) {
7992            final ProcessRecord r = getRecordForAppLocked(caller);
7993            if (r == null) {
7994                throw new SecurityException("Unable to find app for caller "
7995                        + caller
7996                        + " when granting permission to uri " + grantUri);
7997            }
7998            if (targetPkg == null) {
7999                throw new IllegalArgumentException("null target");
8000            }
8001            if (grantUri == null) {
8002                throw new IllegalArgumentException("null uri");
8003            }
8004
8005            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8006                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8007                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8008                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8009
8010            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8011                    UserHandle.getUserId(r.uid));
8012        }
8013    }
8014
8015    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8016        if (perm.modeFlags == 0) {
8017            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8018                    perm.targetUid);
8019            if (perms != null) {
8020                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8021                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8022
8023                perms.remove(perm.uri);
8024                if (perms.isEmpty()) {
8025                    mGrantedUriPermissions.remove(perm.targetUid);
8026                }
8027            }
8028        }
8029    }
8030
8031    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8032        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8033                "Revoking all granted permissions to " + grantUri);
8034
8035        final IPackageManager pm = AppGlobals.getPackageManager();
8036        final String authority = grantUri.uri.getAuthority();
8037        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8038        if (pi == null) {
8039            Slog.w(TAG, "No content provider found for permission revoke: "
8040                    + grantUri.toSafeString());
8041            return;
8042        }
8043
8044        // Does the caller have this permission on the URI?
8045        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8046            // If they don't have direct access to the URI, then revoke any
8047            // ownerless URI permissions that have been granted to them.
8048            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8049            if (perms != null) {
8050                boolean persistChanged = false;
8051                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8052                    final UriPermission perm = it.next();
8053                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8054                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8055                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8056                                "Revoking non-owned " + perm.targetUid
8057                                + " permission to " + perm.uri);
8058                        persistChanged |= perm.revokeModes(
8059                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8060                        if (perm.modeFlags == 0) {
8061                            it.remove();
8062                        }
8063                    }
8064                }
8065                if (perms.isEmpty()) {
8066                    mGrantedUriPermissions.remove(callingUid);
8067                }
8068                if (persistChanged) {
8069                    schedulePersistUriGrants();
8070                }
8071            }
8072            return;
8073        }
8074
8075        boolean persistChanged = false;
8076
8077        // Go through all of the permissions and remove any that match.
8078        int N = mGrantedUriPermissions.size();
8079        for (int i = 0; i < N; i++) {
8080            final int targetUid = mGrantedUriPermissions.keyAt(i);
8081            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8082
8083            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8084                final UriPermission perm = it.next();
8085                if (perm.uri.sourceUserId == grantUri.sourceUserId
8086                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8087                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8088                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8089                    persistChanged |= perm.revokeModes(
8090                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8091                    if (perm.modeFlags == 0) {
8092                        it.remove();
8093                    }
8094                }
8095            }
8096
8097            if (perms.isEmpty()) {
8098                mGrantedUriPermissions.remove(targetUid);
8099                N--;
8100                i--;
8101            }
8102        }
8103
8104        if (persistChanged) {
8105            schedulePersistUriGrants();
8106        }
8107    }
8108
8109    /**
8110     * @param uri This uri must NOT contain an embedded userId.
8111     * @param userId The userId in which the uri is to be resolved.
8112     */
8113    @Override
8114    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8115            int userId) {
8116        enforceNotIsolatedCaller("revokeUriPermission");
8117        synchronized(this) {
8118            final ProcessRecord r = getRecordForAppLocked(caller);
8119            if (r == null) {
8120                throw new SecurityException("Unable to find app for caller "
8121                        + caller
8122                        + " when revoking permission to uri " + uri);
8123            }
8124            if (uri == null) {
8125                Slog.w(TAG, "revokeUriPermission: null uri");
8126                return;
8127            }
8128
8129            if (!Intent.isAccessUriMode(modeFlags)) {
8130                return;
8131            }
8132
8133            final String authority = uri.getAuthority();
8134            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8135            if (pi == null) {
8136                Slog.w(TAG, "No content provider found for permission revoke: "
8137                        + uri.toSafeString());
8138                return;
8139            }
8140
8141            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8142        }
8143    }
8144
8145    /**
8146     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8147     * given package.
8148     *
8149     * @param packageName Package name to match, or {@code null} to apply to all
8150     *            packages.
8151     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8152     *            to all users.
8153     * @param persistable If persistable grants should be removed.
8154     */
8155    private void removeUriPermissionsForPackageLocked(
8156            String packageName, int userHandle, boolean persistable) {
8157        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8158            throw new IllegalArgumentException("Must narrow by either package or user");
8159        }
8160
8161        boolean persistChanged = false;
8162
8163        int N = mGrantedUriPermissions.size();
8164        for (int i = 0; i < N; i++) {
8165            final int targetUid = mGrantedUriPermissions.keyAt(i);
8166            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8167
8168            // Only inspect grants matching user
8169            if (userHandle == UserHandle.USER_ALL
8170                    || userHandle == UserHandle.getUserId(targetUid)) {
8171                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8172                    final UriPermission perm = it.next();
8173
8174                    // Only inspect grants matching package
8175                    if (packageName == null || perm.sourcePkg.equals(packageName)
8176                            || perm.targetPkg.equals(packageName)) {
8177                        persistChanged |= perm.revokeModes(persistable
8178                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8179
8180                        // Only remove when no modes remain; any persisted grants
8181                        // will keep this alive.
8182                        if (perm.modeFlags == 0) {
8183                            it.remove();
8184                        }
8185                    }
8186                }
8187
8188                if (perms.isEmpty()) {
8189                    mGrantedUriPermissions.remove(targetUid);
8190                    N--;
8191                    i--;
8192                }
8193            }
8194        }
8195
8196        if (persistChanged) {
8197            schedulePersistUriGrants();
8198        }
8199    }
8200
8201    @Override
8202    public IBinder newUriPermissionOwner(String name) {
8203        enforceNotIsolatedCaller("newUriPermissionOwner");
8204        synchronized(this) {
8205            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8206            return owner.getExternalTokenLocked();
8207        }
8208    }
8209
8210    @Override
8211    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8212        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8213        synchronized(this) {
8214            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8215            if (r == null) {
8216                throw new IllegalArgumentException("Activity does not exist; token="
8217                        + activityToken);
8218            }
8219            return r.getUriPermissionsLocked().getExternalTokenLocked();
8220        }
8221    }
8222    /**
8223     * @param uri This uri must NOT contain an embedded userId.
8224     * @param sourceUserId The userId in which the uri is to be resolved.
8225     * @param targetUserId The userId of the app that receives the grant.
8226     */
8227    @Override
8228    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8229            final int modeFlags, int sourceUserId, int targetUserId) {
8230        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8231                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8232                "grantUriPermissionFromOwner", null);
8233        synchronized(this) {
8234            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8235            if (owner == null) {
8236                throw new IllegalArgumentException("Unknown owner: " + token);
8237            }
8238            if (fromUid != Binder.getCallingUid()) {
8239                if (Binder.getCallingUid() != Process.myUid()) {
8240                    // Only system code can grant URI permissions on behalf
8241                    // of other users.
8242                    throw new SecurityException("nice try");
8243                }
8244            }
8245            if (targetPkg == null) {
8246                throw new IllegalArgumentException("null target");
8247            }
8248            if (uri == null) {
8249                throw new IllegalArgumentException("null uri");
8250            }
8251
8252            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8253                    modeFlags, owner, targetUserId);
8254        }
8255    }
8256
8257    /**
8258     * @param uri This uri must NOT contain an embedded userId.
8259     * @param userId The userId in which the uri is to be resolved.
8260     */
8261    @Override
8262    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8263        synchronized(this) {
8264            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8265            if (owner == null) {
8266                throw new IllegalArgumentException("Unknown owner: " + token);
8267            }
8268
8269            if (uri == null) {
8270                owner.removeUriPermissionsLocked(mode);
8271            } else {
8272                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8273            }
8274        }
8275    }
8276
8277    private void schedulePersistUriGrants() {
8278        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8279            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8280                    10 * DateUtils.SECOND_IN_MILLIS);
8281        }
8282    }
8283
8284    private void writeGrantedUriPermissions() {
8285        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8286
8287        // Snapshot permissions so we can persist without lock
8288        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8289        synchronized (this) {
8290            final int size = mGrantedUriPermissions.size();
8291            for (int i = 0; i < size; i++) {
8292                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8293                for (UriPermission perm : perms.values()) {
8294                    if (perm.persistedModeFlags != 0) {
8295                        persist.add(perm.snapshot());
8296                    }
8297                }
8298            }
8299        }
8300
8301        FileOutputStream fos = null;
8302        try {
8303            fos = mGrantFile.startWrite();
8304
8305            XmlSerializer out = new FastXmlSerializer();
8306            out.setOutput(fos, StandardCharsets.UTF_8.name());
8307            out.startDocument(null, true);
8308            out.startTag(null, TAG_URI_GRANTS);
8309            for (UriPermission.Snapshot perm : persist) {
8310                out.startTag(null, TAG_URI_GRANT);
8311                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8312                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8313                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8314                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8315                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8316                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8317                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8318                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8319                out.endTag(null, TAG_URI_GRANT);
8320            }
8321            out.endTag(null, TAG_URI_GRANTS);
8322            out.endDocument();
8323
8324            mGrantFile.finishWrite(fos);
8325        } catch (IOException e) {
8326            if (fos != null) {
8327                mGrantFile.failWrite(fos);
8328            }
8329        }
8330    }
8331
8332    private void readGrantedUriPermissionsLocked() {
8333        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8334
8335        final long now = System.currentTimeMillis();
8336
8337        FileInputStream fis = null;
8338        try {
8339            fis = mGrantFile.openRead();
8340            final XmlPullParser in = Xml.newPullParser();
8341            in.setInput(fis, StandardCharsets.UTF_8.name());
8342
8343            int type;
8344            while ((type = in.next()) != END_DOCUMENT) {
8345                final String tag = in.getName();
8346                if (type == START_TAG) {
8347                    if (TAG_URI_GRANT.equals(tag)) {
8348                        final int sourceUserId;
8349                        final int targetUserId;
8350                        final int userHandle = readIntAttribute(in,
8351                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8352                        if (userHandle != UserHandle.USER_NULL) {
8353                            // For backwards compatibility.
8354                            sourceUserId = userHandle;
8355                            targetUserId = userHandle;
8356                        } else {
8357                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8358                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8359                        }
8360                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8361                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8362                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8363                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8364                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8365                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8366
8367                        // Sanity check that provider still belongs to source package
8368                        final ProviderInfo pi = getProviderInfoLocked(
8369                                uri.getAuthority(), sourceUserId);
8370                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8371                            int targetUid = -1;
8372                            try {
8373                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8374                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8375                            } catch (RemoteException e) {
8376                            }
8377                            if (targetUid != -1) {
8378                                final UriPermission perm = findOrCreateUriPermissionLocked(
8379                                        sourcePkg, targetPkg, targetUid,
8380                                        new GrantUri(sourceUserId, uri, prefix));
8381                                perm.initPersistedModes(modeFlags, createdTime);
8382                            }
8383                        } else {
8384                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8385                                    + " but instead found " + pi);
8386                        }
8387                    }
8388                }
8389            }
8390        } catch (FileNotFoundException e) {
8391            // Missing grants is okay
8392        } catch (IOException e) {
8393            Slog.wtf(TAG, "Failed reading Uri grants", e);
8394        } catch (XmlPullParserException e) {
8395            Slog.wtf(TAG, "Failed reading Uri grants", e);
8396        } finally {
8397            IoUtils.closeQuietly(fis);
8398        }
8399    }
8400
8401    /**
8402     * @param uri This uri must NOT contain an embedded userId.
8403     * @param userId The userId in which the uri is to be resolved.
8404     */
8405    @Override
8406    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8407        enforceNotIsolatedCaller("takePersistableUriPermission");
8408
8409        Preconditions.checkFlagsArgument(modeFlags,
8410                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8411
8412        synchronized (this) {
8413            final int callingUid = Binder.getCallingUid();
8414            boolean persistChanged = false;
8415            GrantUri grantUri = new GrantUri(userId, uri, false);
8416
8417            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8418                    new GrantUri(userId, uri, false));
8419            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8420                    new GrantUri(userId, uri, true));
8421
8422            final boolean exactValid = (exactPerm != null)
8423                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8424            final boolean prefixValid = (prefixPerm != null)
8425                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8426
8427            if (!(exactValid || prefixValid)) {
8428                throw new SecurityException("No persistable permission grants found for UID "
8429                        + callingUid + " and Uri " + grantUri.toSafeString());
8430            }
8431
8432            if (exactValid) {
8433                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8434            }
8435            if (prefixValid) {
8436                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8437            }
8438
8439            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8440
8441            if (persistChanged) {
8442                schedulePersistUriGrants();
8443            }
8444        }
8445    }
8446
8447    /**
8448     * @param uri This uri must NOT contain an embedded userId.
8449     * @param userId The userId in which the uri is to be resolved.
8450     */
8451    @Override
8452    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8453        enforceNotIsolatedCaller("releasePersistableUriPermission");
8454
8455        Preconditions.checkFlagsArgument(modeFlags,
8456                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8457
8458        synchronized (this) {
8459            final int callingUid = Binder.getCallingUid();
8460            boolean persistChanged = false;
8461
8462            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8463                    new GrantUri(userId, uri, false));
8464            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8465                    new GrantUri(userId, uri, true));
8466            if (exactPerm == null && prefixPerm == null) {
8467                throw new SecurityException("No permission grants found for UID " + callingUid
8468                        + " and Uri " + uri.toSafeString());
8469            }
8470
8471            if (exactPerm != null) {
8472                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8473                removeUriPermissionIfNeededLocked(exactPerm);
8474            }
8475            if (prefixPerm != null) {
8476                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8477                removeUriPermissionIfNeededLocked(prefixPerm);
8478            }
8479
8480            if (persistChanged) {
8481                schedulePersistUriGrants();
8482            }
8483        }
8484    }
8485
8486    /**
8487     * Prune any older {@link UriPermission} for the given UID until outstanding
8488     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8489     *
8490     * @return if any mutations occured that require persisting.
8491     */
8492    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8493        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8494        if (perms == null) return false;
8495        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8496
8497        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8498        for (UriPermission perm : perms.values()) {
8499            if (perm.persistedModeFlags != 0) {
8500                persisted.add(perm);
8501            }
8502        }
8503
8504        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8505        if (trimCount <= 0) return false;
8506
8507        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8508        for (int i = 0; i < trimCount; i++) {
8509            final UriPermission perm = persisted.get(i);
8510
8511            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8512                    "Trimming grant created at " + perm.persistedCreateTime);
8513
8514            perm.releasePersistableModes(~0);
8515            removeUriPermissionIfNeededLocked(perm);
8516        }
8517
8518        return true;
8519    }
8520
8521    @Override
8522    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8523            String packageName, boolean incoming) {
8524        enforceNotIsolatedCaller("getPersistedUriPermissions");
8525        Preconditions.checkNotNull(packageName, "packageName");
8526
8527        final int callingUid = Binder.getCallingUid();
8528        final IPackageManager pm = AppGlobals.getPackageManager();
8529        try {
8530            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8531                    UserHandle.getUserId(callingUid));
8532            if (packageUid != callingUid) {
8533                throw new SecurityException(
8534                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8535            }
8536        } catch (RemoteException e) {
8537            throw new SecurityException("Failed to verify package name ownership");
8538        }
8539
8540        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8541        synchronized (this) {
8542            if (incoming) {
8543                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8544                        callingUid);
8545                if (perms == null) {
8546                    Slog.w(TAG, "No permission grants found for " + packageName);
8547                } else {
8548                    for (UriPermission perm : perms.values()) {
8549                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8550                            result.add(perm.buildPersistedPublicApiObject());
8551                        }
8552                    }
8553                }
8554            } else {
8555                final int size = mGrantedUriPermissions.size();
8556                for (int i = 0; i < size; i++) {
8557                    final ArrayMap<GrantUri, UriPermission> perms =
8558                            mGrantedUriPermissions.valueAt(i);
8559                    for (UriPermission perm : perms.values()) {
8560                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8561                            result.add(perm.buildPersistedPublicApiObject());
8562                        }
8563                    }
8564                }
8565            }
8566        }
8567        return new ParceledListSlice<android.content.UriPermission>(result);
8568    }
8569
8570    @Override
8571    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8572            String packageName, int userId) {
8573        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8574                "getGrantedUriPermissions");
8575
8576        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8577        synchronized (this) {
8578            final int size = mGrantedUriPermissions.size();
8579            for (int i = 0; i < size; i++) {
8580                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8581                for (UriPermission perm : perms.values()) {
8582                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8583                            && perm.persistedModeFlags != 0) {
8584                        result.add(perm.buildPersistedPublicApiObject());
8585                    }
8586                }
8587            }
8588        }
8589        return new ParceledListSlice<android.content.UriPermission>(result);
8590    }
8591
8592    @Override
8593    public void clearGrantedUriPermissions(String packageName, int userId) {
8594        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8595                "clearGrantedUriPermissions");
8596        removeUriPermissionsForPackageLocked(packageName, userId, true);
8597    }
8598
8599    @Override
8600    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8601        synchronized (this) {
8602            ProcessRecord app =
8603                who != null ? getRecordForAppLocked(who) : null;
8604            if (app == null) return;
8605
8606            Message msg = Message.obtain();
8607            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8608            msg.obj = app;
8609            msg.arg1 = waiting ? 1 : 0;
8610            mUiHandler.sendMessage(msg);
8611        }
8612    }
8613
8614    @Override
8615    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8616        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8617        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8618        outInfo.availMem = Process.getFreeMemory();
8619        outInfo.totalMem = Process.getTotalMemory();
8620        outInfo.threshold = homeAppMem;
8621        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8622        outInfo.hiddenAppThreshold = cachedAppMem;
8623        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8624                ProcessList.SERVICE_ADJ);
8625        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8626                ProcessList.VISIBLE_APP_ADJ);
8627        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8628                ProcessList.FOREGROUND_APP_ADJ);
8629    }
8630
8631    // =========================================================
8632    // TASK MANAGEMENT
8633    // =========================================================
8634
8635    @Override
8636    public List<IAppTask> getAppTasks(String callingPackage) {
8637        int callingUid = Binder.getCallingUid();
8638        long ident = Binder.clearCallingIdentity();
8639
8640        synchronized(this) {
8641            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8642            try {
8643                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8644
8645                final int N = mRecentTasks.size();
8646                for (int i = 0; i < N; i++) {
8647                    TaskRecord tr = mRecentTasks.get(i);
8648                    // Skip tasks that do not match the caller.  We don't need to verify
8649                    // callingPackage, because we are also limiting to callingUid and know
8650                    // that will limit to the correct security sandbox.
8651                    if (tr.effectiveUid != callingUid) {
8652                        continue;
8653                    }
8654                    Intent intent = tr.getBaseIntent();
8655                    if (intent == null ||
8656                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8657                        continue;
8658                    }
8659                    ActivityManager.RecentTaskInfo taskInfo =
8660                            createRecentTaskInfoFromTaskRecord(tr);
8661                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8662                    list.add(taskImpl);
8663                }
8664            } finally {
8665                Binder.restoreCallingIdentity(ident);
8666            }
8667            return list;
8668        }
8669    }
8670
8671    @Override
8672    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8673        final int callingUid = Binder.getCallingUid();
8674        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8675
8676        synchronized(this) {
8677            if (DEBUG_ALL) Slog.v(
8678                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8679
8680            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8681                    callingUid);
8682
8683            // TODO: Improve with MRU list from all ActivityStacks.
8684            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8685        }
8686
8687        return list;
8688    }
8689
8690    /**
8691     * Creates a new RecentTaskInfo from a TaskRecord.
8692     */
8693    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8694        // Update the task description to reflect any changes in the task stack
8695        tr.updateTaskDescription();
8696
8697        // Compose the recent task info
8698        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8699        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8700        rti.persistentId = tr.taskId;
8701        rti.baseIntent = new Intent(tr.getBaseIntent());
8702        rti.origActivity = tr.origActivity;
8703        rti.realActivity = tr.realActivity;
8704        rti.description = tr.lastDescription;
8705        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8706        rti.userId = tr.userId;
8707        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8708        rti.firstActiveTime = tr.firstActiveTime;
8709        rti.lastActiveTime = tr.lastActiveTime;
8710        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8711        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8712        rti.numActivities = 0;
8713        if (tr.mBounds != null) {
8714            rti.bounds = new Rect(tr.mBounds);
8715        }
8716        rti.isDockable = tr.canGoInDockedStack();
8717
8718        ActivityRecord base = null;
8719        ActivityRecord top = null;
8720        ActivityRecord tmp;
8721
8722        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8723            tmp = tr.mActivities.get(i);
8724            if (tmp.finishing) {
8725                continue;
8726            }
8727            base = tmp;
8728            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8729                top = base;
8730            }
8731            rti.numActivities++;
8732        }
8733
8734        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8735        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8736
8737        return rti;
8738    }
8739
8740    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8741        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8742                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8743        if (!allowed) {
8744            if (checkPermission(android.Manifest.permission.GET_TASKS,
8745                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8746                // Temporary compatibility: some existing apps on the system image may
8747                // still be requesting the old permission and not switched to the new
8748                // one; if so, we'll still allow them full access.  This means we need
8749                // to see if they are holding the old permission and are a system app.
8750                try {
8751                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8752                        allowed = true;
8753                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8754                                + " is using old GET_TASKS but privileged; allowing");
8755                    }
8756                } catch (RemoteException e) {
8757                }
8758            }
8759        }
8760        if (!allowed) {
8761            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8762                    + " does not hold REAL_GET_TASKS; limiting output");
8763        }
8764        return allowed;
8765    }
8766
8767    @Override
8768    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8769        final int callingUid = Binder.getCallingUid();
8770        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8771                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8772
8773        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8774        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8775        synchronized (this) {
8776            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8777                    callingUid);
8778            final boolean detailed = checkCallingPermission(
8779                    android.Manifest.permission.GET_DETAILED_TASKS)
8780                    == PackageManager.PERMISSION_GRANTED;
8781
8782            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8783                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8784                return Collections.emptyList();
8785            }
8786            mRecentTasks.loadUserRecentsLocked(userId);
8787
8788            final int recentsCount = mRecentTasks.size();
8789            ArrayList<ActivityManager.RecentTaskInfo> res =
8790                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8791
8792            final Set<Integer> includedUsers;
8793            if (includeProfiles) {
8794                includedUsers = mUserController.getProfileIds(userId);
8795            } else {
8796                includedUsers = new HashSet<>();
8797            }
8798            includedUsers.add(Integer.valueOf(userId));
8799
8800            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8801                TaskRecord tr = mRecentTasks.get(i);
8802                // Only add calling user or related users recent tasks
8803                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8804                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8805                    continue;
8806                }
8807
8808                if (tr.realActivitySuspended) {
8809                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8810                    continue;
8811                }
8812
8813                // Return the entry if desired by the caller.  We always return
8814                // the first entry, because callers always expect this to be the
8815                // foreground app.  We may filter others if the caller has
8816                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8817                // we should exclude the entry.
8818
8819                if (i == 0
8820                        || withExcluded
8821                        || (tr.intent == null)
8822                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8823                                == 0)) {
8824                    if (!allowed) {
8825                        // If the caller doesn't have the GET_TASKS permission, then only
8826                        // allow them to see a small subset of tasks -- their own and home.
8827                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8828                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8829                            continue;
8830                        }
8831                    }
8832                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8833                        if (tr.stack != null && tr.stack.isHomeStack()) {
8834                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8835                                    "Skipping, home stack task: " + tr);
8836                            continue;
8837                        }
8838                    }
8839                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8840                        if (tr.stack != null && tr.stack.isDockedStack()) {
8841                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8842                                    "Skipping, docked stack task: " + tr);
8843                            continue;
8844                        }
8845                    }
8846                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8847                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8848                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8849                                    "Skipping, pinned stack task: " + tr);
8850                            continue;
8851                        }
8852                    }
8853                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8854                        // Don't include auto remove tasks that are finished or finishing.
8855                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8856                                "Skipping, auto-remove without activity: " + tr);
8857                        continue;
8858                    }
8859                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8860                            && !tr.isAvailable) {
8861                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8862                                "Skipping, unavail real act: " + tr);
8863                        continue;
8864                    }
8865
8866                    if (!tr.mUserSetupComplete) {
8867                        // Don't include task launched while user is not done setting-up.
8868                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8869                                "Skipping, user setup not complete: " + tr);
8870                        continue;
8871                    }
8872
8873                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8874                    if (!detailed) {
8875                        rti.baseIntent.replaceExtras((Bundle)null);
8876                    }
8877
8878                    res.add(rti);
8879                    maxNum--;
8880                }
8881            }
8882            return res;
8883        }
8884    }
8885
8886    @Override
8887    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8888        synchronized (this) {
8889            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8890                    "getTaskThumbnail()");
8891            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8892                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8893            if (tr != null) {
8894                return tr.getTaskThumbnailLocked();
8895            }
8896        }
8897        return null;
8898    }
8899
8900    @Override
8901    public int addAppTask(IBinder activityToken, Intent intent,
8902            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8903        final int callingUid = Binder.getCallingUid();
8904        final long callingIdent = Binder.clearCallingIdentity();
8905
8906        try {
8907            synchronized (this) {
8908                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8909                if (r == null) {
8910                    throw new IllegalArgumentException("Activity does not exist; token="
8911                            + activityToken);
8912                }
8913                ComponentName comp = intent.getComponent();
8914                if (comp == null) {
8915                    throw new IllegalArgumentException("Intent " + intent
8916                            + " must specify explicit component");
8917                }
8918                if (thumbnail.getWidth() != mThumbnailWidth
8919                        || thumbnail.getHeight() != mThumbnailHeight) {
8920                    throw new IllegalArgumentException("Bad thumbnail size: got "
8921                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8922                            + mThumbnailWidth + "x" + mThumbnailHeight);
8923                }
8924                if (intent.getSelector() != null) {
8925                    intent.setSelector(null);
8926                }
8927                if (intent.getSourceBounds() != null) {
8928                    intent.setSourceBounds(null);
8929                }
8930                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8931                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8932                        // The caller has added this as an auto-remove task...  that makes no
8933                        // sense, so turn off auto-remove.
8934                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8935                    }
8936                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8937                    // Must be a new task.
8938                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8939                }
8940                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8941                    mLastAddedTaskActivity = null;
8942                }
8943                ActivityInfo ainfo = mLastAddedTaskActivity;
8944                if (ainfo == null) {
8945                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8946                            comp, 0, UserHandle.getUserId(callingUid));
8947                    if (ainfo.applicationInfo.uid != callingUid) {
8948                        throw new SecurityException(
8949                                "Can't add task for another application: target uid="
8950                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8951                    }
8952                }
8953
8954                // Use the full screen as the context for the task thumbnail
8955                final Point displaySize = new Point();
8956                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8957                r.task.stack.getDisplaySize(displaySize);
8958                thumbnailInfo.taskWidth = displaySize.x;
8959                thumbnailInfo.taskHeight = displaySize.y;
8960                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8961
8962                TaskRecord task = new TaskRecord(this,
8963                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
8964                        ainfo, intent, description, thumbnailInfo);
8965
8966                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8967                if (trimIdx >= 0) {
8968                    // If this would have caused a trim, then we'll abort because that
8969                    // means it would be added at the end of the list but then just removed.
8970                    return INVALID_TASK_ID;
8971                }
8972
8973                final int N = mRecentTasks.size();
8974                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8975                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8976                    tr.removedFromRecents();
8977                }
8978
8979                task.inRecents = true;
8980                mRecentTasks.add(task);
8981                r.task.stack.addTask(task, false, "addAppTask");
8982
8983                task.setLastThumbnailLocked(thumbnail);
8984                task.freeLastThumbnail();
8985
8986                return task.taskId;
8987            }
8988        } finally {
8989            Binder.restoreCallingIdentity(callingIdent);
8990        }
8991    }
8992
8993    @Override
8994    public Point getAppTaskThumbnailSize() {
8995        synchronized (this) {
8996            return new Point(mThumbnailWidth,  mThumbnailHeight);
8997        }
8998    }
8999
9000    @Override
9001    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9002        synchronized (this) {
9003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9004            if (r != null) {
9005                r.setTaskDescription(td);
9006                r.task.updateTaskDescription();
9007            }
9008        }
9009    }
9010
9011    @Override
9012    public void setTaskResizeable(int taskId, int resizeableMode) {
9013        synchronized (this) {
9014            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9015                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9016            if (task == null) {
9017                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9018                return;
9019            }
9020            if (task.mResizeMode != resizeableMode) {
9021                task.mResizeMode = resizeableMode;
9022                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9023                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9024                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9025            }
9026        }
9027    }
9028
9029    @Override
9030    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9031        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9032        long ident = Binder.clearCallingIdentity();
9033        try {
9034            synchronized (this) {
9035                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9036                if (task == null) {
9037                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9038                    return;
9039                }
9040                int stackId = task.stack.mStackId;
9041                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9042                // in crop windows resize mode or if the task size is affected by the docked stack
9043                // changing size. No need to update configuration.
9044                if (bounds != null && task.inCropWindowsResizeMode()
9045                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9046                    mWindowManager.scrollTask(task.taskId, bounds);
9047                    return;
9048                }
9049
9050                // Place the task in the right stack if it isn't there already based on
9051                // the requested bounds.
9052                // The stack transition logic is:
9053                // - a null bounds on a freeform task moves that task to fullscreen
9054                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9055                //   that task to freeform
9056                // - otherwise the task is not moved
9057                if (!StackId.isTaskResizeAllowed(stackId)) {
9058                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9059                }
9060                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9061                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9062                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9063                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9064                }
9065                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9066                if (stackId != task.stack.mStackId) {
9067                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9068                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9069                    preserveWindow = false;
9070                }
9071
9072                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9073            }
9074        } finally {
9075            Binder.restoreCallingIdentity(ident);
9076        }
9077    }
9078
9079    @Override
9080    public Rect getTaskBounds(int taskId) {
9081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9082        long ident = Binder.clearCallingIdentity();
9083        Rect rect = new Rect();
9084        try {
9085            synchronized (this) {
9086                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9087                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9088                if (task == null) {
9089                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9090                    return rect;
9091                }
9092                if (task.stack != null) {
9093                    // Return the bounds from window manager since it will be adjusted for various
9094                    // things like the presense of a docked stack for tasks that aren't resizeable.
9095                    mWindowManager.getTaskBounds(task.taskId, rect);
9096                } else {
9097                    // Task isn't in window manager yet since it isn't associated with a stack.
9098                    // Return the persist value from activity manager
9099                    if (task.mBounds != null) {
9100                        rect.set(task.mBounds);
9101                    } else if (task.mLastNonFullscreenBounds != null) {
9102                        rect.set(task.mLastNonFullscreenBounds);
9103                    }
9104                }
9105            }
9106        } finally {
9107            Binder.restoreCallingIdentity(ident);
9108        }
9109        return rect;
9110    }
9111
9112    @Override
9113    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9114        if (userId != UserHandle.getCallingUserId()) {
9115            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9116                    "getTaskDescriptionIcon");
9117        }
9118        final File passedIconFile = new File(filePath);
9119        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9120                passedIconFile.getName());
9121        if (!legitIconFile.getPath().equals(filePath)
9122                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9123            throw new IllegalArgumentException("Bad file path: " + filePath
9124                    + " passed for userId " + userId);
9125        }
9126        return mRecentTasks.getTaskDescriptionIcon(filePath);
9127    }
9128
9129    @Override
9130    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9131            throws RemoteException {
9132        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9133                opts.getCustomInPlaceResId() == 0) {
9134            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9135                    "with valid animation");
9136        }
9137        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9138        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9139                opts.getCustomInPlaceResId());
9140        mWindowManager.executeAppTransition();
9141    }
9142
9143    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9144            boolean removeFromRecents) {
9145        if (removeFromRecents) {
9146            mRecentTasks.remove(tr);
9147            tr.removedFromRecents();
9148        }
9149        ComponentName component = tr.getBaseIntent().getComponent();
9150        if (component == null) {
9151            Slog.w(TAG, "No component for base intent of task: " + tr);
9152            return;
9153        }
9154
9155        // Find any running services associated with this app and stop if needed.
9156        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9157
9158        if (!killProcess) {
9159            return;
9160        }
9161
9162        // Determine if the process(es) for this task should be killed.
9163        final String pkg = component.getPackageName();
9164        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9165        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9166        for (int i = 0; i < pmap.size(); i++) {
9167
9168            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9169            for (int j = 0; j < uids.size(); j++) {
9170                ProcessRecord proc = uids.valueAt(j);
9171                if (proc.userId != tr.userId) {
9172                    // Don't kill process for a different user.
9173                    continue;
9174                }
9175                if (proc == mHomeProcess) {
9176                    // Don't kill the home process along with tasks from the same package.
9177                    continue;
9178                }
9179                if (!proc.pkgList.containsKey(pkg)) {
9180                    // Don't kill process that is not associated with this task.
9181                    continue;
9182                }
9183
9184                for (int k = 0; k < proc.activities.size(); k++) {
9185                    TaskRecord otherTask = proc.activities.get(k).task;
9186                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9187                        // Don't kill process(es) that has an activity in a different task that is
9188                        // also in recents.
9189                        return;
9190                    }
9191                }
9192
9193                if (proc.foregroundServices) {
9194                    // Don't kill process(es) with foreground service.
9195                    return;
9196                }
9197
9198                // Add process to kill list.
9199                procsToKill.add(proc);
9200            }
9201        }
9202
9203        // Kill the running processes.
9204        for (int i = 0; i < procsToKill.size(); i++) {
9205            ProcessRecord pr = procsToKill.get(i);
9206            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9207                    && pr.curReceiver == null) {
9208                pr.kill("remove task", true);
9209            } else {
9210                // We delay killing processes that are not in the background or running a receiver.
9211                pr.waitingToKill = "remove task";
9212            }
9213        }
9214    }
9215
9216    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9217        // Remove all tasks with activities in the specified package from the list of recent tasks
9218        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9219            TaskRecord tr = mRecentTasks.get(i);
9220            if (tr.userId != userId) continue;
9221
9222            ComponentName cn = tr.intent.getComponent();
9223            if (cn != null && cn.getPackageName().equals(packageName)) {
9224                // If the package name matches, remove the task.
9225                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9226            }
9227        }
9228    }
9229
9230    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9231            int userId) {
9232
9233        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9234            TaskRecord tr = mRecentTasks.get(i);
9235            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9236                continue;
9237            }
9238
9239            ComponentName cn = tr.intent.getComponent();
9240            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9241                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9242            if (sameComponent) {
9243                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9244            }
9245        }
9246    }
9247
9248    /**
9249     * Removes the task with the specified task id.
9250     *
9251     * @param taskId Identifier of the task to be removed.
9252     * @param killProcess Kill any process associated with the task if possible.
9253     * @param removeFromRecents Whether to also remove the task from recents.
9254     * @return Returns true if the given task was found and removed.
9255     */
9256    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9257            boolean removeFromRecents) {
9258        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9259                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9260        if (tr != null) {
9261            tr.removeTaskActivitiesLocked();
9262            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9263            if (tr.isPersistable) {
9264                notifyTaskPersisterLocked(null, true);
9265            }
9266            return true;
9267        }
9268        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9269        return false;
9270    }
9271
9272    @Override
9273    public void removeStack(int stackId) {
9274        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9275        if (stackId == HOME_STACK_ID) {
9276            throw new IllegalArgumentException("Removing home stack is not allowed.");
9277        }
9278
9279        synchronized (this) {
9280            final long ident = Binder.clearCallingIdentity();
9281            try {
9282                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9283                if (stack == null) {
9284                    return;
9285                }
9286                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9287                for (int i = tasks.size() - 1; i >= 0; i--) {
9288                    removeTaskByIdLocked(
9289                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9290                }
9291            } finally {
9292                Binder.restoreCallingIdentity(ident);
9293            }
9294        }
9295    }
9296
9297    @Override
9298    public boolean removeTask(int taskId) {
9299        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9300        synchronized (this) {
9301            final long ident = Binder.clearCallingIdentity();
9302            try {
9303                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9304            } finally {
9305                Binder.restoreCallingIdentity(ident);
9306            }
9307        }
9308    }
9309
9310    /**
9311     * TODO: Add mController hook
9312     */
9313    @Override
9314    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9315        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9316
9317        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9318        synchronized(this) {
9319            moveTaskToFrontLocked(taskId, flags, bOptions);
9320        }
9321    }
9322
9323    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9324        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9325
9326        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9327                Binder.getCallingUid(), -1, -1, "Task to front")) {
9328            ActivityOptions.abort(options);
9329            return;
9330        }
9331        final long origId = Binder.clearCallingIdentity();
9332        try {
9333            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9334            if (task == null) {
9335                Slog.d(TAG, "Could not find task for id: "+ taskId);
9336                return;
9337            }
9338            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9339                mStackSupervisor.showLockTaskToast();
9340                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9341                return;
9342            }
9343            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9344            if (prev != null && prev.isRecentsActivity()) {
9345                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9346            }
9347            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9348        } finally {
9349            Binder.restoreCallingIdentity(origId);
9350        }
9351        ActivityOptions.abort(options);
9352    }
9353
9354    /**
9355     * Moves an activity, and all of the other activities within the same task, to the bottom
9356     * of the history stack.  The activity's order within the task is unchanged.
9357     *
9358     * @param token A reference to the activity we wish to move
9359     * @param nonRoot If false then this only works if the activity is the root
9360     *                of a task; if true it will work for any activity in a task.
9361     * @return Returns true if the move completed, false if not.
9362     */
9363    @Override
9364    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9365        enforceNotIsolatedCaller("moveActivityTaskToBack");
9366        synchronized(this) {
9367            final long origId = Binder.clearCallingIdentity();
9368            try {
9369                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9370                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9371                if (task != null) {
9372                    if (mStackSupervisor.isLockedTask(task)) {
9373                        mStackSupervisor.showLockTaskToast();
9374                        return false;
9375                    }
9376                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9377                }
9378            } finally {
9379                Binder.restoreCallingIdentity(origId);
9380            }
9381        }
9382        return false;
9383    }
9384
9385    @Override
9386    public void moveTaskBackwards(int task) {
9387        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9388                "moveTaskBackwards()");
9389
9390        synchronized(this) {
9391            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9392                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9393                return;
9394            }
9395            final long origId = Binder.clearCallingIdentity();
9396            moveTaskBackwardsLocked(task);
9397            Binder.restoreCallingIdentity(origId);
9398        }
9399    }
9400
9401    private final void moveTaskBackwardsLocked(int task) {
9402        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9403    }
9404
9405    @Override
9406    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9407            IActivityContainerCallback callback) throws RemoteException {
9408        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9409        synchronized (this) {
9410            if (parentActivityToken == null) {
9411                throw new IllegalArgumentException("parent token must not be null");
9412            }
9413            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9414            if (r == null) {
9415                return null;
9416            }
9417            if (callback == null) {
9418                throw new IllegalArgumentException("callback must not be null");
9419            }
9420            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9421        }
9422    }
9423
9424    @Override
9425    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9426        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9427        synchronized (this) {
9428            mStackSupervisor.deleteActivityContainer(container);
9429        }
9430    }
9431
9432    @Override
9433    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9434        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9435        synchronized (this) {
9436            final int stackId = mStackSupervisor.getNextStackId();
9437            final ActivityStack stack =
9438                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9439            if (stack == null) {
9440                return null;
9441            }
9442            return stack.mActivityContainer;
9443        }
9444    }
9445
9446    @Override
9447    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9448        synchronized (this) {
9449            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9450            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9451                return stack.mActivityContainer.getDisplayId();
9452            }
9453            return Display.DEFAULT_DISPLAY;
9454        }
9455    }
9456
9457    @Override
9458    public int getActivityStackId(IBinder token) throws RemoteException {
9459        synchronized (this) {
9460            ActivityStack stack = ActivityRecord.getStackLocked(token);
9461            if (stack == null) {
9462                return INVALID_STACK_ID;
9463            }
9464            return stack.mStackId;
9465        }
9466    }
9467
9468    @Override
9469    public void exitFreeformMode(IBinder token) throws RemoteException {
9470        synchronized (this) {
9471            long ident = Binder.clearCallingIdentity();
9472            try {
9473                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9474                if (r == null) {
9475                    throw new IllegalArgumentException(
9476                            "exitFreeformMode: No activity record matching token=" + token);
9477                }
9478                final ActivityStack stack = r.getStackLocked(token);
9479                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9480                    throw new IllegalStateException(
9481                            "exitFreeformMode: You can only go fullscreen from freeform.");
9482                }
9483                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9484                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9485                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9486            } finally {
9487                Binder.restoreCallingIdentity(ident);
9488            }
9489        }
9490    }
9491
9492    @Override
9493    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9494        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9495        if (stackId == HOME_STACK_ID) {
9496            throw new IllegalArgumentException(
9497                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9498        }
9499        synchronized (this) {
9500            long ident = Binder.clearCallingIdentity();
9501            try {
9502                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9503                        + " to stackId=" + stackId + " toTop=" + toTop);
9504                if (stackId == DOCKED_STACK_ID) {
9505                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9506                            null /* initialBounds */);
9507                }
9508                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9509                        "moveTaskToStack", ANIMATE);
9510            } finally {
9511                Binder.restoreCallingIdentity(ident);
9512            }
9513        }
9514    }
9515
9516    /**
9517     * Moves the input task to the docked stack.
9518     *
9519     * @param taskId Id of task to move.
9520     * @param createMode The mode the docked stack should be created in if it doesn't exist
9521     *                   already. See
9522     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9523     *                   and
9524     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9525     * @param toTop If the task and stack should be moved to the top.
9526     * @param animate Whether we should play an animation for the moving the task
9527     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9528     *                      docked stack. Pass {@code null} to use default bounds.
9529     */
9530    @Override
9531    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9532            Rect initialBounds) {
9533        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9534        synchronized (this) {
9535            long ident = Binder.clearCallingIdentity();
9536            try {
9537                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9538                        + " to createMode=" + createMode + " toTop=" + toTop);
9539                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9540                return mStackSupervisor.moveTaskToStackLocked(
9541                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9542                        "moveTaskToDockedStack", animate);
9543            } finally {
9544                Binder.restoreCallingIdentity(ident);
9545            }
9546        }
9547    }
9548
9549    /**
9550     * Moves the top activity in the input stackId to the pinned stack.
9551     *
9552     * @param stackId Id of stack to move the top activity to pinned stack.
9553     * @param bounds Bounds to use for pinned stack.
9554     *
9555     * @return True if the top activity of the input stack was successfully moved to the pinned
9556     *          stack.
9557     */
9558    @Override
9559    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9560        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9561        synchronized (this) {
9562            if (!mSupportsPictureInPicture) {
9563                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9564                        + "Device doesn't support picture-in-pciture mode");
9565            }
9566
9567            long ident = Binder.clearCallingIdentity();
9568            try {
9569                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9570            } finally {
9571                Binder.restoreCallingIdentity(ident);
9572            }
9573        }
9574    }
9575
9576    @Override
9577    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9578            boolean preserveWindows, boolean animate) {
9579        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9580        long ident = Binder.clearCallingIdentity();
9581        try {
9582            synchronized (this) {
9583                if (animate) {
9584                    if (stackId == PINNED_STACK_ID) {
9585                        mWindowManager.animateResizePinnedStack(bounds);
9586                    } else {
9587                        throw new IllegalArgumentException("Stack: " + stackId
9588                                + " doesn't support animated resize.");
9589                    }
9590                } else {
9591                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9592                            null /* tempTaskInsetBounds */, preserveWindows,
9593                            allowResizeInDockedMode);
9594                }
9595            }
9596        } finally {
9597            Binder.restoreCallingIdentity(ident);
9598        }
9599    }
9600
9601    @Override
9602    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9603            Rect tempDockedTaskInsetBounds,
9604            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9606                "resizeDockedStack()");
9607        long ident = Binder.clearCallingIdentity();
9608        try {
9609            synchronized (this) {
9610                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9611                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9612                        PRESERVE_WINDOWS);
9613            }
9614        } finally {
9615            Binder.restoreCallingIdentity(ident);
9616        }
9617    }
9618
9619    @Override
9620    public void positionTaskInStack(int taskId, int stackId, int position) {
9621        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9622        if (stackId == HOME_STACK_ID) {
9623            throw new IllegalArgumentException(
9624                    "positionTaskInStack: Attempt to change the position of task "
9625                    + taskId + " in/to home stack");
9626        }
9627        synchronized (this) {
9628            long ident = Binder.clearCallingIdentity();
9629            try {
9630                if (DEBUG_STACK) Slog.d(TAG_STACK,
9631                        "positionTaskInStack: positioning task=" + taskId
9632                        + " in stackId=" + stackId + " at position=" + position);
9633                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9634            } finally {
9635                Binder.restoreCallingIdentity(ident);
9636            }
9637        }
9638    }
9639
9640    @Override
9641    public List<StackInfo> getAllStackInfos() {
9642        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9643        long ident = Binder.clearCallingIdentity();
9644        try {
9645            synchronized (this) {
9646                return mStackSupervisor.getAllStackInfosLocked();
9647            }
9648        } finally {
9649            Binder.restoreCallingIdentity(ident);
9650        }
9651    }
9652
9653    @Override
9654    public StackInfo getStackInfo(int stackId) {
9655        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9656        long ident = Binder.clearCallingIdentity();
9657        try {
9658            synchronized (this) {
9659                return mStackSupervisor.getStackInfoLocked(stackId);
9660            }
9661        } finally {
9662            Binder.restoreCallingIdentity(ident);
9663        }
9664    }
9665
9666    @Override
9667    public boolean isInHomeStack(int taskId) {
9668        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9669        long ident = Binder.clearCallingIdentity();
9670        try {
9671            synchronized (this) {
9672                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9673                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9674                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9675            }
9676        } finally {
9677            Binder.restoreCallingIdentity(ident);
9678        }
9679    }
9680
9681    @Override
9682    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9683        synchronized(this) {
9684            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9685        }
9686    }
9687
9688    @Override
9689    public void updateDeviceOwner(String packageName) {
9690        final int callingUid = Binder.getCallingUid();
9691        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9692            throw new SecurityException("updateDeviceOwner called from non-system process");
9693        }
9694        synchronized (this) {
9695            mDeviceOwnerName = packageName;
9696        }
9697    }
9698
9699    @Override
9700    public void updateLockTaskPackages(int userId, String[] packages) {
9701        final int callingUid = Binder.getCallingUid();
9702        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9703            throw new SecurityException("updateLockTaskPackage called from non-system process");
9704        }
9705        synchronized (this) {
9706            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9707                    Arrays.toString(packages));
9708            mLockTaskPackages.put(userId, packages);
9709            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9710        }
9711    }
9712
9713
9714    void startLockTaskModeLocked(TaskRecord task) {
9715        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9716        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9717            return;
9718        }
9719
9720        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9721        // is initiated by system after the pinning request was shown and locked mode is initiated
9722        // by an authorized app directly
9723        final int callingUid = Binder.getCallingUid();
9724        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9725        long ident = Binder.clearCallingIdentity();
9726        try {
9727            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9728            if (!isSystemInitiated) {
9729                task.mLockTaskUid = callingUid;
9730                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9731                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9732                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9733                    StatusBarManagerInternal statusBarManager =
9734                            LocalServices.getService(StatusBarManagerInternal.class);
9735                    if (statusBarManager != null) {
9736                        statusBarManager.showScreenPinningRequest();
9737                    }
9738                    return;
9739                }
9740
9741                if (stack == null || task != stack.topTask()) {
9742                    throw new IllegalArgumentException("Invalid task, not in foreground");
9743                }
9744            }
9745            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9746                    "Locking fully");
9747            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9748                    ActivityManager.LOCK_TASK_MODE_PINNED :
9749                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9750                    "startLockTask", true);
9751        } finally {
9752            Binder.restoreCallingIdentity(ident);
9753        }
9754    }
9755
9756    @Override
9757    public void startLockTaskMode(int taskId) {
9758        synchronized (this) {
9759            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9760            if (task != null) {
9761                startLockTaskModeLocked(task);
9762            }
9763        }
9764    }
9765
9766    @Override
9767    public void startLockTaskMode(IBinder token) {
9768        synchronized (this) {
9769            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9770            if (r == null) {
9771                return;
9772            }
9773            final TaskRecord task = r.task;
9774            if (task != null) {
9775                startLockTaskModeLocked(task);
9776            }
9777        }
9778    }
9779
9780    @Override
9781    public void startLockTaskModeOnCurrent() throws RemoteException {
9782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9783        long ident = Binder.clearCallingIdentity();
9784        try {
9785            synchronized (this) {
9786                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9787                if (r != null) {
9788                    startLockTaskModeLocked(r.task);
9789                }
9790            }
9791        } finally {
9792            Binder.restoreCallingIdentity(ident);
9793        }
9794    }
9795
9796    @Override
9797    public void stopLockTaskMode() {
9798        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9799        if (lockTask == null) {
9800            // Our work here is done.
9801            return;
9802        }
9803
9804        final int callingUid = Binder.getCallingUid();
9805        final int lockTaskUid = lockTask.mLockTaskUid;
9806        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9807        // It is possible lockTaskMode was started by the system process because
9808        // android:lockTaskMode is set to a locking value in the application manifest instead of
9809        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9810        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9811        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9812                callingUid != lockTaskUid
9813                && (lockTaskUid != 0
9814                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9815            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9816                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9817        }
9818
9819        long ident = Binder.clearCallingIdentity();
9820        try {
9821            Log.d(TAG, "stopLockTaskMode");
9822            // Stop lock task
9823            synchronized (this) {
9824                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9825                        "stopLockTask", true);
9826            }
9827        } finally {
9828            Binder.restoreCallingIdentity(ident);
9829        }
9830    }
9831
9832    @Override
9833    public void stopLockTaskModeOnCurrent() throws RemoteException {
9834        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9835        long ident = Binder.clearCallingIdentity();
9836        try {
9837            stopLockTaskMode();
9838        } finally {
9839            Binder.restoreCallingIdentity(ident);
9840        }
9841    }
9842
9843    @Override
9844    public boolean isInLockTaskMode() {
9845        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9846    }
9847
9848    @Override
9849    public int getLockTaskModeState() {
9850        synchronized (this) {
9851            return mStackSupervisor.getLockTaskModeState();
9852        }
9853    }
9854
9855    @Override
9856    public void showLockTaskEscapeMessage(IBinder token) {
9857        synchronized (this) {
9858            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9859            if (r == null) {
9860                return;
9861            }
9862            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9863        }
9864    }
9865
9866    // =========================================================
9867    // CONTENT PROVIDERS
9868    // =========================================================
9869
9870    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9871        List<ProviderInfo> providers = null;
9872        try {
9873            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9874                    .queryContentProviders(app.processName, app.uid,
9875                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9876                                    | MATCH_DEBUG_TRIAGED_MISSING);
9877            providers = slice != null ? slice.getList() : null;
9878        } catch (RemoteException ex) {
9879        }
9880        if (DEBUG_MU) Slog.v(TAG_MU,
9881                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9882        int userId = app.userId;
9883        if (providers != null) {
9884            int N = providers.size();
9885            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9886            for (int i=0; i<N; i++) {
9887                ProviderInfo cpi =
9888                    (ProviderInfo)providers.get(i);
9889                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9890                        cpi.name, cpi.flags);
9891                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9892                    // This is a singleton provider, but a user besides the
9893                    // default user is asking to initialize a process it runs
9894                    // in...  well, no, it doesn't actually run in this process,
9895                    // it runs in the process of the default user.  Get rid of it.
9896                    providers.remove(i);
9897                    N--;
9898                    i--;
9899                    continue;
9900                }
9901
9902                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9903                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9904                if (cpr == null) {
9905                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9906                    mProviderMap.putProviderByClass(comp, cpr);
9907                }
9908                if (DEBUG_MU) Slog.v(TAG_MU,
9909                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9910                app.pubProviders.put(cpi.name, cpr);
9911                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9912                    // Don't add this if it is a platform component that is marked
9913                    // to run in multiple processes, because this is actually
9914                    // part of the framework so doesn't make sense to track as a
9915                    // separate apk in the process.
9916                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9917                            mProcessStats);
9918                }
9919                notifyPackageUse(cpi.applicationInfo.packageName);
9920            }
9921        }
9922        return providers;
9923    }
9924
9925    /**
9926     * Check if {@link ProcessRecord} has a possible chance at accessing the
9927     * given {@link ProviderInfo}. Final permission checking is always done
9928     * in {@link ContentProvider}.
9929     */
9930    private final String checkContentProviderPermissionLocked(
9931            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9932        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9933        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9934        boolean checkedGrants = false;
9935        if (checkUser) {
9936            // Looking for cross-user grants before enforcing the typical cross-users permissions
9937            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9938            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9939                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9940                    return null;
9941                }
9942                checkedGrants = true;
9943            }
9944            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9945                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9946            if (userId != tmpTargetUserId) {
9947                // When we actually went to determine the final targer user ID, this ended
9948                // up different than our initial check for the authority.  This is because
9949                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9950                // SELF.  So we need to re-check the grants again.
9951                checkedGrants = false;
9952            }
9953        }
9954        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9955                cpi.applicationInfo.uid, cpi.exported)
9956                == PackageManager.PERMISSION_GRANTED) {
9957            return null;
9958        }
9959        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9960                cpi.applicationInfo.uid, cpi.exported)
9961                == PackageManager.PERMISSION_GRANTED) {
9962            return null;
9963        }
9964
9965        PathPermission[] pps = cpi.pathPermissions;
9966        if (pps != null) {
9967            int i = pps.length;
9968            while (i > 0) {
9969                i--;
9970                PathPermission pp = pps[i];
9971                String pprperm = pp.getReadPermission();
9972                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9973                        cpi.applicationInfo.uid, cpi.exported)
9974                        == PackageManager.PERMISSION_GRANTED) {
9975                    return null;
9976                }
9977                String ppwperm = pp.getWritePermission();
9978                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9979                        cpi.applicationInfo.uid, cpi.exported)
9980                        == PackageManager.PERMISSION_GRANTED) {
9981                    return null;
9982                }
9983            }
9984        }
9985        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9986            return null;
9987        }
9988
9989        String msg;
9990        if (!cpi.exported) {
9991            msg = "Permission Denial: opening provider " + cpi.name
9992                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9993                    + ", uid=" + callingUid + ") that is not exported from uid "
9994                    + cpi.applicationInfo.uid;
9995        } else {
9996            msg = "Permission Denial: opening provider " + cpi.name
9997                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9998                    + ", uid=" + callingUid + ") requires "
9999                    + cpi.readPermission + " or " + cpi.writePermission;
10000        }
10001        Slog.w(TAG, msg);
10002        return msg;
10003    }
10004
10005    /**
10006     * Returns if the ContentProvider has granted a uri to callingUid
10007     */
10008    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10009        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10010        if (perms != null) {
10011            for (int i=perms.size()-1; i>=0; i--) {
10012                GrantUri grantUri = perms.keyAt(i);
10013                if (grantUri.sourceUserId == userId || !checkUser) {
10014                    if (matchesProvider(grantUri.uri, cpi)) {
10015                        return true;
10016                    }
10017                }
10018            }
10019        }
10020        return false;
10021    }
10022
10023    /**
10024     * Returns true if the uri authority is one of the authorities specified in the provider.
10025     */
10026    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10027        String uriAuth = uri.getAuthority();
10028        String cpiAuth = cpi.authority;
10029        if (cpiAuth.indexOf(';') == -1) {
10030            return cpiAuth.equals(uriAuth);
10031        }
10032        String[] cpiAuths = cpiAuth.split(";");
10033        int length = cpiAuths.length;
10034        for (int i = 0; i < length; i++) {
10035            if (cpiAuths[i].equals(uriAuth)) return true;
10036        }
10037        return false;
10038    }
10039
10040    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10041            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10042        if (r != null) {
10043            for (int i=0; i<r.conProviders.size(); i++) {
10044                ContentProviderConnection conn = r.conProviders.get(i);
10045                if (conn.provider == cpr) {
10046                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10047                            "Adding provider requested by "
10048                            + r.processName + " from process "
10049                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10050                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10051                    if (stable) {
10052                        conn.stableCount++;
10053                        conn.numStableIncs++;
10054                    } else {
10055                        conn.unstableCount++;
10056                        conn.numUnstableIncs++;
10057                    }
10058                    return conn;
10059                }
10060            }
10061            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10062            if (stable) {
10063                conn.stableCount = 1;
10064                conn.numStableIncs = 1;
10065            } else {
10066                conn.unstableCount = 1;
10067                conn.numUnstableIncs = 1;
10068            }
10069            cpr.connections.add(conn);
10070            r.conProviders.add(conn);
10071            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10072            return conn;
10073        }
10074        cpr.addExternalProcessHandleLocked(externalProcessToken);
10075        return null;
10076    }
10077
10078    boolean decProviderCountLocked(ContentProviderConnection conn,
10079            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10080        if (conn != null) {
10081            cpr = conn.provider;
10082            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10083                    "Removing provider requested by "
10084                    + conn.client.processName + " from process "
10085                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10086                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10087            if (stable) {
10088                conn.stableCount--;
10089            } else {
10090                conn.unstableCount--;
10091            }
10092            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10093                cpr.connections.remove(conn);
10094                conn.client.conProviders.remove(conn);
10095                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10096                    // The client is more important than last activity -- note the time this
10097                    // is happening, so we keep the old provider process around a bit as last
10098                    // activity to avoid thrashing it.
10099                    if (cpr.proc != null) {
10100                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10101                    }
10102                }
10103                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10104                return true;
10105            }
10106            return false;
10107        }
10108        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10109        return false;
10110    }
10111
10112    private void checkTime(long startTime, String where) {
10113        long now = SystemClock.elapsedRealtime();
10114        if ((now-startTime) > 1000) {
10115            // If we are taking more than a second, log about it.
10116            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10117        }
10118    }
10119
10120    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10121            String name, IBinder token, boolean stable, int userId) {
10122        ContentProviderRecord cpr;
10123        ContentProviderConnection conn = null;
10124        ProviderInfo cpi = null;
10125
10126        synchronized(this) {
10127            long startTime = SystemClock.elapsedRealtime();
10128
10129            ProcessRecord r = null;
10130            if (caller != null) {
10131                r = getRecordForAppLocked(caller);
10132                if (r == null) {
10133                    throw new SecurityException(
10134                            "Unable to find app for caller " + caller
10135                          + " (pid=" + Binder.getCallingPid()
10136                          + ") when getting content provider " + name);
10137                }
10138            }
10139
10140            boolean checkCrossUser = true;
10141
10142            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10143
10144            // First check if this content provider has been published...
10145            cpr = mProviderMap.getProviderByName(name, userId);
10146            // If that didn't work, check if it exists for user 0 and then
10147            // verify that it's a singleton provider before using it.
10148            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10149                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10150                if (cpr != null) {
10151                    cpi = cpr.info;
10152                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10153                            cpi.name, cpi.flags)
10154                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10155                        userId = UserHandle.USER_SYSTEM;
10156                        checkCrossUser = false;
10157                    } else {
10158                        cpr = null;
10159                        cpi = null;
10160                    }
10161                }
10162            }
10163
10164            boolean providerRunning = cpr != null;
10165            if (providerRunning) {
10166                cpi = cpr.info;
10167                String msg;
10168                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10169                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10170                        != null) {
10171                    throw new SecurityException(msg);
10172                }
10173                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10174
10175                if (r != null && cpr.canRunHere(r)) {
10176                    // This provider has been published or is in the process
10177                    // of being published...  but it is also allowed to run
10178                    // in the caller's process, so don't make a connection
10179                    // and just let the caller instantiate its own instance.
10180                    ContentProviderHolder holder = cpr.newHolder(null);
10181                    // don't give caller the provider object, it needs
10182                    // to make its own.
10183                    holder.provider = null;
10184                    return holder;
10185                }
10186
10187                final long origId = Binder.clearCallingIdentity();
10188
10189                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10190
10191                // In this case the provider instance already exists, so we can
10192                // return it right away.
10193                conn = incProviderCountLocked(r, cpr, token, stable);
10194                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10195                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10196                        // If this is a perceptible app accessing the provider,
10197                        // make sure to count it as being accessed and thus
10198                        // back up on the LRU list.  This is good because
10199                        // content providers are often expensive to start.
10200                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10201                        updateLruProcessLocked(cpr.proc, false, null);
10202                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10203                    }
10204                }
10205
10206                if (cpr.proc != null) {
10207                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10208                    boolean success = updateOomAdjLocked(cpr.proc);
10209                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10210                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10211                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10212                    // NOTE: there is still a race here where a signal could be
10213                    // pending on the process even though we managed to update its
10214                    // adj level.  Not sure what to do about this, but at least
10215                    // the race is now smaller.
10216                    if (!success) {
10217                        // Uh oh...  it looks like the provider's process
10218                        // has been killed on us.  We need to wait for a new
10219                        // process to be started, and make sure its death
10220                        // doesn't kill our process.
10221                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10222                                + " is crashing; detaching " + r);
10223                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10224                        checkTime(startTime, "getContentProviderImpl: before appDied");
10225                        appDiedLocked(cpr.proc);
10226                        checkTime(startTime, "getContentProviderImpl: after appDied");
10227                        if (!lastRef) {
10228                            // This wasn't the last ref our process had on
10229                            // the provider...  we have now been killed, bail.
10230                            return null;
10231                        }
10232                        providerRunning = false;
10233                        conn = null;
10234                    }
10235                }
10236
10237                Binder.restoreCallingIdentity(origId);
10238            }
10239
10240            if (!providerRunning) {
10241                try {
10242                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10243                    cpi = AppGlobals.getPackageManager().
10244                        resolveContentProvider(name,
10245                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10246                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10247                } catch (RemoteException ex) {
10248                }
10249                if (cpi == null) {
10250                    return null;
10251                }
10252                // If the provider is a singleton AND
10253                // (it's a call within the same user || the provider is a
10254                // privileged app)
10255                // Then allow connecting to the singleton provider
10256                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10257                        cpi.name, cpi.flags)
10258                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10259                if (singleton) {
10260                    userId = UserHandle.USER_SYSTEM;
10261                }
10262                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10263                checkTime(startTime, "getContentProviderImpl: got app info for user");
10264
10265                String msg;
10266                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10267                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10268                        != null) {
10269                    throw new SecurityException(msg);
10270                }
10271                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10272
10273                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10274                        && !cpi.processName.equals("system")) {
10275                    // If this content provider does not run in the system
10276                    // process, and the system is not yet ready to run other
10277                    // processes, then fail fast instead of hanging.
10278                    throw new IllegalArgumentException(
10279                            "Attempt to launch content provider before system ready");
10280                }
10281
10282                // Make sure that the user who owns this provider is running.  If not,
10283                // we don't want to allow it to run.
10284                if (!mUserController.isUserRunningLocked(userId, 0)) {
10285                    Slog.w(TAG, "Unable to launch app "
10286                            + cpi.applicationInfo.packageName + "/"
10287                            + cpi.applicationInfo.uid + " for provider "
10288                            + name + ": user " + userId + " is stopped");
10289                    return null;
10290                }
10291
10292                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10293                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10294                cpr = mProviderMap.getProviderByClass(comp, userId);
10295                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10296                final boolean firstClass = cpr == null;
10297                if (firstClass) {
10298                    final long ident = Binder.clearCallingIdentity();
10299
10300                    // If permissions need a review before any of the app components can run,
10301                    // we return no provider and launch a review activity if the calling app
10302                    // is in the foreground.
10303                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10304                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10305                            return null;
10306                        }
10307                    }
10308
10309                    try {
10310                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10311                        ApplicationInfo ai =
10312                            AppGlobals.getPackageManager().
10313                                getApplicationInfo(
10314                                        cpi.applicationInfo.packageName,
10315                                        STOCK_PM_FLAGS, userId);
10316                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10317                        if (ai == null) {
10318                            Slog.w(TAG, "No package info for content provider "
10319                                    + cpi.name);
10320                            return null;
10321                        }
10322                        ai = getAppInfoForUser(ai, userId);
10323                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10324                    } catch (RemoteException ex) {
10325                        // pm is in same process, this will never happen.
10326                    } finally {
10327                        Binder.restoreCallingIdentity(ident);
10328                    }
10329                }
10330
10331                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10332
10333                if (r != null && cpr.canRunHere(r)) {
10334                    // If this is a multiprocess provider, then just return its
10335                    // info and allow the caller to instantiate it.  Only do
10336                    // this if the provider is the same user as the caller's
10337                    // process, or can run as root (so can be in any process).
10338                    return cpr.newHolder(null);
10339                }
10340
10341                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10342                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10343                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10344
10345                // This is single process, and our app is now connecting to it.
10346                // See if we are already in the process of launching this
10347                // provider.
10348                final int N = mLaunchingProviders.size();
10349                int i;
10350                for (i = 0; i < N; i++) {
10351                    if (mLaunchingProviders.get(i) == cpr) {
10352                        break;
10353                    }
10354                }
10355
10356                // If the provider is not already being launched, then get it
10357                // started.
10358                if (i >= N) {
10359                    final long origId = Binder.clearCallingIdentity();
10360
10361                    try {
10362                        // Content provider is now in use, its package can't be stopped.
10363                        try {
10364                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10365                            AppGlobals.getPackageManager().setPackageStoppedState(
10366                                    cpr.appInfo.packageName, false, userId);
10367                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10368                        } catch (RemoteException e) {
10369                        } catch (IllegalArgumentException e) {
10370                            Slog.w(TAG, "Failed trying to unstop package "
10371                                    + cpr.appInfo.packageName + ": " + e);
10372                        }
10373
10374                        // Use existing process if already started
10375                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10376                        ProcessRecord proc = getProcessRecordLocked(
10377                                cpi.processName, cpr.appInfo.uid, false);
10378                        if (proc != null && proc.thread != null) {
10379                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10380                                    "Installing in existing process " + proc);
10381                            if (!proc.pubProviders.containsKey(cpi.name)) {
10382                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10383                                proc.pubProviders.put(cpi.name, cpr);
10384                                try {
10385                                    proc.thread.scheduleInstallProvider(cpi);
10386                                } catch (RemoteException e) {
10387                                }
10388                            }
10389                        } else {
10390                            checkTime(startTime, "getContentProviderImpl: before start process");
10391                            proc = startProcessLocked(cpi.processName,
10392                                    cpr.appInfo, false, 0, "content provider",
10393                                    new ComponentName(cpi.applicationInfo.packageName,
10394                                            cpi.name), false, false, false);
10395                            checkTime(startTime, "getContentProviderImpl: after start process");
10396                            if (proc == null) {
10397                                Slog.w(TAG, "Unable to launch app "
10398                                        + cpi.applicationInfo.packageName + "/"
10399                                        + cpi.applicationInfo.uid + " for provider "
10400                                        + name + ": process is bad");
10401                                return null;
10402                            }
10403                        }
10404                        cpr.launchingApp = proc;
10405                        mLaunchingProviders.add(cpr);
10406                    } finally {
10407                        Binder.restoreCallingIdentity(origId);
10408                    }
10409                }
10410
10411                checkTime(startTime, "getContentProviderImpl: updating data structures");
10412
10413                // Make sure the provider is published (the same provider class
10414                // may be published under multiple names).
10415                if (firstClass) {
10416                    mProviderMap.putProviderByClass(comp, cpr);
10417                }
10418
10419                mProviderMap.putProviderByName(name, cpr);
10420                conn = incProviderCountLocked(r, cpr, token, stable);
10421                if (conn != null) {
10422                    conn.waiting = true;
10423                }
10424            }
10425            checkTime(startTime, "getContentProviderImpl: done!");
10426        }
10427
10428        // Wait for the provider to be published...
10429        synchronized (cpr) {
10430            while (cpr.provider == null) {
10431                if (cpr.launchingApp == null) {
10432                    Slog.w(TAG, "Unable to launch app "
10433                            + cpi.applicationInfo.packageName + "/"
10434                            + cpi.applicationInfo.uid + " for provider "
10435                            + name + ": launching app became null");
10436                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10437                            UserHandle.getUserId(cpi.applicationInfo.uid),
10438                            cpi.applicationInfo.packageName,
10439                            cpi.applicationInfo.uid, name);
10440                    return null;
10441                }
10442                try {
10443                    if (DEBUG_MU) Slog.v(TAG_MU,
10444                            "Waiting to start provider " + cpr
10445                            + " launchingApp=" + cpr.launchingApp);
10446                    if (conn != null) {
10447                        conn.waiting = true;
10448                    }
10449                    cpr.wait();
10450                } catch (InterruptedException ex) {
10451                } finally {
10452                    if (conn != null) {
10453                        conn.waiting = false;
10454                    }
10455                }
10456            }
10457        }
10458        return cpr != null ? cpr.newHolder(conn) : null;
10459    }
10460
10461    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10462            ProcessRecord r, final int userId) {
10463        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10464                cpi.packageName, r.userId)) {
10465
10466            final boolean callerForeground = r != null ? r.setSchedGroup
10467                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10468
10469            // Show a permission review UI only for starting from a foreground app
10470            if (!callerForeground) {
10471                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10472                        + cpi.packageName + " requires a permissions review");
10473                return false;
10474            }
10475
10476            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10477            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10478                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10479            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10480
10481            if (DEBUG_PERMISSIONS_REVIEW) {
10482                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10483                        + "for package " + cpi.packageName);
10484            }
10485
10486            final UserHandle userHandle = new UserHandle(userId);
10487            mHandler.post(new Runnable() {
10488                @Override
10489                public void run() {
10490                    mContext.startActivityAsUser(intent, userHandle);
10491                }
10492            });
10493
10494            return false;
10495        }
10496
10497        return true;
10498    }
10499
10500    PackageManagerInternal getPackageManagerInternalLocked() {
10501        if (mPackageManagerInt == null) {
10502            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10503        }
10504        return mPackageManagerInt;
10505    }
10506
10507    @Override
10508    public final ContentProviderHolder getContentProvider(
10509            IApplicationThread caller, String name, int userId, boolean stable) {
10510        enforceNotIsolatedCaller("getContentProvider");
10511        if (caller == null) {
10512            String msg = "null IApplicationThread when getting content provider "
10513                    + name;
10514            Slog.w(TAG, msg);
10515            throw new SecurityException(msg);
10516        }
10517        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10518        // with cross-user grant.
10519        return getContentProviderImpl(caller, name, null, stable, userId);
10520    }
10521
10522    public ContentProviderHolder getContentProviderExternal(
10523            String name, int userId, IBinder token) {
10524        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10525            "Do not have permission in call getContentProviderExternal()");
10526        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10527                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10528        return getContentProviderExternalUnchecked(name, token, userId);
10529    }
10530
10531    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10532            IBinder token, int userId) {
10533        return getContentProviderImpl(null, name, token, true, userId);
10534    }
10535
10536    /**
10537     * Drop a content provider from a ProcessRecord's bookkeeping
10538     */
10539    public void removeContentProvider(IBinder connection, boolean stable) {
10540        enforceNotIsolatedCaller("removeContentProvider");
10541        long ident = Binder.clearCallingIdentity();
10542        try {
10543            synchronized (this) {
10544                ContentProviderConnection conn;
10545                try {
10546                    conn = (ContentProviderConnection)connection;
10547                } catch (ClassCastException e) {
10548                    String msg ="removeContentProvider: " + connection
10549                            + " not a ContentProviderConnection";
10550                    Slog.w(TAG, msg);
10551                    throw new IllegalArgumentException(msg);
10552                }
10553                if (conn == null) {
10554                    throw new NullPointerException("connection is null");
10555                }
10556                if (decProviderCountLocked(conn, null, null, stable)) {
10557                    updateOomAdjLocked();
10558                }
10559            }
10560        } finally {
10561            Binder.restoreCallingIdentity(ident);
10562        }
10563    }
10564
10565    public void removeContentProviderExternal(String name, IBinder token) {
10566        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10567            "Do not have permission in call removeContentProviderExternal()");
10568        int userId = UserHandle.getCallingUserId();
10569        long ident = Binder.clearCallingIdentity();
10570        try {
10571            removeContentProviderExternalUnchecked(name, token, userId);
10572        } finally {
10573            Binder.restoreCallingIdentity(ident);
10574        }
10575    }
10576
10577    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10578        synchronized (this) {
10579            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10580            if(cpr == null) {
10581                //remove from mProvidersByClass
10582                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10583                return;
10584            }
10585
10586            //update content provider record entry info
10587            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10588            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10589            if (localCpr.hasExternalProcessHandles()) {
10590                if (localCpr.removeExternalProcessHandleLocked(token)) {
10591                    updateOomAdjLocked();
10592                } else {
10593                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10594                            + " with no external reference for token: "
10595                            + token + ".");
10596                }
10597            } else {
10598                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10599                        + " with no external references.");
10600            }
10601        }
10602    }
10603
10604    public final void publishContentProviders(IApplicationThread caller,
10605            List<ContentProviderHolder> providers) {
10606        if (providers == null) {
10607            return;
10608        }
10609
10610        enforceNotIsolatedCaller("publishContentProviders");
10611        synchronized (this) {
10612            final ProcessRecord r = getRecordForAppLocked(caller);
10613            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10614            if (r == null) {
10615                throw new SecurityException(
10616                        "Unable to find app for caller " + caller
10617                      + " (pid=" + Binder.getCallingPid()
10618                      + ") when publishing content providers");
10619            }
10620
10621            final long origId = Binder.clearCallingIdentity();
10622
10623            final int N = providers.size();
10624            for (int i = 0; i < N; i++) {
10625                ContentProviderHolder src = providers.get(i);
10626                if (src == null || src.info == null || src.provider == null) {
10627                    continue;
10628                }
10629                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10630                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10631                if (dst != null) {
10632                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10633                    mProviderMap.putProviderByClass(comp, dst);
10634                    String names[] = dst.info.authority.split(";");
10635                    for (int j = 0; j < names.length; j++) {
10636                        mProviderMap.putProviderByName(names[j], dst);
10637                    }
10638
10639                    int launchingCount = mLaunchingProviders.size();
10640                    int j;
10641                    boolean wasInLaunchingProviders = false;
10642                    for (j = 0; j < launchingCount; j++) {
10643                        if (mLaunchingProviders.get(j) == dst) {
10644                            mLaunchingProviders.remove(j);
10645                            wasInLaunchingProviders = true;
10646                            j--;
10647                            launchingCount--;
10648                        }
10649                    }
10650                    if (wasInLaunchingProviders) {
10651                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10652                    }
10653                    synchronized (dst) {
10654                        dst.provider = src.provider;
10655                        dst.proc = r;
10656                        dst.notifyAll();
10657                    }
10658                    updateOomAdjLocked(r);
10659                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10660                            src.info.authority);
10661                }
10662            }
10663
10664            Binder.restoreCallingIdentity(origId);
10665        }
10666    }
10667
10668    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10669        ContentProviderConnection conn;
10670        try {
10671            conn = (ContentProviderConnection)connection;
10672        } catch (ClassCastException e) {
10673            String msg ="refContentProvider: " + connection
10674                    + " not a ContentProviderConnection";
10675            Slog.w(TAG, msg);
10676            throw new IllegalArgumentException(msg);
10677        }
10678        if (conn == null) {
10679            throw new NullPointerException("connection is null");
10680        }
10681
10682        synchronized (this) {
10683            if (stable > 0) {
10684                conn.numStableIncs += stable;
10685            }
10686            stable = conn.stableCount + stable;
10687            if (stable < 0) {
10688                throw new IllegalStateException("stableCount < 0: " + stable);
10689            }
10690
10691            if (unstable > 0) {
10692                conn.numUnstableIncs += unstable;
10693            }
10694            unstable = conn.unstableCount + unstable;
10695            if (unstable < 0) {
10696                throw new IllegalStateException("unstableCount < 0: " + unstable);
10697            }
10698
10699            if ((stable+unstable) <= 0) {
10700                throw new IllegalStateException("ref counts can't go to zero here: stable="
10701                        + stable + " unstable=" + unstable);
10702            }
10703            conn.stableCount = stable;
10704            conn.unstableCount = unstable;
10705            return !conn.dead;
10706        }
10707    }
10708
10709    public void unstableProviderDied(IBinder connection) {
10710        ContentProviderConnection conn;
10711        try {
10712            conn = (ContentProviderConnection)connection;
10713        } catch (ClassCastException e) {
10714            String msg ="refContentProvider: " + connection
10715                    + " not a ContentProviderConnection";
10716            Slog.w(TAG, msg);
10717            throw new IllegalArgumentException(msg);
10718        }
10719        if (conn == null) {
10720            throw new NullPointerException("connection is null");
10721        }
10722
10723        // Safely retrieve the content provider associated with the connection.
10724        IContentProvider provider;
10725        synchronized (this) {
10726            provider = conn.provider.provider;
10727        }
10728
10729        if (provider == null) {
10730            // Um, yeah, we're way ahead of you.
10731            return;
10732        }
10733
10734        // Make sure the caller is being honest with us.
10735        if (provider.asBinder().pingBinder()) {
10736            // Er, no, still looks good to us.
10737            synchronized (this) {
10738                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10739                        + " says " + conn + " died, but we don't agree");
10740                return;
10741            }
10742        }
10743
10744        // Well look at that!  It's dead!
10745        synchronized (this) {
10746            if (conn.provider.provider != provider) {
10747                // But something changed...  good enough.
10748                return;
10749            }
10750
10751            ProcessRecord proc = conn.provider.proc;
10752            if (proc == null || proc.thread == null) {
10753                // Seems like the process is already cleaned up.
10754                return;
10755            }
10756
10757            // As far as we're concerned, this is just like receiving a
10758            // death notification...  just a bit prematurely.
10759            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10760                    + ") early provider death");
10761            final long ident = Binder.clearCallingIdentity();
10762            try {
10763                appDiedLocked(proc);
10764            } finally {
10765                Binder.restoreCallingIdentity(ident);
10766            }
10767        }
10768    }
10769
10770    @Override
10771    public void appNotRespondingViaProvider(IBinder connection) {
10772        enforceCallingPermission(
10773                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10774
10775        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10776        if (conn == null) {
10777            Slog.w(TAG, "ContentProviderConnection is null");
10778            return;
10779        }
10780
10781        final ProcessRecord host = conn.provider.proc;
10782        if (host == null) {
10783            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10784            return;
10785        }
10786
10787        final long token = Binder.clearCallingIdentity();
10788        try {
10789            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10790        } finally {
10791            Binder.restoreCallingIdentity(token);
10792        }
10793    }
10794
10795    public final void installSystemProviders() {
10796        List<ProviderInfo> providers;
10797        synchronized (this) {
10798            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10799            providers = generateApplicationProvidersLocked(app);
10800            if (providers != null) {
10801                for (int i=providers.size()-1; i>=0; i--) {
10802                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10803                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10804                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10805                                + ": not system .apk");
10806                        providers.remove(i);
10807                    }
10808                }
10809            }
10810        }
10811        if (providers != null) {
10812            mSystemThread.installSystemProviders(providers);
10813        }
10814
10815        mCoreSettingsObserver = new CoreSettingsObserver(this);
10816        mFontScaleSettingObserver = new FontScaleSettingObserver();
10817
10818        //mUsageStatsService.monitorPackages();
10819    }
10820
10821    private void startPersistentApps(int matchFlags) {
10822        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10823
10824        synchronized (this) {
10825            try {
10826                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10827                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags);
10828                for (ApplicationInfo app : apps) {
10829                    if (!"android".equals(app.packageName)) {
10830                        addAppLocked(app, false, null /* ABI override */);
10831                    }
10832                }
10833            } catch (RemoteException ex) {
10834            }
10835        }
10836    }
10837
10838    /**
10839     * When a user is unlocked, we need to install encryption-unaware providers
10840     * belonging to any running apps.
10841     */
10842    private void installEncryptionUnawareProviders(int userId) {
10843        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10844            // TODO: eventually pivot this back to look at current user state,
10845            // similar to the comment in UserManager.isUserUnlocked(), but for
10846            // now, if we started apps when "unlocked" then unaware providers
10847            // have already been spun up.
10848            return;
10849        }
10850
10851        // We're only interested in providers that are encryption unaware, and
10852        // we don't care about uninstalled apps, since there's no way they're
10853        // running at this point.
10854        final int matchFlags = GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE;
10855
10856        synchronized (this) {
10857            final int NP = mProcessNames.getMap().size();
10858            for (int ip = 0; ip < NP; ip++) {
10859                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10860                final int NA = apps.size();
10861                for (int ia = 0; ia < NA; ia++) {
10862                    final ProcessRecord app = apps.valueAt(ia);
10863                    if (app.userId != userId || app.thread == null) continue;
10864
10865                    final int NG = app.pkgList.size();
10866                    for (int ig = 0; ig < NG; ig++) {
10867                        try {
10868                            final String pkgName = app.pkgList.keyAt(ig);
10869                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10870                                    .getPackageInfo(pkgName, matchFlags, userId);
10871                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10872                                for (ProviderInfo provInfo : pkgInfo.providers) {
10873                                    Log.v(TAG, "Installing " + provInfo);
10874                                    app.thread.scheduleInstallProvider(provInfo);
10875                                }
10876                            }
10877                        } catch (RemoteException ignored) {
10878                        }
10879                    }
10880                }
10881            }
10882        }
10883    }
10884
10885    /**
10886     * Allows apps to retrieve the MIME type of a URI.
10887     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10888     * users, then it does not need permission to access the ContentProvider.
10889     * Either, it needs cross-user uri grants.
10890     *
10891     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10892     *
10893     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10894     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10895     */
10896    public String getProviderMimeType(Uri uri, int userId) {
10897        enforceNotIsolatedCaller("getProviderMimeType");
10898        final String name = uri.getAuthority();
10899        int callingUid = Binder.getCallingUid();
10900        int callingPid = Binder.getCallingPid();
10901        long ident = 0;
10902        boolean clearedIdentity = false;
10903        synchronized (this) {
10904            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10905        }
10906        if (canClearIdentity(callingPid, callingUid, userId)) {
10907            clearedIdentity = true;
10908            ident = Binder.clearCallingIdentity();
10909        }
10910        ContentProviderHolder holder = null;
10911        try {
10912            holder = getContentProviderExternalUnchecked(name, null, userId);
10913            if (holder != null) {
10914                return holder.provider.getType(uri);
10915            }
10916        } catch (RemoteException e) {
10917            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10918            return null;
10919        } finally {
10920            // We need to clear the identity to call removeContentProviderExternalUnchecked
10921            if (!clearedIdentity) {
10922                ident = Binder.clearCallingIdentity();
10923            }
10924            try {
10925                if (holder != null) {
10926                    removeContentProviderExternalUnchecked(name, null, userId);
10927                }
10928            } finally {
10929                Binder.restoreCallingIdentity(ident);
10930            }
10931        }
10932
10933        return null;
10934    }
10935
10936    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10937        if (UserHandle.getUserId(callingUid) == userId) {
10938            return true;
10939        }
10940        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10941                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10942                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10943                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10944                return true;
10945        }
10946        return false;
10947    }
10948
10949    // =========================================================
10950    // GLOBAL MANAGEMENT
10951    // =========================================================
10952
10953    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10954            boolean isolated, int isolatedUid) {
10955        String proc = customProcess != null ? customProcess : info.processName;
10956        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10957        final int userId = UserHandle.getUserId(info.uid);
10958        int uid = info.uid;
10959        if (isolated) {
10960            if (isolatedUid == 0) {
10961                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10962                while (true) {
10963                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10964                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10965                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10966                    }
10967                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10968                    mNextIsolatedProcessUid++;
10969                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10970                        // No process for this uid, use it.
10971                        break;
10972                    }
10973                    stepsLeft--;
10974                    if (stepsLeft <= 0) {
10975                        return null;
10976                    }
10977                }
10978            } else {
10979                // Special case for startIsolatedProcess (internal only), where
10980                // the uid of the isolated process is specified by the caller.
10981                uid = isolatedUid;
10982            }
10983        }
10984        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10985        if (!mBooted && !mBooting
10986                && userId == UserHandle.USER_SYSTEM
10987                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10988            r.persistent = true;
10989        }
10990        addProcessNameLocked(r);
10991        return r;
10992    }
10993
10994    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10995            String abiOverride) {
10996        ProcessRecord app;
10997        if (!isolated) {
10998            app = getProcessRecordLocked(info.processName, info.uid, true);
10999        } else {
11000            app = null;
11001        }
11002
11003        if (app == null) {
11004            app = newProcessRecordLocked(info, null, isolated, 0);
11005            updateLruProcessLocked(app, false, null);
11006            updateOomAdjLocked();
11007        }
11008
11009        // This package really, really can not be stopped.
11010        try {
11011            AppGlobals.getPackageManager().setPackageStoppedState(
11012                    info.packageName, false, UserHandle.getUserId(app.uid));
11013        } catch (RemoteException e) {
11014        } catch (IllegalArgumentException e) {
11015            Slog.w(TAG, "Failed trying to unstop package "
11016                    + info.packageName + ": " + e);
11017        }
11018
11019        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11020            app.persistent = true;
11021            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11022        }
11023        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11024            mPersistentStartingProcesses.add(app);
11025            startProcessLocked(app, "added application", app.processName, abiOverride,
11026                    null /* entryPoint */, null /* entryPointArgs */);
11027        }
11028
11029        return app;
11030    }
11031
11032    public void unhandledBack() {
11033        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11034                "unhandledBack()");
11035
11036        synchronized(this) {
11037            final long origId = Binder.clearCallingIdentity();
11038            try {
11039                getFocusedStack().unhandledBackLocked();
11040            } finally {
11041                Binder.restoreCallingIdentity(origId);
11042            }
11043        }
11044    }
11045
11046    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11047        enforceNotIsolatedCaller("openContentUri");
11048        final int userId = UserHandle.getCallingUserId();
11049        String name = uri.getAuthority();
11050        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11051        ParcelFileDescriptor pfd = null;
11052        if (cph != null) {
11053            // We record the binder invoker's uid in thread-local storage before
11054            // going to the content provider to open the file.  Later, in the code
11055            // that handles all permissions checks, we look for this uid and use
11056            // that rather than the Activity Manager's own uid.  The effect is that
11057            // we do the check against the caller's permissions even though it looks
11058            // to the content provider like the Activity Manager itself is making
11059            // the request.
11060            Binder token = new Binder();
11061            sCallerIdentity.set(new Identity(
11062                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11063            try {
11064                pfd = cph.provider.openFile(null, uri, "r", null, token);
11065            } catch (FileNotFoundException e) {
11066                // do nothing; pfd will be returned null
11067            } finally {
11068                // Ensure that whatever happens, we clean up the identity state
11069                sCallerIdentity.remove();
11070                // Ensure we're done with the provider.
11071                removeContentProviderExternalUnchecked(name, null, userId);
11072            }
11073        } else {
11074            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11075        }
11076        return pfd;
11077    }
11078
11079    // Actually is sleeping or shutting down or whatever else in the future
11080    // is an inactive state.
11081    public boolean isSleepingOrShuttingDown() {
11082        return isSleeping() || mShuttingDown;
11083    }
11084
11085    public boolean isSleeping() {
11086        return mSleeping;
11087    }
11088
11089    void onWakefulnessChanged(int wakefulness) {
11090        synchronized(this) {
11091            mWakefulness = wakefulness;
11092            updateSleepIfNeededLocked();
11093        }
11094    }
11095
11096    void finishRunningVoiceLocked() {
11097        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
11098        if (mRunningVoice != null) {
11099            mRunningVoice = null;
11100            mVoiceWakeLock.release();
11101            updateSleepIfNeededLocked();
11102        }
11103    }
11104
11105    void startTimeTrackingFocusedActivityLocked() {
11106        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11107            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11108        }
11109    }
11110
11111    void updateSleepIfNeededLocked() {
11112        if (mSleeping && !shouldSleepLocked()) {
11113            mSleeping = false;
11114            startTimeTrackingFocusedActivityLocked();
11115            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11116            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11117            updateOomAdjLocked();
11118        } else if (!mSleeping && shouldSleepLocked()) {
11119            mSleeping = true;
11120            if (mCurAppTimeTracker != null) {
11121                mCurAppTimeTracker.stop();
11122            }
11123            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11124            mStackSupervisor.goingToSleepLocked();
11125            updateOomAdjLocked();
11126
11127            // Initialize the wake times of all processes.
11128            checkExcessivePowerUsageLocked(false);
11129            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11130            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11131            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11132        }
11133    }
11134
11135    private boolean shouldSleepLocked() {
11136        // Resume applications while running a voice interactor.
11137        if (mRunningVoice != null) {
11138            return false;
11139        }
11140
11141        // TODO: Transform the lock screen state into a sleep token instead.
11142        switch (mWakefulness) {
11143            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11144            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11145            case PowerManagerInternal.WAKEFULNESS_DOZING:
11146                // Pause applications whenever the lock screen is shown or any sleep
11147                // tokens have been acquired.
11148                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11149            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11150            default:
11151                // If we're asleep then pause applications unconditionally.
11152                return true;
11153        }
11154    }
11155
11156    /** Pokes the task persister. */
11157    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11158        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11159    }
11160
11161    /** Notifies all listeners when the task stack has changed. */
11162    void notifyTaskStackChangedLocked() {
11163        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11164        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11165        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11166        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11167    }
11168
11169    /** Notifies all listeners when an Activity is pinned. */
11170    void notifyActivityPinnedLocked() {
11171        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11172        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11173    }
11174
11175    /**
11176     * Notifies all listeners when an attempt was made to start an an activity that is already
11177     * running in the pinned stack and the activity was not actually started, but the task is
11178     * either brought to the front or a new Intent is delivered to it.
11179     */
11180    void notifyPinnedActivityRestartAttemptLocked() {
11181        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11182        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11183    }
11184
11185    /** Notifies all listeners when the pinned stack animation ends. */
11186    @Override
11187    public void notifyPinnedStackAnimationEnded() {
11188        synchronized (this) {
11189            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11190            mHandler.obtainMessage(
11191                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11192        }
11193    }
11194
11195    @Override
11196    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11197        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11198    }
11199
11200    @Override
11201    public boolean shutdown(int timeout) {
11202        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11203                != PackageManager.PERMISSION_GRANTED) {
11204            throw new SecurityException("Requires permission "
11205                    + android.Manifest.permission.SHUTDOWN);
11206        }
11207
11208        boolean timedout = false;
11209
11210        synchronized(this) {
11211            mShuttingDown = true;
11212            updateEventDispatchingLocked();
11213            timedout = mStackSupervisor.shutdownLocked(timeout);
11214        }
11215
11216        mAppOpsService.shutdown();
11217        if (mUsageStatsService != null) {
11218            mUsageStatsService.prepareShutdown();
11219        }
11220        mBatteryStatsService.shutdown();
11221        synchronized (this) {
11222            mProcessStats.shutdownLocked();
11223            notifyTaskPersisterLocked(null, true);
11224        }
11225
11226        return timedout;
11227    }
11228
11229    public final void activitySlept(IBinder token) {
11230        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11231
11232        final long origId = Binder.clearCallingIdentity();
11233
11234        synchronized (this) {
11235            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11236            if (r != null) {
11237                mStackSupervisor.activitySleptLocked(r);
11238            }
11239        }
11240
11241        Binder.restoreCallingIdentity(origId);
11242    }
11243
11244    private String lockScreenShownToString() {
11245        switch (mLockScreenShown) {
11246            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11247            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11248            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11249            default: return "Unknown=" + mLockScreenShown;
11250        }
11251    }
11252
11253    void logLockScreen(String msg) {
11254        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11255                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11256                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11257                + " mSleeping=" + mSleeping);
11258    }
11259
11260    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11261        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11262        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11263        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11264            boolean wasRunningVoice = mRunningVoice != null;
11265            mRunningVoice = session;
11266            if (!wasRunningVoice) {
11267                mVoiceWakeLock.acquire();
11268                updateSleepIfNeededLocked();
11269            }
11270        }
11271    }
11272
11273    private void updateEventDispatchingLocked() {
11274        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11275    }
11276
11277    public void setLockScreenShown(boolean shown) {
11278        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11279                != PackageManager.PERMISSION_GRANTED) {
11280            throw new SecurityException("Requires permission "
11281                    + android.Manifest.permission.DEVICE_POWER);
11282        }
11283
11284        final int user = UserHandle.myUserId();
11285        synchronized(this) {
11286            long ident = Binder.clearCallingIdentity();
11287            try {
11288                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11289                    startHomeActivityLocked(user, "setLockScreenShown");
11290                }
11291                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11292                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11293                updateSleepIfNeededLocked();
11294            } finally {
11295                Binder.restoreCallingIdentity(ident);
11296            }
11297        }
11298    }
11299
11300    @Override
11301    public void stopAppSwitches() {
11302        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11303                != PackageManager.PERMISSION_GRANTED) {
11304            throw new SecurityException("viewquires permission "
11305                    + android.Manifest.permission.STOP_APP_SWITCHES);
11306        }
11307
11308        synchronized(this) {
11309            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11310                    + APP_SWITCH_DELAY_TIME;
11311            mDidAppSwitch = false;
11312            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11313            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11314            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11315        }
11316    }
11317
11318    public void resumeAppSwitches() {
11319        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11320                != PackageManager.PERMISSION_GRANTED) {
11321            throw new SecurityException("Requires permission "
11322                    + android.Manifest.permission.STOP_APP_SWITCHES);
11323        }
11324
11325        synchronized(this) {
11326            // Note that we don't execute any pending app switches... we will
11327            // let those wait until either the timeout, or the next start
11328            // activity request.
11329            mAppSwitchesAllowedTime = 0;
11330        }
11331    }
11332
11333    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11334            int callingPid, int callingUid, String name) {
11335        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11336            return true;
11337        }
11338
11339        int perm = checkComponentPermission(
11340                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11341                sourceUid, -1, true);
11342        if (perm == PackageManager.PERMISSION_GRANTED) {
11343            return true;
11344        }
11345
11346        // If the actual IPC caller is different from the logical source, then
11347        // also see if they are allowed to control app switches.
11348        if (callingUid != -1 && callingUid != sourceUid) {
11349            perm = checkComponentPermission(
11350                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11351                    callingUid, -1, true);
11352            if (perm == PackageManager.PERMISSION_GRANTED) {
11353                return true;
11354            }
11355        }
11356
11357        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11358        return false;
11359    }
11360
11361    public void setDebugApp(String packageName, boolean waitForDebugger,
11362            boolean persistent) {
11363        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11364                "setDebugApp()");
11365
11366        long ident = Binder.clearCallingIdentity();
11367        try {
11368            // Note that this is not really thread safe if there are multiple
11369            // callers into it at the same time, but that's not a situation we
11370            // care about.
11371            if (persistent) {
11372                final ContentResolver resolver = mContext.getContentResolver();
11373                Settings.Global.putString(
11374                    resolver, Settings.Global.DEBUG_APP,
11375                    packageName);
11376                Settings.Global.putInt(
11377                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11378                    waitForDebugger ? 1 : 0);
11379            }
11380
11381            synchronized (this) {
11382                if (!persistent) {
11383                    mOrigDebugApp = mDebugApp;
11384                    mOrigWaitForDebugger = mWaitForDebugger;
11385                }
11386                mDebugApp = packageName;
11387                mWaitForDebugger = waitForDebugger;
11388                mDebugTransient = !persistent;
11389                if (packageName != null) {
11390                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11391                            false, UserHandle.USER_ALL, "set debug app");
11392                }
11393            }
11394        } finally {
11395            Binder.restoreCallingIdentity(ident);
11396        }
11397    }
11398
11399    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11400        synchronized (this) {
11401            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11402            if (!isDebuggable) {
11403                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11404                    throw new SecurityException("Process not debuggable: " + app.packageName);
11405                }
11406            }
11407
11408            mTrackAllocationApp = processName;
11409        }
11410    }
11411
11412    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11413        synchronized (this) {
11414            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11415            if (!isDebuggable) {
11416                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11417                    throw new SecurityException("Process not debuggable: " + app.packageName);
11418                }
11419            }
11420            mProfileApp = processName;
11421            mProfileFile = profilerInfo.profileFile;
11422            if (mProfileFd != null) {
11423                try {
11424                    mProfileFd.close();
11425                } catch (IOException e) {
11426                }
11427                mProfileFd = null;
11428            }
11429            mProfileFd = profilerInfo.profileFd;
11430            mSamplingInterval = profilerInfo.samplingInterval;
11431            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11432            mProfileType = 0;
11433        }
11434    }
11435
11436    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11437        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11438        if (!isDebuggable) {
11439            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11440                throw new SecurityException("Process not debuggable: " + app.packageName);
11441            }
11442        }
11443        mNativeDebuggingApp = processName;
11444    }
11445
11446    @Override
11447    public void setAlwaysFinish(boolean enabled) {
11448        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11449                "setAlwaysFinish()");
11450
11451        long ident = Binder.clearCallingIdentity();
11452        try {
11453            Settings.Global.putInt(
11454                    mContext.getContentResolver(),
11455                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11456
11457            synchronized (this) {
11458                mAlwaysFinishActivities = enabled;
11459            }
11460        } finally {
11461            Binder.restoreCallingIdentity(ident);
11462        }
11463    }
11464
11465    @Override
11466    public void setLenientBackgroundCheck(boolean enabled) {
11467        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11468                "setLenientBackgroundCheck()");
11469
11470        long ident = Binder.clearCallingIdentity();
11471        try {
11472            Settings.Global.putInt(
11473                    mContext.getContentResolver(),
11474                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11475
11476            synchronized (this) {
11477                mLenientBackgroundCheck = enabled;
11478            }
11479        } finally {
11480            Binder.restoreCallingIdentity(ident);
11481        }
11482    }
11483
11484    @Override
11485    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11486        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11487                "setActivityController()");
11488        synchronized (this) {
11489            mController = controller;
11490            mControllerIsAMonkey = imAMonkey;
11491            Watchdog.getInstance().setActivityController(controller);
11492        }
11493    }
11494
11495    @Override
11496    public void setUserIsMonkey(boolean userIsMonkey) {
11497        synchronized (this) {
11498            synchronized (mPidsSelfLocked) {
11499                final int callingPid = Binder.getCallingPid();
11500                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11501                if (precessRecord == null) {
11502                    throw new SecurityException("Unknown process: " + callingPid);
11503                }
11504                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11505                    throw new SecurityException("Only an instrumentation process "
11506                            + "with a UiAutomation can call setUserIsMonkey");
11507                }
11508            }
11509            mUserIsMonkey = userIsMonkey;
11510        }
11511    }
11512
11513    @Override
11514    public boolean isUserAMonkey() {
11515        synchronized (this) {
11516            // If there is a controller also implies the user is a monkey.
11517            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11518        }
11519    }
11520
11521    public void requestBugReport(int bugreportType) {
11522        String service = null;
11523        switch (bugreportType) {
11524            case ActivityManager.BUGREPORT_OPTION_FULL:
11525                service = "bugreport";
11526                break;
11527            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11528                service = "bugreportplus";
11529                break;
11530            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11531                service = "bugreportremote";
11532                break;
11533        }
11534        if (service == null) {
11535            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11536                    + bugreportType);
11537        }
11538        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11539        SystemProperties.set("ctl.start", service);
11540    }
11541
11542    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11543        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11544    }
11545
11546    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11547        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11548            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11549        }
11550        return KEY_DISPATCHING_TIMEOUT;
11551    }
11552
11553    @Override
11554    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11555        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11556                != PackageManager.PERMISSION_GRANTED) {
11557            throw new SecurityException("Requires permission "
11558                    + android.Manifest.permission.FILTER_EVENTS);
11559        }
11560        ProcessRecord proc;
11561        long timeout;
11562        synchronized (this) {
11563            synchronized (mPidsSelfLocked) {
11564                proc = mPidsSelfLocked.get(pid);
11565            }
11566            timeout = getInputDispatchingTimeoutLocked(proc);
11567        }
11568
11569        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11570            return -1;
11571        }
11572
11573        return timeout;
11574    }
11575
11576    /**
11577     * Handle input dispatching timeouts.
11578     * Returns whether input dispatching should be aborted or not.
11579     */
11580    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11581            final ActivityRecord activity, final ActivityRecord parent,
11582            final boolean aboveSystem, String reason) {
11583        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11584                != PackageManager.PERMISSION_GRANTED) {
11585            throw new SecurityException("Requires permission "
11586                    + android.Manifest.permission.FILTER_EVENTS);
11587        }
11588
11589        final String annotation;
11590        if (reason == null) {
11591            annotation = "Input dispatching timed out";
11592        } else {
11593            annotation = "Input dispatching timed out (" + reason + ")";
11594        }
11595
11596        if (proc != null) {
11597            synchronized (this) {
11598                if (proc.debugging) {
11599                    return false;
11600                }
11601
11602                if (mDidDexOpt) {
11603                    // Give more time since we were dexopting.
11604                    mDidDexOpt = false;
11605                    return false;
11606                }
11607
11608                if (proc.instrumentationClass != null) {
11609                    Bundle info = new Bundle();
11610                    info.putString("shortMsg", "keyDispatchingTimedOut");
11611                    info.putString("longMsg", annotation);
11612                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11613                    return true;
11614                }
11615            }
11616            mHandler.post(new Runnable() {
11617                @Override
11618                public void run() {
11619                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11620                }
11621            });
11622        }
11623
11624        return true;
11625    }
11626
11627    @Override
11628    public Bundle getAssistContextExtras(int requestType) {
11629        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11630                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11631        if (pae == null) {
11632            return null;
11633        }
11634        synchronized (pae) {
11635            while (!pae.haveResult) {
11636                try {
11637                    pae.wait();
11638                } catch (InterruptedException e) {
11639                }
11640            }
11641        }
11642        synchronized (this) {
11643            buildAssistBundleLocked(pae, pae.result);
11644            mPendingAssistExtras.remove(pae);
11645            mUiHandler.removeCallbacks(pae);
11646        }
11647        return pae.extras;
11648    }
11649
11650    @Override
11651    public boolean isAssistDataAllowedOnCurrentActivity() {
11652        int userId;
11653        synchronized (this) {
11654            userId = mUserController.getCurrentUserIdLocked();
11655            ActivityRecord activity = getFocusedStack().topActivity();
11656            if (activity == null) {
11657                return false;
11658            }
11659            userId = activity.userId;
11660        }
11661        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11662                Context.DEVICE_POLICY_SERVICE);
11663        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11664    }
11665
11666    @Override
11667    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11668        long ident = Binder.clearCallingIdentity();
11669        try {
11670            synchronized (this) {
11671                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11672                ActivityRecord top = getFocusedStack().topActivity();
11673                if (top != caller) {
11674                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11675                            + " is not current top " + top);
11676                    return false;
11677                }
11678                if (!top.nowVisible) {
11679                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11680                            + " is not visible");
11681                    return false;
11682                }
11683            }
11684            AssistUtils utils = new AssistUtils(mContext);
11685            return utils.showSessionForActiveService(args,
11686                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11687        } finally {
11688            Binder.restoreCallingIdentity(ident);
11689        }
11690    }
11691
11692    @Override
11693    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11694            IBinder activityToken) {
11695        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11696                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11697    }
11698
11699    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11700            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11701            long timeout) {
11702        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11703                "enqueueAssistContext()");
11704        synchronized (this) {
11705            ActivityRecord activity = getFocusedStack().topActivity();
11706            if (activity == null) {
11707                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11708                return null;
11709            }
11710            if (activity.app == null || activity.app.thread == null) {
11711                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11712                return null;
11713            }
11714            if (activityToken != null) {
11715                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11716                if (activity != caller) {
11717                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11718                            + " is not current top " + activity);
11719                    return null;
11720                }
11721            }
11722            PendingAssistExtras pae;
11723            Bundle extras = new Bundle();
11724            if (args != null) {
11725                extras.putAll(args);
11726            }
11727            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11728            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11729            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11730            try {
11731                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11732                        requestType);
11733                mPendingAssistExtras.add(pae);
11734                mUiHandler.postDelayed(pae, timeout);
11735            } catch (RemoteException e) {
11736                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11737                return null;
11738            }
11739            return pae;
11740        }
11741    }
11742
11743    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11744        IResultReceiver receiver;
11745        synchronized (this) {
11746            mPendingAssistExtras.remove(pae);
11747            receiver = pae.receiver;
11748        }
11749        if (receiver != null) {
11750            // Caller wants result sent back to them.
11751            try {
11752                pae.receiver.send(0, null);
11753            } catch (RemoteException e) {
11754            }
11755        }
11756    }
11757
11758    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11759        if (result != null) {
11760            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11761        }
11762        if (pae.hint != null) {
11763            pae.extras.putBoolean(pae.hint, true);
11764        }
11765    }
11766
11767    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11768            AssistContent content, Uri referrer) {
11769        PendingAssistExtras pae = (PendingAssistExtras)token;
11770        synchronized (pae) {
11771            pae.result = extras;
11772            pae.structure = structure;
11773            pae.content = content;
11774            if (referrer != null) {
11775                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11776            }
11777            pae.haveResult = true;
11778            pae.notifyAll();
11779            if (pae.intent == null && pae.receiver == null) {
11780                // Caller is just waiting for the result.
11781                return;
11782            }
11783        }
11784
11785        // We are now ready to launch the assist activity.
11786        IResultReceiver sendReceiver = null;
11787        Bundle sendBundle = null;
11788        synchronized (this) {
11789            buildAssistBundleLocked(pae, extras);
11790            boolean exists = mPendingAssistExtras.remove(pae);
11791            mUiHandler.removeCallbacks(pae);
11792            if (!exists) {
11793                // Timed out.
11794                return;
11795            }
11796            if ((sendReceiver=pae.receiver) != null) {
11797                // Caller wants result sent back to them.
11798                sendBundle = new Bundle();
11799                sendBundle.putBundle("data", pae.extras);
11800                sendBundle.putParcelable("structure", pae.structure);
11801                sendBundle.putParcelable("content", pae.content);
11802            }
11803        }
11804        if (sendReceiver != null) {
11805            try {
11806                sendReceiver.send(0, sendBundle);
11807            } catch (RemoteException e) {
11808            }
11809            return;
11810        }
11811
11812        long ident = Binder.clearCallingIdentity();
11813        try {
11814            pae.intent.replaceExtras(pae.extras);
11815            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11816                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11817                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11818            closeSystemDialogs("assist");
11819            try {
11820                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11821            } catch (ActivityNotFoundException e) {
11822                Slog.w(TAG, "No activity to handle assist action.", e);
11823            }
11824        } finally {
11825            Binder.restoreCallingIdentity(ident);
11826        }
11827    }
11828
11829    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11830            Bundle args) {
11831        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11832                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11833    }
11834
11835    public void registerProcessObserver(IProcessObserver observer) {
11836        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11837                "registerProcessObserver()");
11838        synchronized (this) {
11839            mProcessObservers.register(observer);
11840        }
11841    }
11842
11843    @Override
11844    public void unregisterProcessObserver(IProcessObserver observer) {
11845        synchronized (this) {
11846            mProcessObservers.unregister(observer);
11847        }
11848    }
11849
11850    @Override
11851    public void registerUidObserver(IUidObserver observer, int which) {
11852        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11853                "registerUidObserver()");
11854        synchronized (this) {
11855            mUidObservers.register(observer, which);
11856        }
11857    }
11858
11859    @Override
11860    public void unregisterUidObserver(IUidObserver observer) {
11861        synchronized (this) {
11862            mUidObservers.unregister(observer);
11863        }
11864    }
11865
11866    @Override
11867    public boolean convertFromTranslucent(IBinder token) {
11868        final long origId = Binder.clearCallingIdentity();
11869        try {
11870            synchronized (this) {
11871                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11872                if (r == null) {
11873                    return false;
11874                }
11875                final boolean translucentChanged = r.changeWindowTranslucency(true);
11876                if (translucentChanged) {
11877                    r.task.stack.releaseBackgroundResources(r);
11878                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11879                }
11880                mWindowManager.setAppFullscreen(token, true);
11881                return translucentChanged;
11882            }
11883        } finally {
11884            Binder.restoreCallingIdentity(origId);
11885        }
11886    }
11887
11888    @Override
11889    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11890        final long origId = Binder.clearCallingIdentity();
11891        try {
11892            synchronized (this) {
11893                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11894                if (r == null) {
11895                    return false;
11896                }
11897                int index = r.task.mActivities.lastIndexOf(r);
11898                if (index > 0) {
11899                    ActivityRecord under = r.task.mActivities.get(index - 1);
11900                    under.returningOptions = options;
11901                }
11902                final boolean translucentChanged = r.changeWindowTranslucency(false);
11903                if (translucentChanged) {
11904                    r.task.stack.convertActivityToTranslucent(r);
11905                }
11906                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11907                mWindowManager.setAppFullscreen(token, false);
11908                return translucentChanged;
11909            }
11910        } finally {
11911            Binder.restoreCallingIdentity(origId);
11912        }
11913    }
11914
11915    @Override
11916    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11917        final long origId = Binder.clearCallingIdentity();
11918        try {
11919            synchronized (this) {
11920                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11921                if (r != null) {
11922                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11923                }
11924            }
11925            return false;
11926        } finally {
11927            Binder.restoreCallingIdentity(origId);
11928        }
11929    }
11930
11931    @Override
11932    public boolean isBackgroundVisibleBehind(IBinder token) {
11933        final long origId = Binder.clearCallingIdentity();
11934        try {
11935            synchronized (this) {
11936                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11937                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11938                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11939                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11940                return visible;
11941            }
11942        } finally {
11943            Binder.restoreCallingIdentity(origId);
11944        }
11945    }
11946
11947    @Override
11948    public ActivityOptions getActivityOptions(IBinder token) {
11949        final long origId = Binder.clearCallingIdentity();
11950        try {
11951            synchronized (this) {
11952                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11953                if (r != null) {
11954                    final ActivityOptions activityOptions = r.pendingOptions;
11955                    r.pendingOptions = null;
11956                    return activityOptions;
11957                }
11958                return null;
11959            }
11960        } finally {
11961            Binder.restoreCallingIdentity(origId);
11962        }
11963    }
11964
11965    @Override
11966    public void setImmersive(IBinder token, boolean immersive) {
11967        synchronized(this) {
11968            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11969            if (r == null) {
11970                throw new IllegalArgumentException();
11971            }
11972            r.immersive = immersive;
11973
11974            // update associated state if we're frontmost
11975            if (r == mFocusedActivity) {
11976                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11977                applyUpdateLockStateLocked(r);
11978            }
11979        }
11980    }
11981
11982    @Override
11983    public boolean isImmersive(IBinder token) {
11984        synchronized (this) {
11985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11986            if (r == null) {
11987                throw new IllegalArgumentException();
11988            }
11989            return r.immersive;
11990        }
11991    }
11992
11993    @Override
11994    public void setVrMode(IBinder token, boolean enabled) {
11995        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11996            throw new UnsupportedOperationException("VR mode not supported on this device!");
11997        }
11998
11999        synchronized(this) {
12000            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12001            if (r == null) {
12002                throw new IllegalArgumentException();
12003            }
12004            r.isVrActivity = enabled;
12005
12006            // Update associated state if this activity is currently focused
12007            if (r == mFocusedActivity) {
12008                applyUpdateVrModeLocked(r);
12009            }
12010        }
12011    }
12012
12013    public boolean isTopActivityImmersive() {
12014        enforceNotIsolatedCaller("startActivity");
12015        synchronized (this) {
12016            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12017            return (r != null) ? r.immersive : false;
12018        }
12019    }
12020
12021    @Override
12022    public boolean isTopOfTask(IBinder token) {
12023        synchronized (this) {
12024            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12025            if (r == null) {
12026                throw new IllegalArgumentException();
12027            }
12028            return r.task.getTopActivity() == r;
12029        }
12030    }
12031
12032    public final void enterSafeMode() {
12033        synchronized(this) {
12034            // It only makes sense to do this before the system is ready
12035            // and started launching other packages.
12036            if (!mSystemReady) {
12037                try {
12038                    AppGlobals.getPackageManager().enterSafeMode();
12039                } catch (RemoteException e) {
12040                }
12041            }
12042
12043            mSafeMode = true;
12044        }
12045    }
12046
12047    public final void showSafeModeOverlay() {
12048        View v = LayoutInflater.from(mContext).inflate(
12049                com.android.internal.R.layout.safe_mode, null);
12050        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12051        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12052        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12053        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12054        lp.gravity = Gravity.BOTTOM | Gravity.START;
12055        lp.format = v.getBackground().getOpacity();
12056        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12057                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12058        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12059        ((WindowManager)mContext.getSystemService(
12060                Context.WINDOW_SERVICE)).addView(v, lp);
12061    }
12062
12063    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12064        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12065            return;
12066        }
12067        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12068        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12069        synchronized (stats) {
12070            if (mBatteryStatsService.isOnBattery()) {
12071                mBatteryStatsService.enforceCallingPermission();
12072                int MY_UID = Binder.getCallingUid();
12073                final int uid;
12074                if (sender == null) {
12075                    uid = sourceUid;
12076                } else {
12077                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12078                }
12079                BatteryStatsImpl.Uid.Pkg pkg =
12080                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12081                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12082                pkg.noteWakeupAlarmLocked(tag);
12083            }
12084        }
12085    }
12086
12087    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12088        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12089            return;
12090        }
12091        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12092        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12093        synchronized (stats) {
12094            mBatteryStatsService.enforceCallingPermission();
12095            int MY_UID = Binder.getCallingUid();
12096            final int uid;
12097            if (sender == null) {
12098                uid = sourceUid;
12099            } else {
12100                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12101            }
12102            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12103        }
12104    }
12105
12106    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12107        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12108            return;
12109        }
12110        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12111        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12112        synchronized (stats) {
12113            mBatteryStatsService.enforceCallingPermission();
12114            int MY_UID = Binder.getCallingUid();
12115            final int uid;
12116            if (sender == null) {
12117                uid = sourceUid;
12118            } else {
12119                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12120            }
12121            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12122        }
12123    }
12124
12125    public boolean killPids(int[] pids, String pReason, boolean secure) {
12126        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12127            throw new SecurityException("killPids only available to the system");
12128        }
12129        String reason = (pReason == null) ? "Unknown" : pReason;
12130        // XXX Note: don't acquire main activity lock here, because the window
12131        // manager calls in with its locks held.
12132
12133        boolean killed = false;
12134        synchronized (mPidsSelfLocked) {
12135            int worstType = 0;
12136            for (int i=0; i<pids.length; i++) {
12137                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12138                if (proc != null) {
12139                    int type = proc.setAdj;
12140                    if (type > worstType) {
12141                        worstType = type;
12142                    }
12143                }
12144            }
12145
12146            // If the worst oom_adj is somewhere in the cached proc LRU range,
12147            // then constrain it so we will kill all cached procs.
12148            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12149                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12150                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12151            }
12152
12153            // If this is not a secure call, don't let it kill processes that
12154            // are important.
12155            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12156                worstType = ProcessList.SERVICE_ADJ;
12157            }
12158
12159            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12160            for (int i=0; i<pids.length; i++) {
12161                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12162                if (proc == null) {
12163                    continue;
12164                }
12165                int adj = proc.setAdj;
12166                if (adj >= worstType && !proc.killedByAm) {
12167                    proc.kill(reason, true);
12168                    killed = true;
12169                }
12170            }
12171        }
12172        return killed;
12173    }
12174
12175    @Override
12176    public void killUid(int appId, int userId, String reason) {
12177        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12178        synchronized (this) {
12179            final long identity = Binder.clearCallingIdentity();
12180            try {
12181                killPackageProcessesLocked(null, appId, userId,
12182                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12183                        reason != null ? reason : "kill uid");
12184            } finally {
12185                Binder.restoreCallingIdentity(identity);
12186            }
12187        }
12188    }
12189
12190    @Override
12191    public boolean killProcessesBelowForeground(String reason) {
12192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12193            throw new SecurityException("killProcessesBelowForeground() only available to system");
12194        }
12195
12196        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12197    }
12198
12199    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12200        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12201            throw new SecurityException("killProcessesBelowAdj() only available to system");
12202        }
12203
12204        boolean killed = false;
12205        synchronized (mPidsSelfLocked) {
12206            final int size = mPidsSelfLocked.size();
12207            for (int i = 0; i < size; i++) {
12208                final int pid = mPidsSelfLocked.keyAt(i);
12209                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12210                if (proc == null) continue;
12211
12212                final int adj = proc.setAdj;
12213                if (adj > belowAdj && !proc.killedByAm) {
12214                    proc.kill(reason, true);
12215                    killed = true;
12216                }
12217            }
12218        }
12219        return killed;
12220    }
12221
12222    @Override
12223    public void hang(final IBinder who, boolean allowRestart) {
12224        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12225                != PackageManager.PERMISSION_GRANTED) {
12226            throw new SecurityException("Requires permission "
12227                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12228        }
12229
12230        final IBinder.DeathRecipient death = new DeathRecipient() {
12231            @Override
12232            public void binderDied() {
12233                synchronized (this) {
12234                    notifyAll();
12235                }
12236            }
12237        };
12238
12239        try {
12240            who.linkToDeath(death, 0);
12241        } catch (RemoteException e) {
12242            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12243            return;
12244        }
12245
12246        synchronized (this) {
12247            Watchdog.getInstance().setAllowRestart(allowRestart);
12248            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12249            synchronized (death) {
12250                while (who.isBinderAlive()) {
12251                    try {
12252                        death.wait();
12253                    } catch (InterruptedException e) {
12254                    }
12255                }
12256            }
12257            Watchdog.getInstance().setAllowRestart(true);
12258        }
12259    }
12260
12261    @Override
12262    public void restart() {
12263        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12264                != PackageManager.PERMISSION_GRANTED) {
12265            throw new SecurityException("Requires permission "
12266                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12267        }
12268
12269        Log.i(TAG, "Sending shutdown broadcast...");
12270
12271        BroadcastReceiver br = new BroadcastReceiver() {
12272            @Override public void onReceive(Context context, Intent intent) {
12273                // Now the broadcast is done, finish up the low-level shutdown.
12274                Log.i(TAG, "Shutting down activity manager...");
12275                shutdown(10000);
12276                Log.i(TAG, "Shutdown complete, restarting!");
12277                Process.killProcess(Process.myPid());
12278                System.exit(10);
12279            }
12280        };
12281
12282        // First send the high-level shut down broadcast.
12283        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12284        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12285        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12286        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12287        mContext.sendOrderedBroadcastAsUser(intent,
12288                UserHandle.ALL, null, br, mHandler, 0, null, null);
12289        */
12290        br.onReceive(mContext, intent);
12291    }
12292
12293    private long getLowRamTimeSinceIdle(long now) {
12294        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12295    }
12296
12297    @Override
12298    public void performIdleMaintenance() {
12299        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12300                != PackageManager.PERMISSION_GRANTED) {
12301            throw new SecurityException("Requires permission "
12302                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12303        }
12304
12305        synchronized (this) {
12306            final long now = SystemClock.uptimeMillis();
12307            final long timeSinceLastIdle = now - mLastIdleTime;
12308            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12309            mLastIdleTime = now;
12310            mLowRamTimeSinceLastIdle = 0;
12311            if (mLowRamStartTime != 0) {
12312                mLowRamStartTime = now;
12313            }
12314
12315            StringBuilder sb = new StringBuilder(128);
12316            sb.append("Idle maintenance over ");
12317            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12318            sb.append(" low RAM for ");
12319            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12320            Slog.i(TAG, sb.toString());
12321
12322            // If at least 1/3 of our time since the last idle period has been spent
12323            // with RAM low, then we want to kill processes.
12324            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12325
12326            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12327                ProcessRecord proc = mLruProcesses.get(i);
12328                if (proc.notCachedSinceIdle) {
12329                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12330                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12331                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12332                        if (doKilling && proc.initialIdlePss != 0
12333                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12334                            sb = new StringBuilder(128);
12335                            sb.append("Kill");
12336                            sb.append(proc.processName);
12337                            sb.append(" in idle maint: pss=");
12338                            sb.append(proc.lastPss);
12339                            sb.append(", swapPss=");
12340                            sb.append(proc.lastSwapPss);
12341                            sb.append(", initialPss=");
12342                            sb.append(proc.initialIdlePss);
12343                            sb.append(", period=");
12344                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12345                            sb.append(", lowRamPeriod=");
12346                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12347                            Slog.wtfQuiet(TAG, sb.toString());
12348                            proc.kill("idle maint (pss " + proc.lastPss
12349                                    + " from " + proc.initialIdlePss + ")", true);
12350                        }
12351                    }
12352                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12353                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12354                    proc.notCachedSinceIdle = true;
12355                    proc.initialIdlePss = 0;
12356                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12357                            mTestPssMode, isSleeping(), now);
12358                }
12359            }
12360
12361            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12362            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12363        }
12364    }
12365
12366    private void retrieveSettings() {
12367        final ContentResolver resolver = mContext.getContentResolver();
12368        final boolean freeformWindowManagement =
12369                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12370                        || Settings.Global.getInt(
12371                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12372        final boolean supportsPictureInPicture =
12373                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12374
12375        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12376        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12377        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12378        final boolean alwaysFinishActivities =
12379                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12380        final boolean lenientBackgroundCheck =
12381                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12382        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12383        final boolean forceResizable = Settings.Global.getInt(
12384                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12385        // Transfer any global setting for forcing RTL layout, into a System Property
12386        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12387
12388        final Configuration configuration = new Configuration();
12389        Settings.System.getConfiguration(resolver, configuration);
12390        if (forceRtl) {
12391            // This will take care of setting the correct layout direction flags
12392            configuration.setLayoutDirection(configuration.locale);
12393        }
12394
12395        synchronized (this) {
12396            mDebugApp = mOrigDebugApp = debugApp;
12397            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12398            mAlwaysFinishActivities = alwaysFinishActivities;
12399            mLenientBackgroundCheck = lenientBackgroundCheck;
12400            mForceResizableActivities = forceResizable;
12401            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12402            if (supportsMultiWindow || forceResizable) {
12403                mSupportsMultiWindow = true;
12404                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12405                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12406            } else {
12407                mSupportsMultiWindow = false;
12408                mSupportsFreeformWindowManagement = false;
12409                mSupportsPictureInPicture = false;
12410            }
12411            // This happens before any activities are started, so we can
12412            // change mConfiguration in-place.
12413            updateConfigurationLocked(configuration, null, true);
12414            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12415                    "Initial config: " + mConfiguration);
12416
12417            // Load resources only after the current configuration has been set.
12418            final Resources res = mContext.getResources();
12419            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12420            mThumbnailWidth = res.getDimensionPixelSize(
12421                    com.android.internal.R.dimen.thumbnail_width);
12422            mThumbnailHeight = res.getDimensionPixelSize(
12423                    com.android.internal.R.dimen.thumbnail_height);
12424            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12425                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12426            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12427                    com.android.internal.R.string.config_appsNotReportingCrashes));
12428        }
12429    }
12430
12431    public boolean testIsSystemReady() {
12432        // no need to synchronize(this) just to read & return the value
12433        return mSystemReady;
12434    }
12435
12436    private static File getCalledPreBootReceiversFile() {
12437        File dataDir = Environment.getDataDirectory();
12438        File systemDir = new File(dataDir, "system");
12439        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12440        return fname;
12441    }
12442
12443    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12444        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12445        File file = getCalledPreBootReceiversFile();
12446        FileInputStream fis = null;
12447        try {
12448            fis = new FileInputStream(file);
12449            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12450            int fvers = dis.readInt();
12451            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12452                String vers = dis.readUTF();
12453                String codename = dis.readUTF();
12454                String build = dis.readUTF();
12455                if (android.os.Build.VERSION.RELEASE.equals(vers)
12456                        && android.os.Build.VERSION.CODENAME.equals(codename)
12457                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12458                    int num = dis.readInt();
12459                    while (num > 0) {
12460                        num--;
12461                        String pkg = dis.readUTF();
12462                        String cls = dis.readUTF();
12463                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12464                    }
12465                }
12466            }
12467        } catch (FileNotFoundException e) {
12468        } catch (IOException e) {
12469            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12470        } finally {
12471            if (fis != null) {
12472                try {
12473                    fis.close();
12474                } catch (IOException e) {
12475                }
12476            }
12477        }
12478        return lastDoneReceivers;
12479    }
12480
12481    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12482        File file = getCalledPreBootReceiversFile();
12483        FileOutputStream fos = null;
12484        DataOutputStream dos = null;
12485        try {
12486            fos = new FileOutputStream(file);
12487            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12488            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12489            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12490            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12491            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12492            dos.writeInt(list.size());
12493            for (int i=0; i<list.size(); i++) {
12494                dos.writeUTF(list.get(i).getPackageName());
12495                dos.writeUTF(list.get(i).getClassName());
12496            }
12497        } catch (IOException e) {
12498            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12499            file.delete();
12500        } finally {
12501            FileUtils.sync(fos);
12502            if (dos != null) {
12503                try {
12504                    dos.close();
12505                } catch (IOException e) {
12506                    // TODO Auto-generated catch block
12507                    e.printStackTrace();
12508                }
12509            }
12510        }
12511    }
12512
12513    final class PreBootContinuation extends IIntentReceiver.Stub {
12514        final Intent intent;
12515        final Runnable onFinishCallback;
12516        final ArrayList<ComponentName> doneReceivers;
12517        final List<ResolveInfo> ris;
12518        final int[] users;
12519        int lastRi = -1;
12520        int curRi = 0;
12521        int curUser = 0;
12522
12523        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12524                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12525            intent = _intent;
12526            onFinishCallback = _onFinishCallback;
12527            doneReceivers = _doneReceivers;
12528            ris = _ris;
12529            users = _users;
12530        }
12531
12532        void go() {
12533            if (lastRi != curRi) {
12534                ActivityInfo ai = ris.get(curRi).activityInfo;
12535                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12536                intent.setComponent(comp);
12537                doneReceivers.add(comp);
12538                lastRi = curRi;
12539                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12540                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12541            }
12542            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12543                    + " for user " + users[curUser]);
12544            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12545            broadcastIntentLocked(null, null, intent, null, this,
12546                    0, null, null, null, AppOpsManager.OP_NONE,
12547                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12548        }
12549
12550        public void performReceive(Intent intent, int resultCode,
12551                String data, Bundle extras, boolean ordered,
12552                boolean sticky, int sendingUser) {
12553            curUser++;
12554            if (curUser >= users.length) {
12555                curUser = 0;
12556                curRi++;
12557                if (curRi >= ris.size()) {
12558                    // All done sending broadcasts!
12559                    if (onFinishCallback != null) {
12560                        // The raw IIntentReceiver interface is called
12561                        // with the AM lock held, so redispatch to
12562                        // execute our code without the lock.
12563                        mHandler.post(onFinishCallback);
12564                    }
12565                    return;
12566                }
12567            }
12568            go();
12569        }
12570    }
12571
12572    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12573            ArrayList<ComponentName> doneReceivers) {
12574        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12575        List<ResolveInfo> ris = null;
12576        try {
12577            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12578                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12579        } catch (RemoteException e) {
12580        }
12581        if (ris == null) {
12582            return false;
12583        }
12584        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12585
12586        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12587        for (int i=0; i<ris.size(); i++) {
12588            ActivityInfo ai = ris.get(i).activityInfo;
12589            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12590            if (lastDoneReceivers.contains(comp)) {
12591                // We already did the pre boot receiver for this app with the current
12592                // platform version, so don't do it again...
12593                ris.remove(i);
12594                i--;
12595                // ...however, do keep it as one that has been done, so we don't
12596                // forget about it when rewriting the file of last done receivers.
12597                doneReceivers.add(comp);
12598            }
12599        }
12600
12601        if (ris.size() <= 0) {
12602            return false;
12603        }
12604
12605        // TODO: can we still do this with per user encryption?
12606        final int[] users = mUserController.getUsers();
12607        if (users.length <= 0) {
12608            return false;
12609        }
12610
12611        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12612                ris, users);
12613        cont.go();
12614        return true;
12615    }
12616
12617    public void systemReady(final Runnable goingCallback) {
12618        synchronized(this) {
12619            if (mSystemReady) {
12620                // If we're done calling all the receivers, run the next "boot phase" passed in
12621                // by the SystemServer
12622                if (goingCallback != null) {
12623                    goingCallback.run();
12624                }
12625                return;
12626            }
12627
12628            mLocalDeviceIdleController
12629                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12630
12631            // Make sure we have the current profile info, since it is needed for security checks.
12632            mUserController.onSystemReady();
12633
12634            mRecentTasks.onSystemReadyLocked();
12635            // Check to see if there are any update receivers to run.
12636            if (!mDidUpdate) {
12637                if (mWaitingUpdate) {
12638                    return;
12639                }
12640                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12641                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12642                    public void run() {
12643                        synchronized (ActivityManagerService.this) {
12644                            mDidUpdate = true;
12645                        }
12646                        showBootMessage(mContext.getText(
12647                                R.string.android_upgrading_complete),
12648                                false);
12649                        writeLastDonePreBootReceivers(doneReceivers);
12650                        systemReady(goingCallback);
12651                    }
12652                }, doneReceivers);
12653
12654                if (mWaitingUpdate) {
12655                    return;
12656                }
12657                mDidUpdate = true;
12658            }
12659
12660            mAppOpsService.systemReady();
12661            mSystemReady = true;
12662        }
12663
12664        ArrayList<ProcessRecord> procsToKill = null;
12665        synchronized(mPidsSelfLocked) {
12666            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12667                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12668                if (!isAllowedWhileBooting(proc.info)){
12669                    if (procsToKill == null) {
12670                        procsToKill = new ArrayList<ProcessRecord>();
12671                    }
12672                    procsToKill.add(proc);
12673                }
12674            }
12675        }
12676
12677        synchronized(this) {
12678            if (procsToKill != null) {
12679                for (int i=procsToKill.size()-1; i>=0; i--) {
12680                    ProcessRecord proc = procsToKill.get(i);
12681                    Slog.i(TAG, "Removing system update proc: " + proc);
12682                    removeProcessLocked(proc, true, false, "system update done");
12683                }
12684            }
12685
12686            // Now that we have cleaned up any update processes, we
12687            // are ready to start launching real processes and know that
12688            // we won't trample on them any more.
12689            mProcessesReady = true;
12690        }
12691
12692        Slog.i(TAG, "System now ready");
12693        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12694            SystemClock.uptimeMillis());
12695
12696        synchronized(this) {
12697            // Make sure we have no pre-ready processes sitting around.
12698
12699            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12700                ResolveInfo ri = mContext.getPackageManager()
12701                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12702                                STOCK_PM_FLAGS);
12703                CharSequence errorMsg = null;
12704                if (ri != null) {
12705                    ActivityInfo ai = ri.activityInfo;
12706                    ApplicationInfo app = ai.applicationInfo;
12707                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12708                        mTopAction = Intent.ACTION_FACTORY_TEST;
12709                        mTopData = null;
12710                        mTopComponent = new ComponentName(app.packageName,
12711                                ai.name);
12712                    } else {
12713                        errorMsg = mContext.getResources().getText(
12714                                com.android.internal.R.string.factorytest_not_system);
12715                    }
12716                } else {
12717                    errorMsg = mContext.getResources().getText(
12718                            com.android.internal.R.string.factorytest_no_action);
12719                }
12720                if (errorMsg != null) {
12721                    mTopAction = null;
12722                    mTopData = null;
12723                    mTopComponent = null;
12724                    Message msg = Message.obtain();
12725                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12726                    msg.getData().putCharSequence("msg", errorMsg);
12727                    mUiHandler.sendMessage(msg);
12728                }
12729            }
12730        }
12731
12732        retrieveSettings();
12733        final int currentUserId;
12734        synchronized (this) {
12735            currentUserId = mUserController.getCurrentUserIdLocked();
12736            readGrantedUriPermissionsLocked();
12737        }
12738
12739        if (goingCallback != null) goingCallback.run();
12740
12741        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12742                Integer.toString(currentUserId), currentUserId);
12743        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12744                Integer.toString(currentUserId), currentUserId);
12745        mSystemServiceManager.startUser(currentUserId);
12746
12747        synchronized (this) {
12748            // Only start up encryption-aware persistent apps; once user is
12749            // unlocked we'll come back around and start unaware apps
12750            startPersistentApps(PackageManager.MATCH_ENCRYPTION_AWARE);
12751
12752            // Start up initial activity.
12753            mBooting = true;
12754            // Enable home activity for system user, so that the system can always boot
12755            if (UserManager.isSplitSystemUser()) {
12756                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12757                try {
12758                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12759                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12760                            UserHandle.USER_SYSTEM);
12761                } catch (RemoteException e) {
12762                    throw e.rethrowAsRuntimeException();
12763                }
12764            }
12765            startHomeActivityLocked(currentUserId, "systemReady");
12766
12767            try {
12768                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12769                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12770                            + " data partition or your device will be unstable.");
12771                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12772                }
12773            } catch (RemoteException e) {
12774            }
12775
12776            if (!Build.isBuildConsistent()) {
12777                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12778                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12779            }
12780
12781            long ident = Binder.clearCallingIdentity();
12782            try {
12783                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12784                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12785                        | Intent.FLAG_RECEIVER_FOREGROUND);
12786                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12787                broadcastIntentLocked(null, null, intent,
12788                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12789                        null, false, false, MY_PID, Process.SYSTEM_UID,
12790                        currentUserId);
12791                intent = new Intent(Intent.ACTION_USER_STARTING);
12792                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12793                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12794                broadcastIntentLocked(null, null, intent,
12795                        null, new IIntentReceiver.Stub() {
12796                            @Override
12797                            public void performReceive(Intent intent, int resultCode, String data,
12798                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12799                                    throws RemoteException {
12800                            }
12801                        }, 0, null, null,
12802                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12803                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12804            } catch (Throwable t) {
12805                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12806            } finally {
12807                Binder.restoreCallingIdentity(ident);
12808            }
12809            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12810            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12811        }
12812    }
12813
12814    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12815        synchronized (this) {
12816            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12817        }
12818    }
12819
12820    void skipCurrentReceiverLocked(ProcessRecord app) {
12821        for (BroadcastQueue queue : mBroadcastQueues) {
12822            queue.skipCurrentReceiverLocked(app);
12823        }
12824    }
12825
12826    /**
12827     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12828     * The application process will exit immediately after this call returns.
12829     * @param app object of the crashing app, null for the system server
12830     * @param crashInfo describing the exception
12831     */
12832    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12833        ProcessRecord r = findAppProcess(app, "Crash");
12834        final String processName = app == null ? "system_server"
12835                : (r == null ? "unknown" : r.processName);
12836
12837        handleApplicationCrashInner("crash", r, processName, crashInfo);
12838    }
12839
12840    /* Native crash reporting uses this inner version because it needs to be somewhat
12841     * decoupled from the AM-managed cleanup lifecycle
12842     */
12843    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12844            ApplicationErrorReport.CrashInfo crashInfo) {
12845        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12846                UserHandle.getUserId(Binder.getCallingUid()), processName,
12847                r == null ? -1 : r.info.flags,
12848                crashInfo.exceptionClassName,
12849                crashInfo.exceptionMessage,
12850                crashInfo.throwFileName,
12851                crashInfo.throwLineNumber);
12852
12853        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12854
12855        mAppErrors.crashApplication(r, crashInfo);
12856    }
12857
12858    public void handleApplicationStrictModeViolation(
12859            IBinder app,
12860            int violationMask,
12861            StrictMode.ViolationInfo info) {
12862        ProcessRecord r = findAppProcess(app, "StrictMode");
12863        if (r == null) {
12864            return;
12865        }
12866
12867        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12868            Integer stackFingerprint = info.hashCode();
12869            boolean logIt = true;
12870            synchronized (mAlreadyLoggedViolatedStacks) {
12871                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12872                    logIt = false;
12873                    // TODO: sub-sample into EventLog for these, with
12874                    // the info.durationMillis?  Then we'd get
12875                    // the relative pain numbers, without logging all
12876                    // the stack traces repeatedly.  We'd want to do
12877                    // likewise in the client code, which also does
12878                    // dup suppression, before the Binder call.
12879                } else {
12880                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12881                        mAlreadyLoggedViolatedStacks.clear();
12882                    }
12883                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12884                }
12885            }
12886            if (logIt) {
12887                logStrictModeViolationToDropBox(r, info);
12888            }
12889        }
12890
12891        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12892            AppErrorResult result = new AppErrorResult();
12893            synchronized (this) {
12894                final long origId = Binder.clearCallingIdentity();
12895
12896                Message msg = Message.obtain();
12897                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12898                HashMap<String, Object> data = new HashMap<String, Object>();
12899                data.put("result", result);
12900                data.put("app", r);
12901                data.put("violationMask", violationMask);
12902                data.put("info", info);
12903                msg.obj = data;
12904                mUiHandler.sendMessage(msg);
12905
12906                Binder.restoreCallingIdentity(origId);
12907            }
12908            int res = result.get();
12909            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12910        }
12911    }
12912
12913    // Depending on the policy in effect, there could be a bunch of
12914    // these in quick succession so we try to batch these together to
12915    // minimize disk writes, number of dropbox entries, and maximize
12916    // compression, by having more fewer, larger records.
12917    private void logStrictModeViolationToDropBox(
12918            ProcessRecord process,
12919            StrictMode.ViolationInfo info) {
12920        if (info == null) {
12921            return;
12922        }
12923        final boolean isSystemApp = process == null ||
12924                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12925                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12926        final String processName = process == null ? "unknown" : process.processName;
12927        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12928        final DropBoxManager dbox = (DropBoxManager)
12929                mContext.getSystemService(Context.DROPBOX_SERVICE);
12930
12931        // Exit early if the dropbox isn't configured to accept this report type.
12932        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12933
12934        boolean bufferWasEmpty;
12935        boolean needsFlush;
12936        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12937        synchronized (sb) {
12938            bufferWasEmpty = sb.length() == 0;
12939            appendDropBoxProcessHeaders(process, processName, sb);
12940            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12941            sb.append("System-App: ").append(isSystemApp).append("\n");
12942            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12943            if (info.violationNumThisLoop != 0) {
12944                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12945            }
12946            if (info.numAnimationsRunning != 0) {
12947                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12948            }
12949            if (info.broadcastIntentAction != null) {
12950                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12951            }
12952            if (info.durationMillis != -1) {
12953                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12954            }
12955            if (info.numInstances != -1) {
12956                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12957            }
12958            if (info.tags != null) {
12959                for (String tag : info.tags) {
12960                    sb.append("Span-Tag: ").append(tag).append("\n");
12961                }
12962            }
12963            sb.append("\n");
12964            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12965                sb.append(info.crashInfo.stackTrace);
12966                sb.append("\n");
12967            }
12968            if (info.message != null) {
12969                sb.append(info.message);
12970                sb.append("\n");
12971            }
12972
12973            // Only buffer up to ~64k.  Various logging bits truncate
12974            // things at 128k.
12975            needsFlush = (sb.length() > 64 * 1024);
12976        }
12977
12978        // Flush immediately if the buffer's grown too large, or this
12979        // is a non-system app.  Non-system apps are isolated with a
12980        // different tag & policy and not batched.
12981        //
12982        // Batching is useful during internal testing with
12983        // StrictMode settings turned up high.  Without batching,
12984        // thousands of separate files could be created on boot.
12985        if (!isSystemApp || needsFlush) {
12986            new Thread("Error dump: " + dropboxTag) {
12987                @Override
12988                public void run() {
12989                    String report;
12990                    synchronized (sb) {
12991                        report = sb.toString();
12992                        sb.delete(0, sb.length());
12993                        sb.trimToSize();
12994                    }
12995                    if (report.length() != 0) {
12996                        dbox.addText(dropboxTag, report);
12997                    }
12998                }
12999            }.start();
13000            return;
13001        }
13002
13003        // System app batching:
13004        if (!bufferWasEmpty) {
13005            // An existing dropbox-writing thread is outstanding, so
13006            // we don't need to start it up.  The existing thread will
13007            // catch the buffer appends we just did.
13008            return;
13009        }
13010
13011        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13012        // (After this point, we shouldn't access AMS internal data structures.)
13013        new Thread("Error dump: " + dropboxTag) {
13014            @Override
13015            public void run() {
13016                // 5 second sleep to let stacks arrive and be batched together
13017                try {
13018                    Thread.sleep(5000);  // 5 seconds
13019                } catch (InterruptedException e) {}
13020
13021                String errorReport;
13022                synchronized (mStrictModeBuffer) {
13023                    errorReport = mStrictModeBuffer.toString();
13024                    if (errorReport.length() == 0) {
13025                        return;
13026                    }
13027                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13028                    mStrictModeBuffer.trimToSize();
13029                }
13030                dbox.addText(dropboxTag, errorReport);
13031            }
13032        }.start();
13033    }
13034
13035    /**
13036     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13037     * @param app object of the crashing app, null for the system server
13038     * @param tag reported by the caller
13039     * @param system whether this wtf is coming from the system
13040     * @param crashInfo describing the context of the error
13041     * @return true if the process should exit immediately (WTF is fatal)
13042     */
13043    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13044            final ApplicationErrorReport.CrashInfo crashInfo) {
13045        final int callingUid = Binder.getCallingUid();
13046        final int callingPid = Binder.getCallingPid();
13047
13048        if (system) {
13049            // If this is coming from the system, we could very well have low-level
13050            // system locks held, so we want to do this all asynchronously.  And we
13051            // never want this to become fatal, so there is that too.
13052            mHandler.post(new Runnable() {
13053                @Override public void run() {
13054                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13055                }
13056            });
13057            return false;
13058        }
13059
13060        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13061                crashInfo);
13062
13063        if (r != null && r.pid != Process.myPid() &&
13064                Settings.Global.getInt(mContext.getContentResolver(),
13065                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13066            mAppErrors.crashApplication(r, crashInfo);
13067            return true;
13068        } else {
13069            return false;
13070        }
13071    }
13072
13073    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13074            final ApplicationErrorReport.CrashInfo crashInfo) {
13075        final ProcessRecord r = findAppProcess(app, "WTF");
13076        final String processName = app == null ? "system_server"
13077                : (r == null ? "unknown" : r.processName);
13078
13079        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13080                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13081
13082        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13083
13084        return r;
13085    }
13086
13087    /**
13088     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13089     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13090     */
13091    private ProcessRecord findAppProcess(IBinder app, String reason) {
13092        if (app == null) {
13093            return null;
13094        }
13095
13096        synchronized (this) {
13097            final int NP = mProcessNames.getMap().size();
13098            for (int ip=0; ip<NP; ip++) {
13099                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13100                final int NA = apps.size();
13101                for (int ia=0; ia<NA; ia++) {
13102                    ProcessRecord p = apps.valueAt(ia);
13103                    if (p.thread != null && p.thread.asBinder() == app) {
13104                        return p;
13105                    }
13106                }
13107            }
13108
13109            Slog.w(TAG, "Can't find mystery application for " + reason
13110                    + " from pid=" + Binder.getCallingPid()
13111                    + " uid=" + Binder.getCallingUid() + ": " + app);
13112            return null;
13113        }
13114    }
13115
13116    /**
13117     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13118     * to append various headers to the dropbox log text.
13119     */
13120    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13121            StringBuilder sb) {
13122        // Watchdog thread ends up invoking this function (with
13123        // a null ProcessRecord) to add the stack file to dropbox.
13124        // Do not acquire a lock on this (am) in such cases, as it
13125        // could cause a potential deadlock, if and when watchdog
13126        // is invoked due to unavailability of lock on am and it
13127        // would prevent watchdog from killing system_server.
13128        if (process == null) {
13129            sb.append("Process: ").append(processName).append("\n");
13130            return;
13131        }
13132        // Note: ProcessRecord 'process' is guarded by the service
13133        // instance.  (notably process.pkgList, which could otherwise change
13134        // concurrently during execution of this method)
13135        synchronized (this) {
13136            sb.append("Process: ").append(processName).append("\n");
13137            int flags = process.info.flags;
13138            IPackageManager pm = AppGlobals.getPackageManager();
13139            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13140            for (int ip=0; ip<process.pkgList.size(); ip++) {
13141                String pkg = process.pkgList.keyAt(ip);
13142                sb.append("Package: ").append(pkg);
13143                try {
13144                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13145                    if (pi != null) {
13146                        sb.append(" v").append(pi.versionCode);
13147                        if (pi.versionName != null) {
13148                            sb.append(" (").append(pi.versionName).append(")");
13149                        }
13150                    }
13151                } catch (RemoteException e) {
13152                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13153                }
13154                sb.append("\n");
13155            }
13156        }
13157    }
13158
13159    private static String processClass(ProcessRecord process) {
13160        if (process == null || process.pid == MY_PID) {
13161            return "system_server";
13162        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13163            return "system_app";
13164        } else {
13165            return "data_app";
13166        }
13167    }
13168
13169    /**
13170     * Write a description of an error (crash, WTF, ANR) to the drop box.
13171     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13172     * @param process which caused the error, null means the system server
13173     * @param activity which triggered the error, null if unknown
13174     * @param parent activity related to the error, null if unknown
13175     * @param subject line related to the error, null if absent
13176     * @param report in long form describing the error, null if absent
13177     * @param logFile to include in the report, null if none
13178     * @param crashInfo giving an application stack trace, null if absent
13179     */
13180    public void addErrorToDropBox(String eventType,
13181            ProcessRecord process, String processName, ActivityRecord activity,
13182            ActivityRecord parent, String subject,
13183            final String report, final File logFile,
13184            final ApplicationErrorReport.CrashInfo crashInfo) {
13185        // NOTE -- this must never acquire the ActivityManagerService lock,
13186        // otherwise the watchdog may be prevented from resetting the system.
13187
13188        final String dropboxTag = processClass(process) + "_" + eventType;
13189        final DropBoxManager dbox = (DropBoxManager)
13190                mContext.getSystemService(Context.DROPBOX_SERVICE);
13191
13192        // Exit early if the dropbox isn't configured to accept this report type.
13193        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13194
13195        final StringBuilder sb = new StringBuilder(1024);
13196        appendDropBoxProcessHeaders(process, processName, sb);
13197        if (process != null) {
13198            sb.append("Foreground: ")
13199                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13200                    .append("\n");
13201        }
13202        if (activity != null) {
13203            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13204        }
13205        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13206            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13207        }
13208        if (parent != null && parent != activity) {
13209            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13210        }
13211        if (subject != null) {
13212            sb.append("Subject: ").append(subject).append("\n");
13213        }
13214        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13215        if (Debug.isDebuggerConnected()) {
13216            sb.append("Debugger: Connected\n");
13217        }
13218        sb.append("\n");
13219
13220        // Do the rest in a worker thread to avoid blocking the caller on I/O
13221        // (After this point, we shouldn't access AMS internal data structures.)
13222        Thread worker = new Thread("Error dump: " + dropboxTag) {
13223            @Override
13224            public void run() {
13225                if (report != null) {
13226                    sb.append(report);
13227                }
13228                if (logFile != null) {
13229                    try {
13230                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13231                                    "\n\n[[TRUNCATED]]"));
13232                    } catch (IOException e) {
13233                        Slog.e(TAG, "Error reading " + logFile, e);
13234                    }
13235                }
13236                if (crashInfo != null && crashInfo.stackTrace != null) {
13237                    sb.append(crashInfo.stackTrace);
13238                }
13239
13240                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13241                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13242                if (lines > 0) {
13243                    sb.append("\n");
13244
13245                    // Merge several logcat streams, and take the last N lines
13246                    InputStreamReader input = null;
13247                    try {
13248                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13249                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13250                                "-b", "crash",
13251                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13252
13253                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13254                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13255                        input = new InputStreamReader(logcat.getInputStream());
13256
13257                        int num;
13258                        char[] buf = new char[8192];
13259                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13260                    } catch (IOException e) {
13261                        Slog.e(TAG, "Error running logcat", e);
13262                    } finally {
13263                        if (input != null) try { input.close(); } catch (IOException e) {}
13264                    }
13265                }
13266
13267                dbox.addText(dropboxTag, sb.toString());
13268            }
13269        };
13270
13271        if (process == null) {
13272            // If process is null, we are being called from some internal code
13273            // and may be about to die -- run this synchronously.
13274            worker.run();
13275        } else {
13276            worker.start();
13277        }
13278    }
13279
13280    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13281        enforceNotIsolatedCaller("getProcessesInErrorState");
13282        // assume our apps are happy - lazy create the list
13283        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13284
13285        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13286                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13287        int userId = UserHandle.getUserId(Binder.getCallingUid());
13288
13289        synchronized (this) {
13290
13291            // iterate across all processes
13292            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13293                ProcessRecord app = mLruProcesses.get(i);
13294                if (!allUsers && app.userId != userId) {
13295                    continue;
13296                }
13297                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13298                    // This one's in trouble, so we'll generate a report for it
13299                    // crashes are higher priority (in case there's a crash *and* an anr)
13300                    ActivityManager.ProcessErrorStateInfo report = null;
13301                    if (app.crashing) {
13302                        report = app.crashingReport;
13303                    } else if (app.notResponding) {
13304                        report = app.notRespondingReport;
13305                    }
13306
13307                    if (report != null) {
13308                        if (errList == null) {
13309                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13310                        }
13311                        errList.add(report);
13312                    } else {
13313                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13314                                " crashing = " + app.crashing +
13315                                " notResponding = " + app.notResponding);
13316                    }
13317                }
13318            }
13319        }
13320
13321        return errList;
13322    }
13323
13324    static int procStateToImportance(int procState, int memAdj,
13325            ActivityManager.RunningAppProcessInfo currApp) {
13326        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13327        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13328            currApp.lru = memAdj;
13329        } else {
13330            currApp.lru = 0;
13331        }
13332        return imp;
13333    }
13334
13335    private void fillInProcMemInfo(ProcessRecord app,
13336            ActivityManager.RunningAppProcessInfo outInfo) {
13337        outInfo.pid = app.pid;
13338        outInfo.uid = app.info.uid;
13339        if (mHeavyWeightProcess == app) {
13340            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13341        }
13342        if (app.persistent) {
13343            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13344        }
13345        if (app.activities.size() > 0) {
13346            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13347        }
13348        outInfo.lastTrimLevel = app.trimMemoryLevel;
13349        int adj = app.curAdj;
13350        int procState = app.curProcState;
13351        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13352        outInfo.importanceReasonCode = app.adjTypeCode;
13353        outInfo.processState = app.curProcState;
13354    }
13355
13356    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13357        enforceNotIsolatedCaller("getRunningAppProcesses");
13358
13359        final int callingUid = Binder.getCallingUid();
13360
13361        // Lazy instantiation of list
13362        List<ActivityManager.RunningAppProcessInfo> runList = null;
13363        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13364                callingUid) == PackageManager.PERMISSION_GRANTED;
13365        final int userId = UserHandle.getUserId(callingUid);
13366        final boolean allUids = isGetTasksAllowed(
13367                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13368
13369        synchronized (this) {
13370            // Iterate across all processes
13371            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13372                ProcessRecord app = mLruProcesses.get(i);
13373                if ((!allUsers && app.userId != userId)
13374                        || (!allUids && app.uid != callingUid)) {
13375                    continue;
13376                }
13377                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13378                    // Generate process state info for running application
13379                    ActivityManager.RunningAppProcessInfo currApp =
13380                        new ActivityManager.RunningAppProcessInfo(app.processName,
13381                                app.pid, app.getPackageList());
13382                    fillInProcMemInfo(app, currApp);
13383                    if (app.adjSource instanceof ProcessRecord) {
13384                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13385                        currApp.importanceReasonImportance =
13386                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13387                                        app.adjSourceProcState);
13388                    } else if (app.adjSource instanceof ActivityRecord) {
13389                        ActivityRecord r = (ActivityRecord)app.adjSource;
13390                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13391                    }
13392                    if (app.adjTarget instanceof ComponentName) {
13393                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13394                    }
13395                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13396                    //        + " lru=" + currApp.lru);
13397                    if (runList == null) {
13398                        runList = new ArrayList<>();
13399                    }
13400                    runList.add(currApp);
13401                }
13402            }
13403        }
13404        return runList;
13405    }
13406
13407    public List<ApplicationInfo> getRunningExternalApplications() {
13408        enforceNotIsolatedCaller("getRunningExternalApplications");
13409        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13410        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13411        if (runningApps != null && runningApps.size() > 0) {
13412            Set<String> extList = new HashSet<String>();
13413            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13414                if (app.pkgList != null) {
13415                    for (String pkg : app.pkgList) {
13416                        extList.add(pkg);
13417                    }
13418                }
13419            }
13420            IPackageManager pm = AppGlobals.getPackageManager();
13421            for (String pkg : extList) {
13422                try {
13423                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13424                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13425                        retList.add(info);
13426                    }
13427                } catch (RemoteException e) {
13428                }
13429            }
13430        }
13431        return retList;
13432    }
13433
13434    @Override
13435    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13436        enforceNotIsolatedCaller("getMyMemoryState");
13437        synchronized (this) {
13438            ProcessRecord proc;
13439            synchronized (mPidsSelfLocked) {
13440                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13441            }
13442            fillInProcMemInfo(proc, outInfo);
13443        }
13444    }
13445
13446    @Override
13447    public int getMemoryTrimLevel() {
13448        enforceNotIsolatedCaller("getMyMemoryState");
13449        synchronized (this) {
13450            return mLastMemoryLevel;
13451        }
13452    }
13453
13454    @Override
13455    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13456            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13457        (new ActivityManagerShellCommand(this, false)).exec(
13458                this, in, out, err, args, resultReceiver);
13459    }
13460
13461    @Override
13462    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13463        if (checkCallingPermission(android.Manifest.permission.DUMP)
13464                != PackageManager.PERMISSION_GRANTED) {
13465            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13466                    + Binder.getCallingPid()
13467                    + ", uid=" + Binder.getCallingUid()
13468                    + " without permission "
13469                    + android.Manifest.permission.DUMP);
13470            return;
13471        }
13472
13473        boolean dumpAll = false;
13474        boolean dumpClient = false;
13475        String dumpPackage = null;
13476
13477        int opti = 0;
13478        while (opti < args.length) {
13479            String opt = args[opti];
13480            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13481                break;
13482            }
13483            opti++;
13484            if ("-a".equals(opt)) {
13485                dumpAll = true;
13486            } else if ("-c".equals(opt)) {
13487                dumpClient = true;
13488            } else if ("-p".equals(opt)) {
13489                if (opti < args.length) {
13490                    dumpPackage = args[opti];
13491                    opti++;
13492                } else {
13493                    pw.println("Error: -p option requires package argument");
13494                    return;
13495                }
13496                dumpClient = true;
13497            } else if ("-h".equals(opt)) {
13498                ActivityManagerShellCommand.dumpHelp(pw, true);
13499                return;
13500            } else {
13501                pw.println("Unknown argument: " + opt + "; use -h for help");
13502            }
13503        }
13504
13505        long origId = Binder.clearCallingIdentity();
13506        boolean more = false;
13507        // Is the caller requesting to dump a particular piece of data?
13508        if (opti < args.length) {
13509            String cmd = args[opti];
13510            opti++;
13511            if ("activities".equals(cmd) || "a".equals(cmd)) {
13512                synchronized (this) {
13513                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13514                }
13515            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13516                synchronized (this) {
13517                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13518                }
13519            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13520                String[] newArgs;
13521                String name;
13522                if (opti >= args.length) {
13523                    name = null;
13524                    newArgs = EMPTY_STRING_ARRAY;
13525                } else {
13526                    dumpPackage = args[opti];
13527                    opti++;
13528                    newArgs = new String[args.length - opti];
13529                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13530                            args.length - opti);
13531                }
13532                synchronized (this) {
13533                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13534                }
13535            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13536                String[] newArgs;
13537                String name;
13538                if (opti >= args.length) {
13539                    name = null;
13540                    newArgs = EMPTY_STRING_ARRAY;
13541                } else {
13542                    dumpPackage = args[opti];
13543                    opti++;
13544                    newArgs = new String[args.length - opti];
13545                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13546                            args.length - opti);
13547                }
13548                synchronized (this) {
13549                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13550                }
13551            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13552                String[] newArgs;
13553                String name;
13554                if (opti >= args.length) {
13555                    name = null;
13556                    newArgs = EMPTY_STRING_ARRAY;
13557                } else {
13558                    dumpPackage = args[opti];
13559                    opti++;
13560                    newArgs = new String[args.length - opti];
13561                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13562                            args.length - opti);
13563                }
13564                synchronized (this) {
13565                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13566                }
13567            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13568                synchronized (this) {
13569                    dumpOomLocked(fd, pw, args, opti, true);
13570                }
13571            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13572                synchronized (this) {
13573                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13574                }
13575            } else if ("provider".equals(cmd)) {
13576                String[] newArgs;
13577                String name;
13578                if (opti >= args.length) {
13579                    name = null;
13580                    newArgs = EMPTY_STRING_ARRAY;
13581                } else {
13582                    name = args[opti];
13583                    opti++;
13584                    newArgs = new String[args.length - opti];
13585                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13586                }
13587                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13588                    pw.println("No providers match: " + name);
13589                    pw.println("Use -h for help.");
13590                }
13591            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13592                synchronized (this) {
13593                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13594                }
13595            } else if ("service".equals(cmd)) {
13596                String[] newArgs;
13597                String name;
13598                if (opti >= args.length) {
13599                    name = null;
13600                    newArgs = EMPTY_STRING_ARRAY;
13601                } else {
13602                    name = args[opti];
13603                    opti++;
13604                    newArgs = new String[args.length - opti];
13605                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13606                            args.length - opti);
13607                }
13608                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13609                    pw.println("No services match: " + name);
13610                    pw.println("Use -h for help.");
13611                }
13612            } else if ("package".equals(cmd)) {
13613                String[] newArgs;
13614                if (opti >= args.length) {
13615                    pw.println("package: no package name specified");
13616                    pw.println("Use -h for help.");
13617                } else {
13618                    dumpPackage = args[opti];
13619                    opti++;
13620                    newArgs = new String[args.length - opti];
13621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13622                            args.length - opti);
13623                    args = newArgs;
13624                    opti = 0;
13625                    more = true;
13626                }
13627            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13628                synchronized (this) {
13629                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13630                }
13631            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13632                synchronized (this) {
13633                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13634                }
13635            } else if ("locks".equals(cmd)) {
13636                LockGuard.dump(fd, pw, args);
13637            } else {
13638                // Dumping a single activity?
13639                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13640                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13641                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13642                    if (res < 0) {
13643                        pw.println("Bad activity command, or no activities match: " + cmd);
13644                        pw.println("Use -h for help.");
13645                    }
13646                }
13647            }
13648            if (!more) {
13649                Binder.restoreCallingIdentity(origId);
13650                return;
13651            }
13652        }
13653
13654        // No piece of data specified, dump everything.
13655        synchronized (this) {
13656            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13657            pw.println();
13658            if (dumpAll) {
13659                pw.println("-------------------------------------------------------------------------------");
13660            }
13661            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13662            pw.println();
13663            if (dumpAll) {
13664                pw.println("-------------------------------------------------------------------------------");
13665            }
13666            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13667            pw.println();
13668            if (dumpAll) {
13669                pw.println("-------------------------------------------------------------------------------");
13670            }
13671            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13672            pw.println();
13673            if (dumpAll) {
13674                pw.println("-------------------------------------------------------------------------------");
13675            }
13676            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13677            pw.println();
13678            if (dumpAll) {
13679                pw.println("-------------------------------------------------------------------------------");
13680            }
13681            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13682            pw.println();
13683            if (dumpAll) {
13684                pw.println("-------------------------------------------------------------------------------");
13685            }
13686            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13687            if (mAssociations.size() > 0) {
13688                pw.println();
13689                if (dumpAll) {
13690                    pw.println("-------------------------------------------------------------------------------");
13691                }
13692                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13693            }
13694            pw.println();
13695            if (dumpAll) {
13696                pw.println("-------------------------------------------------------------------------------");
13697            }
13698            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13699        }
13700        Binder.restoreCallingIdentity(origId);
13701    }
13702
13703    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13704            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13705        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13706
13707        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13708                dumpPackage);
13709        boolean needSep = printedAnything;
13710
13711        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13712                dumpPackage, needSep, "  mFocusedActivity: ");
13713        if (printed) {
13714            printedAnything = true;
13715            needSep = false;
13716        }
13717
13718        if (dumpPackage == null) {
13719            if (needSep) {
13720                pw.println();
13721            }
13722            needSep = true;
13723            printedAnything = true;
13724            mStackSupervisor.dump(pw, "  ");
13725        }
13726
13727        if (!printedAnything) {
13728            pw.println("  (nothing)");
13729        }
13730    }
13731
13732    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13733            int opti, boolean dumpAll, String dumpPackage) {
13734        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13735
13736        boolean printedAnything = false;
13737
13738        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13739            boolean printedHeader = false;
13740
13741            final int N = mRecentTasks.size();
13742            for (int i=0; i<N; i++) {
13743                TaskRecord tr = mRecentTasks.get(i);
13744                if (dumpPackage != null) {
13745                    if (tr.realActivity == null ||
13746                            !dumpPackage.equals(tr.realActivity)) {
13747                        continue;
13748                    }
13749                }
13750                if (!printedHeader) {
13751                    pw.println("  Recent tasks:");
13752                    printedHeader = true;
13753                    printedAnything = true;
13754                }
13755                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13756                        pw.println(tr);
13757                if (dumpAll) {
13758                    mRecentTasks.get(i).dump(pw, "    ");
13759                }
13760            }
13761        }
13762
13763        if (!printedAnything) {
13764            pw.println("  (nothing)");
13765        }
13766    }
13767
13768    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13769            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13770        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13771
13772        int dumpUid = 0;
13773        if (dumpPackage != null) {
13774            IPackageManager pm = AppGlobals.getPackageManager();
13775            try {
13776                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13777            } catch (RemoteException e) {
13778            }
13779        }
13780
13781        boolean printedAnything = false;
13782
13783        final long now = SystemClock.uptimeMillis();
13784
13785        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13786            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13787                    = mAssociations.valueAt(i1);
13788            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13789                SparseArray<ArrayMap<String, Association>> sourceUids
13790                        = targetComponents.valueAt(i2);
13791                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13792                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13793                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13794                        Association ass = sourceProcesses.valueAt(i4);
13795                        if (dumpPackage != null) {
13796                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13797                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13798                                continue;
13799                            }
13800                        }
13801                        printedAnything = true;
13802                        pw.print("  ");
13803                        pw.print(ass.mTargetProcess);
13804                        pw.print("/");
13805                        UserHandle.formatUid(pw, ass.mTargetUid);
13806                        pw.print(" <- ");
13807                        pw.print(ass.mSourceProcess);
13808                        pw.print("/");
13809                        UserHandle.formatUid(pw, ass.mSourceUid);
13810                        pw.println();
13811                        pw.print("    via ");
13812                        pw.print(ass.mTargetComponent.flattenToShortString());
13813                        pw.println();
13814                        pw.print("    ");
13815                        long dur = ass.mTime;
13816                        if (ass.mNesting > 0) {
13817                            dur += now - ass.mStartTime;
13818                        }
13819                        TimeUtils.formatDuration(dur, pw);
13820                        pw.print(" (");
13821                        pw.print(ass.mCount);
13822                        pw.println(" times)");
13823                        if (ass.mNesting > 0) {
13824                            pw.print("    ");
13825                            pw.print(" Currently active: ");
13826                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13827                            pw.println();
13828                        }
13829                    }
13830                }
13831            }
13832
13833        }
13834
13835        if (!printedAnything) {
13836            pw.println("  (nothing)");
13837        }
13838    }
13839
13840    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13841            String header, boolean needSep) {
13842        boolean printed = false;
13843        int whichAppId = -1;
13844        if (dumpPackage != null) {
13845            try {
13846                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13847                        dumpPackage, 0);
13848                whichAppId = UserHandle.getAppId(info.uid);
13849            } catch (NameNotFoundException e) {
13850                e.printStackTrace();
13851            }
13852        }
13853        for (int i=0; i<uids.size(); i++) {
13854            UidRecord uidRec = uids.valueAt(i);
13855            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13856                continue;
13857            }
13858            if (!printed) {
13859                printed = true;
13860                if (needSep) {
13861                    pw.println();
13862                }
13863                pw.print("  ");
13864                pw.println(header);
13865                needSep = true;
13866            }
13867            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13868            pw.print(": "); pw.println(uidRec);
13869        }
13870        return printed;
13871    }
13872
13873    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13874            int opti, boolean dumpAll, String dumpPackage) {
13875        boolean needSep = false;
13876        boolean printedAnything = false;
13877        int numPers = 0;
13878
13879        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13880
13881        if (dumpAll) {
13882            final int NP = mProcessNames.getMap().size();
13883            for (int ip=0; ip<NP; ip++) {
13884                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13885                final int NA = procs.size();
13886                for (int ia=0; ia<NA; ia++) {
13887                    ProcessRecord r = procs.valueAt(ia);
13888                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13889                        continue;
13890                    }
13891                    if (!needSep) {
13892                        pw.println("  All known processes:");
13893                        needSep = true;
13894                        printedAnything = true;
13895                    }
13896                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13897                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13898                        pw.print(" "); pw.println(r);
13899                    r.dump(pw, "    ");
13900                    if (r.persistent) {
13901                        numPers++;
13902                    }
13903                }
13904            }
13905        }
13906
13907        if (mIsolatedProcesses.size() > 0) {
13908            boolean printed = false;
13909            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13910                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13911                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13912                    continue;
13913                }
13914                if (!printed) {
13915                    if (needSep) {
13916                        pw.println();
13917                    }
13918                    pw.println("  Isolated process list (sorted by uid):");
13919                    printedAnything = true;
13920                    printed = true;
13921                    needSep = true;
13922                }
13923                pw.println(String.format("%sIsolated #%2d: %s",
13924                        "    ", i, r.toString()));
13925            }
13926        }
13927
13928        if (mActiveUids.size() > 0) {
13929            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13930                printedAnything = needSep = true;
13931            }
13932        }
13933        if (mValidateUids.size() > 0) {
13934            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13935                printedAnything = needSep = true;
13936            }
13937        }
13938
13939        if (mLruProcesses.size() > 0) {
13940            if (needSep) {
13941                pw.println();
13942            }
13943            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13944                    pw.print(" total, non-act at ");
13945                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13946                    pw.print(", non-svc at ");
13947                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13948                    pw.println("):");
13949            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13950            needSep = true;
13951            printedAnything = true;
13952        }
13953
13954        if (dumpAll || dumpPackage != null) {
13955            synchronized (mPidsSelfLocked) {
13956                boolean printed = false;
13957                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13958                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13959                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13960                        continue;
13961                    }
13962                    if (!printed) {
13963                        if (needSep) pw.println();
13964                        needSep = true;
13965                        pw.println("  PID mappings:");
13966                        printed = true;
13967                        printedAnything = true;
13968                    }
13969                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13970                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13971                }
13972            }
13973        }
13974
13975        if (mForegroundProcesses.size() > 0) {
13976            synchronized (mPidsSelfLocked) {
13977                boolean printed = false;
13978                for (int i=0; i<mForegroundProcesses.size(); i++) {
13979                    ProcessRecord r = mPidsSelfLocked.get(
13980                            mForegroundProcesses.valueAt(i).pid);
13981                    if (dumpPackage != null && (r == null
13982                            || !r.pkgList.containsKey(dumpPackage))) {
13983                        continue;
13984                    }
13985                    if (!printed) {
13986                        if (needSep) pw.println();
13987                        needSep = true;
13988                        pw.println("  Foreground Processes:");
13989                        printed = true;
13990                        printedAnything = true;
13991                    }
13992                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13993                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13994                }
13995            }
13996        }
13997
13998        if (mPersistentStartingProcesses.size() > 0) {
13999            if (needSep) pw.println();
14000            needSep = true;
14001            printedAnything = true;
14002            pw.println("  Persisent processes that are starting:");
14003            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14004                    "Starting Norm", "Restarting PERS", dumpPackage);
14005        }
14006
14007        if (mRemovedProcesses.size() > 0) {
14008            if (needSep) pw.println();
14009            needSep = true;
14010            printedAnything = true;
14011            pw.println("  Processes that are being removed:");
14012            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14013                    "Removed Norm", "Removed PERS", dumpPackage);
14014        }
14015
14016        if (mProcessesOnHold.size() > 0) {
14017            if (needSep) pw.println();
14018            needSep = true;
14019            printedAnything = true;
14020            pw.println("  Processes that are on old until the system is ready:");
14021            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14022                    "OnHold Norm", "OnHold PERS", dumpPackage);
14023        }
14024
14025        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14026
14027        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14028        if (needSep) {
14029            printedAnything = true;
14030        }
14031
14032        if (dumpPackage == null) {
14033            pw.println();
14034            needSep = false;
14035            mUserController.dump(pw, dumpAll);
14036        }
14037        if (mHomeProcess != null && (dumpPackage == null
14038                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14039            if (needSep) {
14040                pw.println();
14041                needSep = false;
14042            }
14043            pw.println("  mHomeProcess: " + mHomeProcess);
14044        }
14045        if (mPreviousProcess != null && (dumpPackage == null
14046                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14047            if (needSep) {
14048                pw.println();
14049                needSep = false;
14050            }
14051            pw.println("  mPreviousProcess: " + mPreviousProcess);
14052        }
14053        if (dumpAll) {
14054            StringBuilder sb = new StringBuilder(128);
14055            sb.append("  mPreviousProcessVisibleTime: ");
14056            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14057            pw.println(sb);
14058        }
14059        if (mHeavyWeightProcess != null && (dumpPackage == null
14060                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14061            if (needSep) {
14062                pw.println();
14063                needSep = false;
14064            }
14065            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14066        }
14067        if (dumpPackage == null) {
14068            pw.println("  mConfiguration: " + mConfiguration);
14069        }
14070        if (dumpAll) {
14071            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14072            if (mCompatModePackages.getPackages().size() > 0) {
14073                boolean printed = false;
14074                for (Map.Entry<String, Integer> entry
14075                        : mCompatModePackages.getPackages().entrySet()) {
14076                    String pkg = entry.getKey();
14077                    int mode = entry.getValue();
14078                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14079                        continue;
14080                    }
14081                    if (!printed) {
14082                        pw.println("  mScreenCompatPackages:");
14083                        printed = true;
14084                    }
14085                    pw.print("    "); pw.print(pkg); pw.print(": ");
14086                            pw.print(mode); pw.println();
14087                }
14088            }
14089        }
14090        if (dumpPackage == null) {
14091            pw.println("  mWakefulness="
14092                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14093            pw.println("  mSleepTokens=" + mSleepTokens);
14094            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14095                    + lockScreenShownToString());
14096            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14097            if (mRunningVoice != null) {
14098                pw.println("  mRunningVoice=" + mRunningVoice);
14099                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14100            }
14101        }
14102        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14103                || mOrigWaitForDebugger) {
14104            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14105                    || dumpPackage.equals(mOrigDebugApp)) {
14106                if (needSep) {
14107                    pw.println();
14108                    needSep = false;
14109                }
14110                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14111                        + " mDebugTransient=" + mDebugTransient
14112                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14113            }
14114        }
14115        if (mCurAppTimeTracker != null) {
14116            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14117        }
14118        if (mMemWatchProcesses.getMap().size() > 0) {
14119            pw.println("  Mem watch processes:");
14120            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14121                    = mMemWatchProcesses.getMap();
14122            for (int i=0; i<procs.size(); i++) {
14123                final String proc = procs.keyAt(i);
14124                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14125                for (int j=0; j<uids.size(); j++) {
14126                    if (needSep) {
14127                        pw.println();
14128                        needSep = false;
14129                    }
14130                    StringBuilder sb = new StringBuilder();
14131                    sb.append("    ").append(proc).append('/');
14132                    UserHandle.formatUid(sb, uids.keyAt(j));
14133                    Pair<Long, String> val = uids.valueAt(j);
14134                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14135                    if (val.second != null) {
14136                        sb.append(", report to ").append(val.second);
14137                    }
14138                    pw.println(sb.toString());
14139                }
14140            }
14141            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14142            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14143            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14144                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14145        }
14146        if (mTrackAllocationApp != null) {
14147            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14148                if (needSep) {
14149                    pw.println();
14150                    needSep = false;
14151                }
14152                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14153            }
14154        }
14155        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14156                || mProfileFd != null) {
14157            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14158                if (needSep) {
14159                    pw.println();
14160                    needSep = false;
14161                }
14162                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14163                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14164                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14165                        + mAutoStopProfiler);
14166                pw.println("  mProfileType=" + mProfileType);
14167            }
14168        }
14169        if (mNativeDebuggingApp != null) {
14170            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14171                if (needSep) {
14172                    pw.println();
14173                    needSep = false;
14174                }
14175                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14176            }
14177        }
14178        if (dumpPackage == null) {
14179            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14180                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14181                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14182            }
14183            if (mController != null) {
14184                pw.println("  mController=" + mController
14185                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14186            }
14187            if (dumpAll) {
14188                pw.println("  Total persistent processes: " + numPers);
14189                pw.println("  mProcessesReady=" + mProcessesReady
14190                        + " mSystemReady=" + mSystemReady
14191                        + " mBooted=" + mBooted
14192                        + " mFactoryTest=" + mFactoryTest);
14193                pw.println("  mBooting=" + mBooting
14194                        + " mCallFinishBooting=" + mCallFinishBooting
14195                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14196                pw.print("  mLastPowerCheckRealtime=");
14197                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14198                        pw.println("");
14199                pw.print("  mLastPowerCheckUptime=");
14200                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14201                        pw.println("");
14202                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14203                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14204                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14205                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14206                        + " (" + mLruProcesses.size() + " total)"
14207                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14208                        + " mNumServiceProcs=" + mNumServiceProcs
14209                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14210                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14211                        + " mLastMemoryLevel" + mLastMemoryLevel
14212                        + " mLastNumProcesses" + mLastNumProcesses);
14213                long now = SystemClock.uptimeMillis();
14214                pw.print("  mLastIdleTime=");
14215                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14216                        pw.print(" mLowRamSinceLastIdle=");
14217                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14218                        pw.println();
14219            }
14220        }
14221
14222        if (!printedAnything) {
14223            pw.println("  (nothing)");
14224        }
14225    }
14226
14227    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14228            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14229        if (mProcessesToGc.size() > 0) {
14230            boolean printed = false;
14231            long now = SystemClock.uptimeMillis();
14232            for (int i=0; i<mProcessesToGc.size(); i++) {
14233                ProcessRecord proc = mProcessesToGc.get(i);
14234                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14235                    continue;
14236                }
14237                if (!printed) {
14238                    if (needSep) pw.println();
14239                    needSep = true;
14240                    pw.println("  Processes that are waiting to GC:");
14241                    printed = true;
14242                }
14243                pw.print("    Process "); pw.println(proc);
14244                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14245                        pw.print(", last gced=");
14246                        pw.print(now-proc.lastRequestedGc);
14247                        pw.print(" ms ago, last lowMem=");
14248                        pw.print(now-proc.lastLowMemory);
14249                        pw.println(" ms ago");
14250
14251            }
14252        }
14253        return needSep;
14254    }
14255
14256    void printOomLevel(PrintWriter pw, String name, int adj) {
14257        pw.print("    ");
14258        if (adj >= 0) {
14259            pw.print(' ');
14260            if (adj < 10) pw.print(' ');
14261        } else {
14262            if (adj > -10) pw.print(' ');
14263        }
14264        pw.print(adj);
14265        pw.print(": ");
14266        pw.print(name);
14267        pw.print(" (");
14268        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14269        pw.println(")");
14270    }
14271
14272    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14273            int opti, boolean dumpAll) {
14274        boolean needSep = false;
14275
14276        if (mLruProcesses.size() > 0) {
14277            if (needSep) pw.println();
14278            needSep = true;
14279            pw.println("  OOM levels:");
14280            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14281            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14282            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14283            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14284            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14285            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14286            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14287            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14288            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14289            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14290            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14291            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14292            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14293            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14294
14295            if (needSep) pw.println();
14296            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14297                    pw.print(" total, non-act at ");
14298                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14299                    pw.print(", non-svc at ");
14300                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14301                    pw.println("):");
14302            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14303            needSep = true;
14304        }
14305
14306        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14307
14308        pw.println();
14309        pw.println("  mHomeProcess: " + mHomeProcess);
14310        pw.println("  mPreviousProcess: " + mPreviousProcess);
14311        if (mHeavyWeightProcess != null) {
14312            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14313        }
14314
14315        return true;
14316    }
14317
14318    /**
14319     * There are three ways to call this:
14320     *  - no provider specified: dump all the providers
14321     *  - a flattened component name that matched an existing provider was specified as the
14322     *    first arg: dump that one provider
14323     *  - the first arg isn't the flattened component name of an existing provider:
14324     *    dump all providers whose component contains the first arg as a substring
14325     */
14326    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14327            int opti, boolean dumpAll) {
14328        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14329    }
14330
14331    static class ItemMatcher {
14332        ArrayList<ComponentName> components;
14333        ArrayList<String> strings;
14334        ArrayList<Integer> objects;
14335        boolean all;
14336
14337        ItemMatcher() {
14338            all = true;
14339        }
14340
14341        void build(String name) {
14342            ComponentName componentName = ComponentName.unflattenFromString(name);
14343            if (componentName != null) {
14344                if (components == null) {
14345                    components = new ArrayList<ComponentName>();
14346                }
14347                components.add(componentName);
14348                all = false;
14349            } else {
14350                int objectId = 0;
14351                // Not a '/' separated full component name; maybe an object ID?
14352                try {
14353                    objectId = Integer.parseInt(name, 16);
14354                    if (objects == null) {
14355                        objects = new ArrayList<Integer>();
14356                    }
14357                    objects.add(objectId);
14358                    all = false;
14359                } catch (RuntimeException e) {
14360                    // Not an integer; just do string match.
14361                    if (strings == null) {
14362                        strings = new ArrayList<String>();
14363                    }
14364                    strings.add(name);
14365                    all = false;
14366                }
14367            }
14368        }
14369
14370        int build(String[] args, int opti) {
14371            for (; opti<args.length; opti++) {
14372                String name = args[opti];
14373                if ("--".equals(name)) {
14374                    return opti+1;
14375                }
14376                build(name);
14377            }
14378            return opti;
14379        }
14380
14381        boolean match(Object object, ComponentName comp) {
14382            if (all) {
14383                return true;
14384            }
14385            if (components != null) {
14386                for (int i=0; i<components.size(); i++) {
14387                    if (components.get(i).equals(comp)) {
14388                        return true;
14389                    }
14390                }
14391            }
14392            if (objects != null) {
14393                for (int i=0; i<objects.size(); i++) {
14394                    if (System.identityHashCode(object) == objects.get(i)) {
14395                        return true;
14396                    }
14397                }
14398            }
14399            if (strings != null) {
14400                String flat = comp.flattenToString();
14401                for (int i=0; i<strings.size(); i++) {
14402                    if (flat.contains(strings.get(i))) {
14403                        return true;
14404                    }
14405                }
14406            }
14407            return false;
14408        }
14409    }
14410
14411    /**
14412     * There are three things that cmd can be:
14413     *  - a flattened component name that matches an existing activity
14414     *  - the cmd arg isn't the flattened component name of an existing activity:
14415     *    dump all activity whose component contains the cmd as a substring
14416     *  - A hex number of the ActivityRecord object instance.
14417     */
14418    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14419            int opti, boolean dumpAll) {
14420        ArrayList<ActivityRecord> activities;
14421
14422        synchronized (this) {
14423            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14424        }
14425
14426        if (activities.size() <= 0) {
14427            return false;
14428        }
14429
14430        String[] newArgs = new String[args.length - opti];
14431        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14432
14433        TaskRecord lastTask = null;
14434        boolean needSep = false;
14435        for (int i=activities.size()-1; i>=0; i--) {
14436            ActivityRecord r = activities.get(i);
14437            if (needSep) {
14438                pw.println();
14439            }
14440            needSep = true;
14441            synchronized (this) {
14442                if (lastTask != r.task) {
14443                    lastTask = r.task;
14444                    pw.print("TASK "); pw.print(lastTask.affinity);
14445                            pw.print(" id="); pw.println(lastTask.taskId);
14446                    if (dumpAll) {
14447                        lastTask.dump(pw, "  ");
14448                    }
14449                }
14450            }
14451            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14452        }
14453        return true;
14454    }
14455
14456    /**
14457     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14458     * there is a thread associated with the activity.
14459     */
14460    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14461            final ActivityRecord r, String[] args, boolean dumpAll) {
14462        String innerPrefix = prefix + "  ";
14463        synchronized (this) {
14464            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14465                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14466                    pw.print(" pid=");
14467                    if (r.app != null) pw.println(r.app.pid);
14468                    else pw.println("(not running)");
14469            if (dumpAll) {
14470                r.dump(pw, innerPrefix);
14471            }
14472        }
14473        if (r.app != null && r.app.thread != null) {
14474            // flush anything that is already in the PrintWriter since the thread is going
14475            // to write to the file descriptor directly
14476            pw.flush();
14477            try {
14478                TransferPipe tp = new TransferPipe();
14479                try {
14480                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14481                            r.appToken, innerPrefix, args);
14482                    tp.go(fd);
14483                } finally {
14484                    tp.kill();
14485                }
14486            } catch (IOException e) {
14487                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14488            } catch (RemoteException e) {
14489                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14490            }
14491        }
14492    }
14493
14494    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14495            int opti, boolean dumpAll, String dumpPackage) {
14496        boolean needSep = false;
14497        boolean onlyHistory = false;
14498        boolean printedAnything = false;
14499
14500        if ("history".equals(dumpPackage)) {
14501            if (opti < args.length && "-s".equals(args[opti])) {
14502                dumpAll = false;
14503            }
14504            onlyHistory = true;
14505            dumpPackage = null;
14506        }
14507
14508        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14509        if (!onlyHistory && dumpAll) {
14510            if (mRegisteredReceivers.size() > 0) {
14511                boolean printed = false;
14512                Iterator it = mRegisteredReceivers.values().iterator();
14513                while (it.hasNext()) {
14514                    ReceiverList r = (ReceiverList)it.next();
14515                    if (dumpPackage != null && (r.app == null ||
14516                            !dumpPackage.equals(r.app.info.packageName))) {
14517                        continue;
14518                    }
14519                    if (!printed) {
14520                        pw.println("  Registered Receivers:");
14521                        needSep = true;
14522                        printed = true;
14523                        printedAnything = true;
14524                    }
14525                    pw.print("  * "); pw.println(r);
14526                    r.dump(pw, "    ");
14527                }
14528            }
14529
14530            if (mReceiverResolver.dump(pw, needSep ?
14531                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14532                    "    ", dumpPackage, false, false)) {
14533                needSep = true;
14534                printedAnything = true;
14535            }
14536        }
14537
14538        for (BroadcastQueue q : mBroadcastQueues) {
14539            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14540            printedAnything |= needSep;
14541        }
14542
14543        needSep = true;
14544
14545        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14546            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14547                if (needSep) {
14548                    pw.println();
14549                }
14550                needSep = true;
14551                printedAnything = true;
14552                pw.print("  Sticky broadcasts for user ");
14553                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14554                StringBuilder sb = new StringBuilder(128);
14555                for (Map.Entry<String, ArrayList<Intent>> ent
14556                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14557                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14558                    if (dumpAll) {
14559                        pw.println(":");
14560                        ArrayList<Intent> intents = ent.getValue();
14561                        final int N = intents.size();
14562                        for (int i=0; i<N; i++) {
14563                            sb.setLength(0);
14564                            sb.append("    Intent: ");
14565                            intents.get(i).toShortString(sb, false, true, false, false);
14566                            pw.println(sb.toString());
14567                            Bundle bundle = intents.get(i).getExtras();
14568                            if (bundle != null) {
14569                                pw.print("      ");
14570                                pw.println(bundle.toString());
14571                            }
14572                        }
14573                    } else {
14574                        pw.println("");
14575                    }
14576                }
14577            }
14578        }
14579
14580        if (!onlyHistory && dumpAll) {
14581            pw.println();
14582            for (BroadcastQueue queue : mBroadcastQueues) {
14583                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14584                        + queue.mBroadcastsScheduled);
14585            }
14586            pw.println("  mHandler:");
14587            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14588            needSep = true;
14589            printedAnything = true;
14590        }
14591
14592        if (!printedAnything) {
14593            pw.println("  (nothing)");
14594        }
14595    }
14596
14597    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14598            int opti, boolean dumpAll, String dumpPackage) {
14599        boolean needSep;
14600        boolean printedAnything = false;
14601
14602        ItemMatcher matcher = new ItemMatcher();
14603        matcher.build(args, opti);
14604
14605        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14606
14607        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14608        printedAnything |= needSep;
14609
14610        if (mLaunchingProviders.size() > 0) {
14611            boolean printed = false;
14612            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14613                ContentProviderRecord r = mLaunchingProviders.get(i);
14614                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14615                    continue;
14616                }
14617                if (!printed) {
14618                    if (needSep) pw.println();
14619                    needSep = true;
14620                    pw.println("  Launching content providers:");
14621                    printed = true;
14622                    printedAnything = true;
14623                }
14624                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14625                        pw.println(r);
14626            }
14627        }
14628
14629        if (!printedAnything) {
14630            pw.println("  (nothing)");
14631        }
14632    }
14633
14634    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14635            int opti, boolean dumpAll, String dumpPackage) {
14636        boolean needSep = false;
14637        boolean printedAnything = false;
14638
14639        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14640
14641        if (mGrantedUriPermissions.size() > 0) {
14642            boolean printed = false;
14643            int dumpUid = -2;
14644            if (dumpPackage != null) {
14645                try {
14646                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14647                            MATCH_UNINSTALLED_PACKAGES, 0);
14648                } catch (NameNotFoundException e) {
14649                    dumpUid = -1;
14650                }
14651            }
14652            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14653                int uid = mGrantedUriPermissions.keyAt(i);
14654                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14655                    continue;
14656                }
14657                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14658                if (!printed) {
14659                    if (needSep) pw.println();
14660                    needSep = true;
14661                    pw.println("  Granted Uri Permissions:");
14662                    printed = true;
14663                    printedAnything = true;
14664                }
14665                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14666                for (UriPermission perm : perms.values()) {
14667                    pw.print("    "); pw.println(perm);
14668                    if (dumpAll) {
14669                        perm.dump(pw, "      ");
14670                    }
14671                }
14672            }
14673        }
14674
14675        if (!printedAnything) {
14676            pw.println("  (nothing)");
14677        }
14678    }
14679
14680    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14681            int opti, boolean dumpAll, String dumpPackage) {
14682        boolean printed = false;
14683
14684        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14685
14686        if (mIntentSenderRecords.size() > 0) {
14687            Iterator<WeakReference<PendingIntentRecord>> it
14688                    = mIntentSenderRecords.values().iterator();
14689            while (it.hasNext()) {
14690                WeakReference<PendingIntentRecord> ref = it.next();
14691                PendingIntentRecord rec = ref != null ? ref.get(): null;
14692                if (dumpPackage != null && (rec == null
14693                        || !dumpPackage.equals(rec.key.packageName))) {
14694                    continue;
14695                }
14696                printed = true;
14697                if (rec != null) {
14698                    pw.print("  * "); pw.println(rec);
14699                    if (dumpAll) {
14700                        rec.dump(pw, "    ");
14701                    }
14702                } else {
14703                    pw.print("  * "); pw.println(ref);
14704                }
14705            }
14706        }
14707
14708        if (!printed) {
14709            pw.println("  (nothing)");
14710        }
14711    }
14712
14713    private static final int dumpProcessList(PrintWriter pw,
14714            ActivityManagerService service, List list,
14715            String prefix, String normalLabel, String persistentLabel,
14716            String dumpPackage) {
14717        int numPers = 0;
14718        final int N = list.size()-1;
14719        for (int i=N; i>=0; i--) {
14720            ProcessRecord r = (ProcessRecord)list.get(i);
14721            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14722                continue;
14723            }
14724            pw.println(String.format("%s%s #%2d: %s",
14725                    prefix, (r.persistent ? persistentLabel : normalLabel),
14726                    i, r.toString()));
14727            if (r.persistent) {
14728                numPers++;
14729            }
14730        }
14731        return numPers;
14732    }
14733
14734    private static final boolean dumpProcessOomList(PrintWriter pw,
14735            ActivityManagerService service, List<ProcessRecord> origList,
14736            String prefix, String normalLabel, String persistentLabel,
14737            boolean inclDetails, String dumpPackage) {
14738
14739        ArrayList<Pair<ProcessRecord, Integer>> list
14740                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14741        for (int i=0; i<origList.size(); i++) {
14742            ProcessRecord r = origList.get(i);
14743            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14744                continue;
14745            }
14746            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14747        }
14748
14749        if (list.size() <= 0) {
14750            return false;
14751        }
14752
14753        Comparator<Pair<ProcessRecord, Integer>> comparator
14754                = new Comparator<Pair<ProcessRecord, Integer>>() {
14755            @Override
14756            public int compare(Pair<ProcessRecord, Integer> object1,
14757                    Pair<ProcessRecord, Integer> object2) {
14758                if (object1.first.setAdj != object2.first.setAdj) {
14759                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14760                }
14761                if (object1.first.setProcState != object2.first.setProcState) {
14762                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14763                }
14764                if (object1.second.intValue() != object2.second.intValue()) {
14765                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14766                }
14767                return 0;
14768            }
14769        };
14770
14771        Collections.sort(list, comparator);
14772
14773        final long curRealtime = SystemClock.elapsedRealtime();
14774        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14775        final long curUptime = SystemClock.uptimeMillis();
14776        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14777
14778        for (int i=list.size()-1; i>=0; i--) {
14779            ProcessRecord r = list.get(i).first;
14780            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14781            char schedGroup;
14782            switch (r.setSchedGroup) {
14783                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14784                    schedGroup = 'B';
14785                    break;
14786                case Process.THREAD_GROUP_DEFAULT:
14787                    schedGroup = 'F';
14788                    break;
14789                case Process.THREAD_GROUP_TOP_APP:
14790                    schedGroup = 'T';
14791                    break;
14792                default:
14793                    schedGroup = '?';
14794                    break;
14795            }
14796            char foreground;
14797            if (r.foregroundActivities) {
14798                foreground = 'A';
14799            } else if (r.foregroundServices) {
14800                foreground = 'S';
14801            } else {
14802                foreground = ' ';
14803            }
14804            String procState = ProcessList.makeProcStateString(r.curProcState);
14805            pw.print(prefix);
14806            pw.print(r.persistent ? persistentLabel : normalLabel);
14807            pw.print(" #");
14808            int num = (origList.size()-1)-list.get(i).second;
14809            if (num < 10) pw.print(' ');
14810            pw.print(num);
14811            pw.print(": ");
14812            pw.print(oomAdj);
14813            pw.print(' ');
14814            pw.print(schedGroup);
14815            pw.print('/');
14816            pw.print(foreground);
14817            pw.print('/');
14818            pw.print(procState);
14819            pw.print(" trm:");
14820            if (r.trimMemoryLevel < 10) pw.print(' ');
14821            pw.print(r.trimMemoryLevel);
14822            pw.print(' ');
14823            pw.print(r.toShortString());
14824            pw.print(" (");
14825            pw.print(r.adjType);
14826            pw.println(')');
14827            if (r.adjSource != null || r.adjTarget != null) {
14828                pw.print(prefix);
14829                pw.print("    ");
14830                if (r.adjTarget instanceof ComponentName) {
14831                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14832                } else if (r.adjTarget != null) {
14833                    pw.print(r.adjTarget.toString());
14834                } else {
14835                    pw.print("{null}");
14836                }
14837                pw.print("<=");
14838                if (r.adjSource instanceof ProcessRecord) {
14839                    pw.print("Proc{");
14840                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14841                    pw.println("}");
14842                } else if (r.adjSource != null) {
14843                    pw.println(r.adjSource.toString());
14844                } else {
14845                    pw.println("{null}");
14846                }
14847            }
14848            if (inclDetails) {
14849                pw.print(prefix);
14850                pw.print("    ");
14851                pw.print("oom: max="); pw.print(r.maxAdj);
14852                pw.print(" curRaw="); pw.print(r.curRawAdj);
14853                pw.print(" setRaw="); pw.print(r.setRawAdj);
14854                pw.print(" cur="); pw.print(r.curAdj);
14855                pw.print(" set="); pw.println(r.setAdj);
14856                pw.print(prefix);
14857                pw.print("    ");
14858                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14859                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14860                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14861                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14862                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14863                pw.println();
14864                pw.print(prefix);
14865                pw.print("    ");
14866                pw.print("cached="); pw.print(r.cached);
14867                pw.print(" empty="); pw.print(r.empty);
14868                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14869
14870                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14871                    if (r.lastWakeTime != 0) {
14872                        long wtime;
14873                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14874                        synchronized (stats) {
14875                            wtime = stats.getProcessWakeTime(r.info.uid,
14876                                    r.pid, curRealtime);
14877                        }
14878                        long timeUsed = wtime - r.lastWakeTime;
14879                        pw.print(prefix);
14880                        pw.print("    ");
14881                        pw.print("keep awake over ");
14882                        TimeUtils.formatDuration(realtimeSince, pw);
14883                        pw.print(" used ");
14884                        TimeUtils.formatDuration(timeUsed, pw);
14885                        pw.print(" (");
14886                        pw.print((timeUsed*100)/realtimeSince);
14887                        pw.println("%)");
14888                    }
14889                    if (r.lastCpuTime != 0) {
14890                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14891                        pw.print(prefix);
14892                        pw.print("    ");
14893                        pw.print("run cpu over ");
14894                        TimeUtils.formatDuration(uptimeSince, pw);
14895                        pw.print(" used ");
14896                        TimeUtils.formatDuration(timeUsed, pw);
14897                        pw.print(" (");
14898                        pw.print((timeUsed*100)/uptimeSince);
14899                        pw.println("%)");
14900                    }
14901                }
14902            }
14903        }
14904        return true;
14905    }
14906
14907    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14908            String[] args) {
14909        ArrayList<ProcessRecord> procs;
14910        synchronized (this) {
14911            if (args != null && args.length > start
14912                    && args[start].charAt(0) != '-') {
14913                procs = new ArrayList<ProcessRecord>();
14914                int pid = -1;
14915                try {
14916                    pid = Integer.parseInt(args[start]);
14917                } catch (NumberFormatException e) {
14918                }
14919                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14920                    ProcessRecord proc = mLruProcesses.get(i);
14921                    if (proc.pid == pid) {
14922                        procs.add(proc);
14923                    } else if (allPkgs && proc.pkgList != null
14924                            && proc.pkgList.containsKey(args[start])) {
14925                        procs.add(proc);
14926                    } else if (proc.processName.equals(args[start])) {
14927                        procs.add(proc);
14928                    }
14929                }
14930                if (procs.size() <= 0) {
14931                    return null;
14932                }
14933            } else {
14934                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14935            }
14936        }
14937        return procs;
14938    }
14939
14940    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14941            PrintWriter pw, String[] args) {
14942        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14943        if (procs == null) {
14944            pw.println("No process found for: " + args[0]);
14945            return;
14946        }
14947
14948        long uptime = SystemClock.uptimeMillis();
14949        long realtime = SystemClock.elapsedRealtime();
14950        pw.println("Applications Graphics Acceleration Info:");
14951        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14952
14953        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14954            ProcessRecord r = procs.get(i);
14955            if (r.thread != null) {
14956                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14957                pw.flush();
14958                try {
14959                    TransferPipe tp = new TransferPipe();
14960                    try {
14961                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14962                        tp.go(fd);
14963                    } finally {
14964                        tp.kill();
14965                    }
14966                } catch (IOException e) {
14967                    pw.println("Failure while dumping the app: " + r);
14968                    pw.flush();
14969                } catch (RemoteException e) {
14970                    pw.println("Got a RemoteException while dumping the app " + r);
14971                    pw.flush();
14972                }
14973            }
14974        }
14975    }
14976
14977    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14978        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14979        if (procs == null) {
14980            pw.println("No process found for: " + args[0]);
14981            return;
14982        }
14983
14984        pw.println("Applications Database Info:");
14985
14986        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14987            ProcessRecord r = procs.get(i);
14988            if (r.thread != null) {
14989                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14990                pw.flush();
14991                try {
14992                    TransferPipe tp = new TransferPipe();
14993                    try {
14994                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14995                        tp.go(fd);
14996                    } finally {
14997                        tp.kill();
14998                    }
14999                } catch (IOException e) {
15000                    pw.println("Failure while dumping the app: " + r);
15001                    pw.flush();
15002                } catch (RemoteException e) {
15003                    pw.println("Got a RemoteException while dumping the app " + r);
15004                    pw.flush();
15005                }
15006            }
15007        }
15008    }
15009
15010    final static class MemItem {
15011        final boolean isProc;
15012        final String label;
15013        final String shortLabel;
15014        final long pss;
15015        final long swapPss;
15016        final int id;
15017        final boolean hasActivities;
15018        ArrayList<MemItem> subitems;
15019
15020        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15021                boolean _hasActivities) {
15022            isProc = true;
15023            label = _label;
15024            shortLabel = _shortLabel;
15025            pss = _pss;
15026            swapPss = _swapPss;
15027            id = _id;
15028            hasActivities = _hasActivities;
15029        }
15030
15031        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15032            isProc = false;
15033            label = _label;
15034            shortLabel = _shortLabel;
15035            pss = _pss;
15036            swapPss = _swapPss;
15037            id = _id;
15038            hasActivities = false;
15039        }
15040    }
15041
15042    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15043            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15044        if (sort && !isCompact) {
15045            Collections.sort(items, new Comparator<MemItem>() {
15046                @Override
15047                public int compare(MemItem lhs, MemItem rhs) {
15048                    if (lhs.pss < rhs.pss) {
15049                        return 1;
15050                    } else if (lhs.pss > rhs.pss) {
15051                        return -1;
15052                    }
15053                    return 0;
15054                }
15055            });
15056        }
15057
15058        for (int i=0; i<items.size(); i++) {
15059            MemItem mi = items.get(i);
15060            if (!isCompact) {
15061                if (dumpSwapPss) {
15062                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15063                            mi.label, stringifyKBSize(mi.swapPss));
15064                } else {
15065                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15066                }
15067            } else if (mi.isProc) {
15068                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15069                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15070                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15071                pw.println(mi.hasActivities ? ",a" : ",e");
15072            } else {
15073                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15074                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15075            }
15076            if (mi.subitems != null) {
15077                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15078                        true, isCompact, dumpSwapPss);
15079            }
15080        }
15081    }
15082
15083    // These are in KB.
15084    static final long[] DUMP_MEM_BUCKETS = new long[] {
15085        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15086        120*1024, 160*1024, 200*1024,
15087        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15088        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15089    };
15090
15091    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15092            boolean stackLike) {
15093        int start = label.lastIndexOf('.');
15094        if (start >= 0) start++;
15095        else start = 0;
15096        int end = label.length();
15097        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15098            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15099                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15100                out.append(bucket);
15101                out.append(stackLike ? "MB." : "MB ");
15102                out.append(label, start, end);
15103                return;
15104            }
15105        }
15106        out.append(memKB/1024);
15107        out.append(stackLike ? "MB." : "MB ");
15108        out.append(label, start, end);
15109    }
15110
15111    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15112            ProcessList.NATIVE_ADJ,
15113            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15114            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15115            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15116            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15117            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15118            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15119    };
15120    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15121            "Native",
15122            "System", "Persistent", "Persistent Service", "Foreground",
15123            "Visible", "Perceptible",
15124            "Heavy Weight", "Backup",
15125            "A Services", "Home",
15126            "Previous", "B Services", "Cached"
15127    };
15128    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15129            "native",
15130            "sys", "pers", "persvc", "fore",
15131            "vis", "percept",
15132            "heavy", "backup",
15133            "servicea", "home",
15134            "prev", "serviceb", "cached"
15135    };
15136
15137    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15138            long realtime, boolean isCheckinRequest, boolean isCompact) {
15139        if (isCompact) {
15140            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15141        }
15142        if (isCheckinRequest || isCompact) {
15143            // short checkin version
15144            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15145        } else {
15146            pw.println("Applications Memory Usage (in Kilobytes):");
15147            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15148        }
15149    }
15150
15151    private static final int KSM_SHARED = 0;
15152    private static final int KSM_SHARING = 1;
15153    private static final int KSM_UNSHARED = 2;
15154    private static final int KSM_VOLATILE = 3;
15155
15156    private final long[] getKsmInfo() {
15157        long[] longOut = new long[4];
15158        final int[] SINGLE_LONG_FORMAT = new int[] {
15159            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15160        };
15161        long[] longTmp = new long[1];
15162        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15163                SINGLE_LONG_FORMAT, null, longTmp, null);
15164        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15165        longTmp[0] = 0;
15166        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15167                SINGLE_LONG_FORMAT, null, longTmp, null);
15168        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15169        longTmp[0] = 0;
15170        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15171                SINGLE_LONG_FORMAT, null, longTmp, null);
15172        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15173        longTmp[0] = 0;
15174        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15175                SINGLE_LONG_FORMAT, null, longTmp, null);
15176        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15177        return longOut;
15178    }
15179
15180    private static String stringifySize(long size, int order) {
15181        Locale locale = Locale.US;
15182        switch (order) {
15183            case 1:
15184                return String.format(locale, "%,13d", size);
15185            case 1024:
15186                return String.format(locale, "%,9dK", size / 1024);
15187            case 1024 * 1024:
15188                return String.format(locale, "%,5dM", size / 1024 / 1024);
15189            case 1024 * 1024 * 1024:
15190                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15191            default:
15192                throw new IllegalArgumentException("Invalid size order");
15193        }
15194    }
15195
15196    private static String stringifyKBSize(long size) {
15197        return stringifySize(size * 1024, 1024);
15198    }
15199
15200    // Update this version number in case you change the 'compact' format
15201    private static final int MEMINFO_COMPACT_VERSION = 1;
15202
15203    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15204            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15205        boolean dumpDetails = false;
15206        boolean dumpFullDetails = false;
15207        boolean dumpDalvik = false;
15208        boolean dumpSummaryOnly = false;
15209        boolean dumpUnreachable = false;
15210        boolean oomOnly = false;
15211        boolean isCompact = false;
15212        boolean localOnly = false;
15213        boolean packages = false;
15214        boolean isCheckinRequest = false;
15215        boolean dumpSwapPss = false;
15216
15217        int opti = 0;
15218        while (opti < args.length) {
15219            String opt = args[opti];
15220            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15221                break;
15222            }
15223            opti++;
15224            if ("-a".equals(opt)) {
15225                dumpDetails = true;
15226                dumpFullDetails = true;
15227                dumpDalvik = true;
15228                dumpSwapPss = true;
15229            } else if ("-d".equals(opt)) {
15230                dumpDalvik = true;
15231            } else if ("-c".equals(opt)) {
15232                isCompact = true;
15233            } else if ("-s".equals(opt)) {
15234                dumpDetails = true;
15235                dumpSummaryOnly = true;
15236            } else if ("-S".equals(opt)) {
15237                dumpSwapPss = true;
15238            } else if ("--unreachable".equals(opt)) {
15239                dumpUnreachable = true;
15240            } else if ("--oom".equals(opt)) {
15241                oomOnly = true;
15242            } else if ("--local".equals(opt)) {
15243                localOnly = true;
15244            } else if ("--package".equals(opt)) {
15245                packages = true;
15246            } else if ("--checkin".equals(opt)) {
15247                isCheckinRequest = true;
15248
15249            } else if ("-h".equals(opt)) {
15250                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15251                pw.println("  -a: include all available information for each process.");
15252                pw.println("  -d: include dalvik details.");
15253                pw.println("  -c: dump in a compact machine-parseable representation.");
15254                pw.println("  -s: dump only summary of application memory usage.");
15255                pw.println("  -S: dump also SwapPss.");
15256                pw.println("  --oom: only show processes organized by oom adj.");
15257                pw.println("  --local: only collect details locally, don't call process.");
15258                pw.println("  --package: interpret process arg as package, dumping all");
15259                pw.println("             processes that have loaded that package.");
15260                pw.println("  --checkin: dump data for a checkin");
15261                pw.println("If [process] is specified it can be the name or ");
15262                pw.println("pid of a specific process to dump.");
15263                return;
15264            } else {
15265                pw.println("Unknown argument: " + opt + "; use -h for help");
15266            }
15267        }
15268
15269        long uptime = SystemClock.uptimeMillis();
15270        long realtime = SystemClock.elapsedRealtime();
15271        final long[] tmpLong = new long[1];
15272
15273        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15274        if (procs == null) {
15275            // No Java processes.  Maybe they want to print a native process.
15276            if (args != null && args.length > opti
15277                    && args[opti].charAt(0) != '-') {
15278                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15279                        = new ArrayList<ProcessCpuTracker.Stats>();
15280                updateCpuStatsNow();
15281                int findPid = -1;
15282                try {
15283                    findPid = Integer.parseInt(args[opti]);
15284                } catch (NumberFormatException e) {
15285                }
15286                synchronized (mProcessCpuTracker) {
15287                    final int N = mProcessCpuTracker.countStats();
15288                    for (int i=0; i<N; i++) {
15289                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15290                        if (st.pid == findPid || (st.baseName != null
15291                                && st.baseName.equals(args[opti]))) {
15292                            nativeProcs.add(st);
15293                        }
15294                    }
15295                }
15296                if (nativeProcs.size() > 0) {
15297                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15298                            isCompact);
15299                    Debug.MemoryInfo mi = null;
15300                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15301                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15302                        final int pid = r.pid;
15303                        if (!isCheckinRequest && dumpDetails) {
15304                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15305                        }
15306                        if (mi == null) {
15307                            mi = new Debug.MemoryInfo();
15308                        }
15309                        if (dumpDetails || (!brief && !oomOnly)) {
15310                            Debug.getMemoryInfo(pid, mi);
15311                        } else {
15312                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15313                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15314                        }
15315                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15316                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15317                        if (isCheckinRequest) {
15318                            pw.println();
15319                        }
15320                    }
15321                    return;
15322                }
15323            }
15324            pw.println("No process found for: " + args[opti]);
15325            return;
15326        }
15327
15328        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15329            dumpDetails = true;
15330        }
15331
15332        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15333
15334        String[] innerArgs = new String[args.length-opti];
15335        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15336
15337        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15338        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15339        long nativePss = 0;
15340        long nativeSwapPss = 0;
15341        long dalvikPss = 0;
15342        long dalvikSwapPss = 0;
15343        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15344                EmptyArray.LONG;
15345        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15346                EmptyArray.LONG;
15347        long otherPss = 0;
15348        long otherSwapPss = 0;
15349        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15350        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15351
15352        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15353        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15354        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15355                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15356
15357        long totalPss = 0;
15358        long totalSwapPss = 0;
15359        long cachedPss = 0;
15360        long cachedSwapPss = 0;
15361        boolean hasSwapPss = false;
15362
15363        Debug.MemoryInfo mi = null;
15364        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15365            final ProcessRecord r = procs.get(i);
15366            final IApplicationThread thread;
15367            final int pid;
15368            final int oomAdj;
15369            final boolean hasActivities;
15370            synchronized (this) {
15371                thread = r.thread;
15372                pid = r.pid;
15373                oomAdj = r.getSetAdjWithServices();
15374                hasActivities = r.activities.size() > 0;
15375            }
15376            if (thread != null) {
15377                if (!isCheckinRequest && dumpDetails) {
15378                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15379                }
15380                if (mi == null) {
15381                    mi = new Debug.MemoryInfo();
15382                }
15383                if (dumpDetails || (!brief && !oomOnly)) {
15384                    Debug.getMemoryInfo(pid, mi);
15385                    hasSwapPss = mi.hasSwappedOutPss;
15386                } else {
15387                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15388                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15389                }
15390                if (dumpDetails) {
15391                    if (localOnly) {
15392                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15393                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15394                        if (isCheckinRequest) {
15395                            pw.println();
15396                        }
15397                    } else {
15398                        try {
15399                            pw.flush();
15400                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15401                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15402                        } catch (RemoteException e) {
15403                            if (!isCheckinRequest) {
15404                                pw.println("Got RemoteException!");
15405                                pw.flush();
15406                            }
15407                        }
15408                    }
15409                }
15410
15411                final long myTotalPss = mi.getTotalPss();
15412                final long myTotalUss = mi.getTotalUss();
15413                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15414
15415                synchronized (this) {
15416                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15417                        // Record this for posterity if the process has been stable.
15418                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15419                    }
15420                }
15421
15422                if (!isCheckinRequest && mi != null) {
15423                    totalPss += myTotalPss;
15424                    totalSwapPss += myTotalSwapPss;
15425                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15426                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15427                            myTotalSwapPss, pid, hasActivities);
15428                    procMems.add(pssItem);
15429                    procMemsMap.put(pid, pssItem);
15430
15431                    nativePss += mi.nativePss;
15432                    nativeSwapPss += mi.nativeSwappedOutPss;
15433                    dalvikPss += mi.dalvikPss;
15434                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15435                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15436                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15437                        dalvikSubitemSwapPss[j] +=
15438                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15439                    }
15440                    otherPss += mi.otherPss;
15441                    otherSwapPss += mi.otherSwappedOutPss;
15442                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15443                        long mem = mi.getOtherPss(j);
15444                        miscPss[j] += mem;
15445                        otherPss -= mem;
15446                        mem = mi.getOtherSwappedOutPss(j);
15447                        miscSwapPss[j] += mem;
15448                        otherSwapPss -= mem;
15449                    }
15450
15451                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15452                        cachedPss += myTotalPss;
15453                        cachedSwapPss += myTotalSwapPss;
15454                    }
15455
15456                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15457                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15458                                || oomIndex == (oomPss.length-1)) {
15459                            oomPss[oomIndex] += myTotalPss;
15460                            oomSwapPss[oomIndex] += myTotalSwapPss;
15461                            if (oomProcs[oomIndex] == null) {
15462                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15463                            }
15464                            oomProcs[oomIndex].add(pssItem);
15465                            break;
15466                        }
15467                    }
15468                }
15469            }
15470        }
15471
15472        long nativeProcTotalPss = 0;
15473
15474        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15475            // If we are showing aggregations, also look for native processes to
15476            // include so that our aggregations are more accurate.
15477            updateCpuStatsNow();
15478            mi = null;
15479            synchronized (mProcessCpuTracker) {
15480                final int N = mProcessCpuTracker.countStats();
15481                for (int i=0; i<N; i++) {
15482                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15483                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15484                        if (mi == null) {
15485                            mi = new Debug.MemoryInfo();
15486                        }
15487                        if (!brief && !oomOnly) {
15488                            Debug.getMemoryInfo(st.pid, mi);
15489                        } else {
15490                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15491                            mi.nativePrivateDirty = (int)tmpLong[0];
15492                        }
15493
15494                        final long myTotalPss = mi.getTotalPss();
15495                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15496                        totalPss += myTotalPss;
15497                        nativeProcTotalPss += myTotalPss;
15498
15499                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15500                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15501                        procMems.add(pssItem);
15502
15503                        nativePss += mi.nativePss;
15504                        nativeSwapPss += mi.nativeSwappedOutPss;
15505                        dalvikPss += mi.dalvikPss;
15506                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15507                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15508                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15509                            dalvikSubitemSwapPss[j] +=
15510                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15511                        }
15512                        otherPss += mi.otherPss;
15513                        otherSwapPss += mi.otherSwappedOutPss;
15514                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15515                            long mem = mi.getOtherPss(j);
15516                            miscPss[j] += mem;
15517                            otherPss -= mem;
15518                            mem = mi.getOtherSwappedOutPss(j);
15519                            miscSwapPss[j] += mem;
15520                            otherSwapPss -= mem;
15521                        }
15522                        oomPss[0] += myTotalPss;
15523                        oomSwapPss[0] += myTotalSwapPss;
15524                        if (oomProcs[0] == null) {
15525                            oomProcs[0] = new ArrayList<MemItem>();
15526                        }
15527                        oomProcs[0].add(pssItem);
15528                    }
15529                }
15530            }
15531
15532            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15533
15534            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15535            final MemItem dalvikItem =
15536                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15537            if (dalvikSubitemPss.length > 0) {
15538                dalvikItem.subitems = new ArrayList<MemItem>();
15539                for (int j=0; j<dalvikSubitemPss.length; j++) {
15540                    final String name = Debug.MemoryInfo.getOtherLabel(
15541                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15542                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15543                                    dalvikSubitemSwapPss[j], j));
15544                }
15545            }
15546            catMems.add(dalvikItem);
15547            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15548            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15549                String label = Debug.MemoryInfo.getOtherLabel(j);
15550                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15551            }
15552
15553            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15554            for (int j=0; j<oomPss.length; j++) {
15555                if (oomPss[j] != 0) {
15556                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15557                            : DUMP_MEM_OOM_LABEL[j];
15558                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15559                            DUMP_MEM_OOM_ADJ[j]);
15560                    item.subitems = oomProcs[j];
15561                    oomMems.add(item);
15562                }
15563            }
15564
15565            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15566            if (!brief && !oomOnly && !isCompact) {
15567                pw.println();
15568                pw.println("Total PSS by process:");
15569                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15570                pw.println();
15571            }
15572            if (!isCompact) {
15573                pw.println("Total PSS by OOM adjustment:");
15574            }
15575            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15576            if (!brief && !oomOnly) {
15577                PrintWriter out = categoryPw != null ? categoryPw : pw;
15578                if (!isCompact) {
15579                    out.println();
15580                    out.println("Total PSS by category:");
15581                }
15582                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15583            }
15584            if (!isCompact) {
15585                pw.println();
15586            }
15587            MemInfoReader memInfo = new MemInfoReader();
15588            memInfo.readMemInfo();
15589            if (nativeProcTotalPss > 0) {
15590                synchronized (this) {
15591                    final long cachedKb = memInfo.getCachedSizeKb();
15592                    final long freeKb = memInfo.getFreeSizeKb();
15593                    final long zramKb = memInfo.getZramTotalSizeKb();
15594                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15595                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15596                            kernelKb*1024, nativeProcTotalPss*1024);
15597                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15598                            nativeProcTotalPss);
15599                }
15600            }
15601            if (!brief) {
15602                if (!isCompact) {
15603                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15604                    pw.print(" (status ");
15605                    switch (mLastMemoryLevel) {
15606                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15607                            pw.println("normal)");
15608                            break;
15609                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15610                            pw.println("moderate)");
15611                            break;
15612                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15613                            pw.println("low)");
15614                            break;
15615                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15616                            pw.println("critical)");
15617                            break;
15618                        default:
15619                            pw.print(mLastMemoryLevel);
15620                            pw.println(")");
15621                            break;
15622                    }
15623                    pw.print(" Free RAM: ");
15624                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15625                            + memInfo.getFreeSizeKb()));
15626                    pw.print(" (");
15627                    pw.print(stringifyKBSize(cachedPss));
15628                    pw.print(" cached pss + ");
15629                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15630                    pw.print(" cached kernel + ");
15631                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15632                    pw.println(" free)");
15633                } else {
15634                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15635                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15636                            + memInfo.getFreeSizeKb()); pw.print(",");
15637                    pw.println(totalPss - cachedPss);
15638                }
15639            }
15640            long lostRAM = memInfo.getTotalSizeKb()
15641                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15642                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15643            if (!isCompact) {
15644                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15645                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15646                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15647                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15648                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15649            } else {
15650                pw.print("lostram,"); pw.println(lostRAM);
15651            }
15652            if (!brief) {
15653                if (memInfo.getZramTotalSizeKb() != 0) {
15654                    if (!isCompact) {
15655                        pw.print("     ZRAM: ");
15656                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15657                                pw.print(" physical used for ");
15658                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15659                                        - memInfo.getSwapFreeSizeKb()));
15660                                pw.print(" in swap (");
15661                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15662                                pw.println(" total swap)");
15663                    } else {
15664                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15665                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15666                                pw.println(memInfo.getSwapFreeSizeKb());
15667                    }
15668                }
15669                final long[] ksm = getKsmInfo();
15670                if (!isCompact) {
15671                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15672                            || ksm[KSM_VOLATILE] != 0) {
15673                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15674                                pw.print(" saved from shared ");
15675                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15676                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15677                                pw.print(" unshared; ");
15678                                pw.print(stringifyKBSize(
15679                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15680                    }
15681                    pw.print("   Tuning: ");
15682                    pw.print(ActivityManager.staticGetMemoryClass());
15683                    pw.print(" (large ");
15684                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15685                    pw.print("), oom ");
15686                    pw.print(stringifySize(
15687                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15688                    pw.print(", restore limit ");
15689                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15690                    if (ActivityManager.isLowRamDeviceStatic()) {
15691                        pw.print(" (low-ram)");
15692                    }
15693                    if (ActivityManager.isHighEndGfx()) {
15694                        pw.print(" (high-end-gfx)");
15695                    }
15696                    pw.println();
15697                } else {
15698                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15699                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15700                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15701                    pw.print("tuning,");
15702                    pw.print(ActivityManager.staticGetMemoryClass());
15703                    pw.print(',');
15704                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15705                    pw.print(',');
15706                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15707                    if (ActivityManager.isLowRamDeviceStatic()) {
15708                        pw.print(",low-ram");
15709                    }
15710                    if (ActivityManager.isHighEndGfx()) {
15711                        pw.print(",high-end-gfx");
15712                    }
15713                    pw.println();
15714                }
15715            }
15716        }
15717    }
15718
15719    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15720            long memtrack, String name) {
15721        sb.append("  ");
15722        sb.append(ProcessList.makeOomAdjString(oomAdj));
15723        sb.append(' ');
15724        sb.append(ProcessList.makeProcStateString(procState));
15725        sb.append(' ');
15726        ProcessList.appendRamKb(sb, pss);
15727        sb.append(": ");
15728        sb.append(name);
15729        if (memtrack > 0) {
15730            sb.append(" (");
15731            sb.append(stringifyKBSize(memtrack));
15732            sb.append(" memtrack)");
15733        }
15734    }
15735
15736    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15737        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15738        sb.append(" (pid ");
15739        sb.append(mi.pid);
15740        sb.append(") ");
15741        sb.append(mi.adjType);
15742        sb.append('\n');
15743        if (mi.adjReason != null) {
15744            sb.append("                      ");
15745            sb.append(mi.adjReason);
15746            sb.append('\n');
15747        }
15748    }
15749
15750    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15751        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15752        for (int i=0, N=memInfos.size(); i<N; i++) {
15753            ProcessMemInfo mi = memInfos.get(i);
15754            infoMap.put(mi.pid, mi);
15755        }
15756        updateCpuStatsNow();
15757        long[] memtrackTmp = new long[1];
15758        synchronized (mProcessCpuTracker) {
15759            final int N = mProcessCpuTracker.countStats();
15760            for (int i=0; i<N; i++) {
15761                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15762                if (st.vsize > 0) {
15763                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15764                    if (pss > 0) {
15765                        if (infoMap.indexOfKey(st.pid) < 0) {
15766                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15767                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15768                            mi.pss = pss;
15769                            mi.memtrack = memtrackTmp[0];
15770                            memInfos.add(mi);
15771                        }
15772                    }
15773                }
15774            }
15775        }
15776
15777        long totalPss = 0;
15778        long totalMemtrack = 0;
15779        for (int i=0, N=memInfos.size(); i<N; i++) {
15780            ProcessMemInfo mi = memInfos.get(i);
15781            if (mi.pss == 0) {
15782                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15783                mi.memtrack = memtrackTmp[0];
15784            }
15785            totalPss += mi.pss;
15786            totalMemtrack += mi.memtrack;
15787        }
15788        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15789            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15790                if (lhs.oomAdj != rhs.oomAdj) {
15791                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15792                }
15793                if (lhs.pss != rhs.pss) {
15794                    return lhs.pss < rhs.pss ? 1 : -1;
15795                }
15796                return 0;
15797            }
15798        });
15799
15800        StringBuilder tag = new StringBuilder(128);
15801        StringBuilder stack = new StringBuilder(128);
15802        tag.append("Low on memory -- ");
15803        appendMemBucket(tag, totalPss, "total", false);
15804        appendMemBucket(stack, totalPss, "total", true);
15805
15806        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15807        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15808        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15809
15810        boolean firstLine = true;
15811        int lastOomAdj = Integer.MIN_VALUE;
15812        long extraNativeRam = 0;
15813        long extraNativeMemtrack = 0;
15814        long cachedPss = 0;
15815        for (int i=0, N=memInfos.size(); i<N; i++) {
15816            ProcessMemInfo mi = memInfos.get(i);
15817
15818            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15819                cachedPss += mi.pss;
15820            }
15821
15822            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15823                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15824                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15825                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15826                if (lastOomAdj != mi.oomAdj) {
15827                    lastOomAdj = mi.oomAdj;
15828                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15829                        tag.append(" / ");
15830                    }
15831                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15832                        if (firstLine) {
15833                            stack.append(":");
15834                            firstLine = false;
15835                        }
15836                        stack.append("\n\t at ");
15837                    } else {
15838                        stack.append("$");
15839                    }
15840                } else {
15841                    tag.append(" ");
15842                    stack.append("$");
15843                }
15844                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15845                    appendMemBucket(tag, mi.pss, mi.name, false);
15846                }
15847                appendMemBucket(stack, mi.pss, mi.name, true);
15848                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15849                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15850                    stack.append("(");
15851                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15852                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15853                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15854                            stack.append(":");
15855                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15856                        }
15857                    }
15858                    stack.append(")");
15859                }
15860            }
15861
15862            appendMemInfo(fullNativeBuilder, mi);
15863            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15864                // The short form only has native processes that are >= 512K.
15865                if (mi.pss >= 512) {
15866                    appendMemInfo(shortNativeBuilder, mi);
15867                } else {
15868                    extraNativeRam += mi.pss;
15869                    extraNativeMemtrack += mi.memtrack;
15870                }
15871            } else {
15872                // Short form has all other details, but if we have collected RAM
15873                // from smaller native processes let's dump a summary of that.
15874                if (extraNativeRam > 0) {
15875                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15876                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15877                    shortNativeBuilder.append('\n');
15878                    extraNativeRam = 0;
15879                }
15880                appendMemInfo(fullJavaBuilder, mi);
15881            }
15882        }
15883
15884        fullJavaBuilder.append("           ");
15885        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15886        fullJavaBuilder.append(": TOTAL");
15887        if (totalMemtrack > 0) {
15888            fullJavaBuilder.append(" (");
15889            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15890            fullJavaBuilder.append(" memtrack)");
15891        } else {
15892        }
15893        fullJavaBuilder.append("\n");
15894
15895        MemInfoReader memInfo = new MemInfoReader();
15896        memInfo.readMemInfo();
15897        final long[] infos = memInfo.getRawInfo();
15898
15899        StringBuilder memInfoBuilder = new StringBuilder(1024);
15900        Debug.getMemInfo(infos);
15901        memInfoBuilder.append("  MemInfo: ");
15902        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15903        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15904        memInfoBuilder.append(stringifyKBSize(
15905                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15906        memInfoBuilder.append(stringifyKBSize(
15907                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15908        memInfoBuilder.append(stringifyKBSize(
15909                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15910        memInfoBuilder.append("           ");
15911        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15912        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15913        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15914        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15915        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15916            memInfoBuilder.append("  ZRAM: ");
15917            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15918            memInfoBuilder.append(" RAM, ");
15919            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15920            memInfoBuilder.append(" swap total, ");
15921            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15922            memInfoBuilder.append(" swap free\n");
15923        }
15924        final long[] ksm = getKsmInfo();
15925        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15926                || ksm[KSM_VOLATILE] != 0) {
15927            memInfoBuilder.append("  KSM: ");
15928            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15929            memInfoBuilder.append(" saved from shared ");
15930            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15931            memInfoBuilder.append("\n       ");
15932            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15933            memInfoBuilder.append(" unshared; ");
15934            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15935            memInfoBuilder.append(" volatile\n");
15936        }
15937        memInfoBuilder.append("  Free RAM: ");
15938        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15939                + memInfo.getFreeSizeKb()));
15940        memInfoBuilder.append("\n");
15941        memInfoBuilder.append("  Used RAM: ");
15942        memInfoBuilder.append(stringifyKBSize(
15943                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15944        memInfoBuilder.append("\n");
15945        memInfoBuilder.append("  Lost RAM: ");
15946        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15947                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15948                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15949        memInfoBuilder.append("\n");
15950        Slog.i(TAG, "Low on memory:");
15951        Slog.i(TAG, shortNativeBuilder.toString());
15952        Slog.i(TAG, fullJavaBuilder.toString());
15953        Slog.i(TAG, memInfoBuilder.toString());
15954
15955        StringBuilder dropBuilder = new StringBuilder(1024);
15956        /*
15957        StringWriter oomSw = new StringWriter();
15958        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15959        StringWriter catSw = new StringWriter();
15960        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15961        String[] emptyArgs = new String[] { };
15962        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15963        oomPw.flush();
15964        String oomString = oomSw.toString();
15965        */
15966        dropBuilder.append("Low on memory:");
15967        dropBuilder.append(stack);
15968        dropBuilder.append('\n');
15969        dropBuilder.append(fullNativeBuilder);
15970        dropBuilder.append(fullJavaBuilder);
15971        dropBuilder.append('\n');
15972        dropBuilder.append(memInfoBuilder);
15973        dropBuilder.append('\n');
15974        /*
15975        dropBuilder.append(oomString);
15976        dropBuilder.append('\n');
15977        */
15978        StringWriter catSw = new StringWriter();
15979        synchronized (ActivityManagerService.this) {
15980            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15981            String[] emptyArgs = new String[] { };
15982            catPw.println();
15983            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15984            catPw.println();
15985            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15986                    false, false, null);
15987            catPw.println();
15988            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15989            catPw.flush();
15990        }
15991        dropBuilder.append(catSw.toString());
15992        addErrorToDropBox("lowmem", null, "system_server", null,
15993                null, tag.toString(), dropBuilder.toString(), null, null);
15994        //Slog.i(TAG, "Sent to dropbox:");
15995        //Slog.i(TAG, dropBuilder.toString());
15996        synchronized (ActivityManagerService.this) {
15997            long now = SystemClock.uptimeMillis();
15998            if (mLastMemUsageReportTime < now) {
15999                mLastMemUsageReportTime = now;
16000            }
16001        }
16002    }
16003
16004    /**
16005     * Searches array of arguments for the specified string
16006     * @param args array of argument strings
16007     * @param value value to search for
16008     * @return true if the value is contained in the array
16009     */
16010    private static boolean scanArgs(String[] args, String value) {
16011        if (args != null) {
16012            for (String arg : args) {
16013                if (value.equals(arg)) {
16014                    return true;
16015                }
16016            }
16017        }
16018        return false;
16019    }
16020
16021    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16022            ContentProviderRecord cpr, boolean always) {
16023        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16024
16025        if (!inLaunching || always) {
16026            synchronized (cpr) {
16027                cpr.launchingApp = null;
16028                cpr.notifyAll();
16029            }
16030            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16031            String names[] = cpr.info.authority.split(";");
16032            for (int j = 0; j < names.length; j++) {
16033                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16034            }
16035        }
16036
16037        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16038            ContentProviderConnection conn = cpr.connections.get(i);
16039            if (conn.waiting) {
16040                // If this connection is waiting for the provider, then we don't
16041                // need to mess with its process unless we are always removing
16042                // or for some reason the provider is not currently launching.
16043                if (inLaunching && !always) {
16044                    continue;
16045                }
16046            }
16047            ProcessRecord capp = conn.client;
16048            conn.dead = true;
16049            if (conn.stableCount > 0) {
16050                if (!capp.persistent && capp.thread != null
16051                        && capp.pid != 0
16052                        && capp.pid != MY_PID) {
16053                    capp.kill("depends on provider "
16054                            + cpr.name.flattenToShortString()
16055                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16056                }
16057            } else if (capp.thread != null && conn.provider.provider != null) {
16058                try {
16059                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16060                } catch (RemoteException e) {
16061                }
16062                // In the protocol here, we don't expect the client to correctly
16063                // clean up this connection, we'll just remove it.
16064                cpr.connections.remove(i);
16065                if (conn.client.conProviders.remove(conn)) {
16066                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16067                }
16068            }
16069        }
16070
16071        if (inLaunching && always) {
16072            mLaunchingProviders.remove(cpr);
16073        }
16074        return inLaunching;
16075    }
16076
16077    /**
16078     * Main code for cleaning up a process when it has gone away.  This is
16079     * called both as a result of the process dying, or directly when stopping
16080     * a process when running in single process mode.
16081     *
16082     * @return Returns true if the given process has been restarted, so the
16083     * app that was passed in must remain on the process lists.
16084     */
16085    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16086            boolean restarting, boolean allowRestart, int index) {
16087        if (index >= 0) {
16088            removeLruProcessLocked(app);
16089            ProcessList.remove(app.pid);
16090        }
16091
16092        mProcessesToGc.remove(app);
16093        mPendingPssProcesses.remove(app);
16094
16095        // Dismiss any open dialogs.
16096        if (app.crashDialog != null && !app.forceCrashReport) {
16097            app.crashDialog.dismiss();
16098            app.crashDialog = null;
16099        }
16100        if (app.anrDialog != null) {
16101            app.anrDialog.dismiss();
16102            app.anrDialog = null;
16103        }
16104        if (app.waitDialog != null) {
16105            app.waitDialog.dismiss();
16106            app.waitDialog = null;
16107        }
16108
16109        app.crashing = false;
16110        app.notResponding = false;
16111
16112        app.resetPackageList(mProcessStats);
16113        app.unlinkDeathRecipient();
16114        app.makeInactive(mProcessStats);
16115        app.waitingToKill = null;
16116        app.forcingToForeground = null;
16117        updateProcessForegroundLocked(app, false, false);
16118        app.foregroundActivities = false;
16119        app.hasShownUi = false;
16120        app.treatLikeActivity = false;
16121        app.hasAboveClient = false;
16122        app.hasClientActivities = false;
16123
16124        mServices.killServicesLocked(app, allowRestart);
16125
16126        boolean restart = false;
16127
16128        // Remove published content providers.
16129        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16130            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16131            final boolean always = app.bad || !allowRestart;
16132            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16133            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16134                // We left the provider in the launching list, need to
16135                // restart it.
16136                restart = true;
16137            }
16138
16139            cpr.provider = null;
16140            cpr.proc = null;
16141        }
16142        app.pubProviders.clear();
16143
16144        // Take care of any launching providers waiting for this process.
16145        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16146            restart = true;
16147        }
16148
16149        // Unregister from connected content providers.
16150        if (!app.conProviders.isEmpty()) {
16151            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16152                ContentProviderConnection conn = app.conProviders.get(i);
16153                conn.provider.connections.remove(conn);
16154                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16155                        conn.provider.name);
16156            }
16157            app.conProviders.clear();
16158        }
16159
16160        // At this point there may be remaining entries in mLaunchingProviders
16161        // where we were the only one waiting, so they are no longer of use.
16162        // Look for these and clean up if found.
16163        // XXX Commented out for now.  Trying to figure out a way to reproduce
16164        // the actual situation to identify what is actually going on.
16165        if (false) {
16166            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16167                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16168                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16169                    synchronized (cpr) {
16170                        cpr.launchingApp = null;
16171                        cpr.notifyAll();
16172                    }
16173                }
16174            }
16175        }
16176
16177        skipCurrentReceiverLocked(app);
16178
16179        // Unregister any receivers.
16180        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16181            removeReceiverLocked(app.receivers.valueAt(i));
16182        }
16183        app.receivers.clear();
16184
16185        // If the app is undergoing backup, tell the backup manager about it
16186        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16187            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16188                    + mBackupTarget.appInfo + " died during backup");
16189            try {
16190                IBackupManager bm = IBackupManager.Stub.asInterface(
16191                        ServiceManager.getService(Context.BACKUP_SERVICE));
16192                bm.agentDisconnected(app.info.packageName);
16193            } catch (RemoteException e) {
16194                // can't happen; backup manager is local
16195            }
16196        }
16197
16198        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16199            ProcessChangeItem item = mPendingProcessChanges.get(i);
16200            if (item.pid == app.pid) {
16201                mPendingProcessChanges.remove(i);
16202                mAvailProcessChanges.add(item);
16203            }
16204        }
16205        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16206                null).sendToTarget();
16207
16208        // If the caller is restarting this app, then leave it in its
16209        // current lists and let the caller take care of it.
16210        if (restarting) {
16211            return false;
16212        }
16213
16214        if (!app.persistent || app.isolated) {
16215            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16216                    "Removing non-persistent process during cleanup: " + app);
16217            removeProcessNameLocked(app.processName, app.uid);
16218            if (mHeavyWeightProcess == app) {
16219                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16220                        mHeavyWeightProcess.userId, 0));
16221                mHeavyWeightProcess = null;
16222            }
16223        } else if (!app.removed) {
16224            // This app is persistent, so we need to keep its record around.
16225            // If it is not already on the pending app list, add it there
16226            // and start a new process for it.
16227            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16228                mPersistentStartingProcesses.add(app);
16229                restart = true;
16230            }
16231        }
16232        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16233                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16234        mProcessesOnHold.remove(app);
16235
16236        if (app == mHomeProcess) {
16237            mHomeProcess = null;
16238        }
16239        if (app == mPreviousProcess) {
16240            mPreviousProcess = null;
16241        }
16242
16243        if (restart && !app.isolated) {
16244            // We have components that still need to be running in the
16245            // process, so re-launch it.
16246            if (index < 0) {
16247                ProcessList.remove(app.pid);
16248            }
16249            addProcessNameLocked(app);
16250            startProcessLocked(app, "restart", app.processName);
16251            return true;
16252        } else if (app.pid > 0 && app.pid != MY_PID) {
16253            // Goodbye!
16254            boolean removed;
16255            synchronized (mPidsSelfLocked) {
16256                mPidsSelfLocked.remove(app.pid);
16257                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16258            }
16259            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16260            if (app.isolated) {
16261                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16262            }
16263            app.setPid(0);
16264        }
16265        return false;
16266    }
16267
16268    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16269        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16270            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16271            if (cpr.launchingApp == app) {
16272                return true;
16273            }
16274        }
16275        return false;
16276    }
16277
16278    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16279        // Look through the content providers we are waiting to have launched,
16280        // and if any run in this process then either schedule a restart of
16281        // the process or kill the client waiting for it if this process has
16282        // gone bad.
16283        boolean restart = false;
16284        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16285            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16286            if (cpr.launchingApp == app) {
16287                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16288                    restart = true;
16289                } else {
16290                    removeDyingProviderLocked(app, cpr, true);
16291                }
16292            }
16293        }
16294        return restart;
16295    }
16296
16297    // =========================================================
16298    // SERVICES
16299    // =========================================================
16300
16301    @Override
16302    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16303            int flags) {
16304        enforceNotIsolatedCaller("getServices");
16305        synchronized (this) {
16306            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16307        }
16308    }
16309
16310    @Override
16311    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16312        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16313        synchronized (this) {
16314            return mServices.getRunningServiceControlPanelLocked(name);
16315        }
16316    }
16317
16318    @Override
16319    public ComponentName startService(IApplicationThread caller, Intent service,
16320            String resolvedType, String callingPackage, int userId)
16321            throws TransactionTooLargeException {
16322        enforceNotIsolatedCaller("startService");
16323        // Refuse possible leaked file descriptors
16324        if (service != null && service.hasFileDescriptors() == true) {
16325            throw new IllegalArgumentException("File descriptors passed in Intent");
16326        }
16327
16328        if (callingPackage == null) {
16329            throw new IllegalArgumentException("callingPackage cannot be null");
16330        }
16331
16332        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16333                "startService: " + service + " type=" + resolvedType);
16334        synchronized(this) {
16335            final int callingPid = Binder.getCallingPid();
16336            final int callingUid = Binder.getCallingUid();
16337            final long origId = Binder.clearCallingIdentity();
16338            ComponentName res = mServices.startServiceLocked(caller, service,
16339                    resolvedType, callingPid, callingUid, callingPackage, userId);
16340            Binder.restoreCallingIdentity(origId);
16341            return res;
16342        }
16343    }
16344
16345    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16346            String callingPackage, int userId)
16347            throws TransactionTooLargeException {
16348        synchronized(this) {
16349            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16350                    "startServiceInPackage: " + service + " type=" + resolvedType);
16351            final long origId = Binder.clearCallingIdentity();
16352            ComponentName res = mServices.startServiceLocked(null, service,
16353                    resolvedType, -1, uid, callingPackage, userId);
16354            Binder.restoreCallingIdentity(origId);
16355            return res;
16356        }
16357    }
16358
16359    @Override
16360    public int stopService(IApplicationThread caller, Intent service,
16361            String resolvedType, int userId) {
16362        enforceNotIsolatedCaller("stopService");
16363        // Refuse possible leaked file descriptors
16364        if (service != null && service.hasFileDescriptors() == true) {
16365            throw new IllegalArgumentException("File descriptors passed in Intent");
16366        }
16367
16368        synchronized(this) {
16369            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16370        }
16371    }
16372
16373    @Override
16374    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16375        enforceNotIsolatedCaller("peekService");
16376        // Refuse possible leaked file descriptors
16377        if (service != null && service.hasFileDescriptors() == true) {
16378            throw new IllegalArgumentException("File descriptors passed in Intent");
16379        }
16380
16381        if (callingPackage == null) {
16382            throw new IllegalArgumentException("callingPackage cannot be null");
16383        }
16384
16385        synchronized(this) {
16386            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16387        }
16388    }
16389
16390    @Override
16391    public boolean stopServiceToken(ComponentName className, IBinder token,
16392            int startId) {
16393        synchronized(this) {
16394            return mServices.stopServiceTokenLocked(className, token, startId);
16395        }
16396    }
16397
16398    @Override
16399    public void setServiceForeground(ComponentName className, IBinder token,
16400            int id, Notification notification, boolean removeNotification) {
16401        synchronized(this) {
16402            mServices.setServiceForegroundLocked(className, token, id, notification,
16403                    removeNotification);
16404        }
16405    }
16406
16407    @Override
16408    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16409            boolean requireFull, String name, String callerPackage) {
16410        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16411                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16412    }
16413
16414    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16415            String className, int flags) {
16416        boolean result = false;
16417        // For apps that don't have pre-defined UIDs, check for permission
16418        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16419            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16420                if (ActivityManager.checkUidPermission(
16421                        INTERACT_ACROSS_USERS,
16422                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16423                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16424                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16425                            + " requests FLAG_SINGLE_USER, but app does not hold "
16426                            + INTERACT_ACROSS_USERS;
16427                    Slog.w(TAG, msg);
16428                    throw new SecurityException(msg);
16429                }
16430                // Permission passed
16431                result = true;
16432            }
16433        } else if ("system".equals(componentProcessName)) {
16434            result = true;
16435        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16436            // Phone app and persistent apps are allowed to export singleuser providers.
16437            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16438                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16439        }
16440        if (DEBUG_MU) Slog.v(TAG_MU,
16441                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16442                + Integer.toHexString(flags) + ") = " + result);
16443        return result;
16444    }
16445
16446    /**
16447     * Checks to see if the caller is in the same app as the singleton
16448     * component, or the component is in a special app. It allows special apps
16449     * to export singleton components but prevents exporting singleton
16450     * components for regular apps.
16451     */
16452    boolean isValidSingletonCall(int callingUid, int componentUid) {
16453        int componentAppId = UserHandle.getAppId(componentUid);
16454        return UserHandle.isSameApp(callingUid, componentUid)
16455                || componentAppId == Process.SYSTEM_UID
16456                || componentAppId == Process.PHONE_UID
16457                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16458                        == PackageManager.PERMISSION_GRANTED;
16459    }
16460
16461    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16462            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16463            int userId) throws TransactionTooLargeException {
16464        enforceNotIsolatedCaller("bindService");
16465
16466        // Refuse possible leaked file descriptors
16467        if (service != null && service.hasFileDescriptors() == true) {
16468            throw new IllegalArgumentException("File descriptors passed in Intent");
16469        }
16470
16471        if (callingPackage == null) {
16472            throw new IllegalArgumentException("callingPackage cannot be null");
16473        }
16474
16475        synchronized(this) {
16476            return mServices.bindServiceLocked(caller, token, service,
16477                    resolvedType, connection, flags, callingPackage, userId);
16478        }
16479    }
16480
16481    public boolean unbindService(IServiceConnection connection) {
16482        synchronized (this) {
16483            return mServices.unbindServiceLocked(connection);
16484        }
16485    }
16486
16487    public void publishService(IBinder token, Intent intent, IBinder service) {
16488        // Refuse possible leaked file descriptors
16489        if (intent != null && intent.hasFileDescriptors() == true) {
16490            throw new IllegalArgumentException("File descriptors passed in Intent");
16491        }
16492
16493        synchronized(this) {
16494            if (!(token instanceof ServiceRecord)) {
16495                throw new IllegalArgumentException("Invalid service token");
16496            }
16497            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16498        }
16499    }
16500
16501    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16502        // Refuse possible leaked file descriptors
16503        if (intent != null && intent.hasFileDescriptors() == true) {
16504            throw new IllegalArgumentException("File descriptors passed in Intent");
16505        }
16506
16507        synchronized(this) {
16508            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16509        }
16510    }
16511
16512    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16513        synchronized(this) {
16514            if (!(token instanceof ServiceRecord)) {
16515                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16516                throw new IllegalArgumentException("Invalid service token");
16517            }
16518            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16519        }
16520    }
16521
16522    // =========================================================
16523    // BACKUP AND RESTORE
16524    // =========================================================
16525
16526    // Cause the target app to be launched if necessary and its backup agent
16527    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16528    // activity manager to announce its creation.
16529    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16530        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16531                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16532        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16533
16534        synchronized(this) {
16535            // !!! TODO: currently no check here that we're already bound
16536            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16537            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16538            synchronized (stats) {
16539                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16540            }
16541
16542            // Backup agent is now in use, its package can't be stopped.
16543            try {
16544                AppGlobals.getPackageManager().setPackageStoppedState(
16545                        app.packageName, false, UserHandle.getUserId(app.uid));
16546            } catch (RemoteException e) {
16547            } catch (IllegalArgumentException e) {
16548                Slog.w(TAG, "Failed trying to unstop package "
16549                        + app.packageName + ": " + e);
16550            }
16551
16552            BackupRecord r = new BackupRecord(ss, app, backupMode);
16553            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16554                    ? new ComponentName(app.packageName, app.backupAgentName)
16555                    : new ComponentName("android", "FullBackupAgent");
16556            // startProcessLocked() returns existing proc's record if it's already running
16557            ProcessRecord proc = startProcessLocked(app.processName, app,
16558                    false, 0, "backup", hostingName, false, false, false);
16559            if (proc == null) {
16560                Slog.e(TAG, "Unable to start backup agent process " + r);
16561                return false;
16562            }
16563
16564            r.app = proc;
16565            mBackupTarget = r;
16566            mBackupAppName = app.packageName;
16567
16568            // Try not to kill the process during backup
16569            updateOomAdjLocked(proc);
16570
16571            // If the process is already attached, schedule the creation of the backup agent now.
16572            // If it is not yet live, this will be done when it attaches to the framework.
16573            if (proc.thread != null) {
16574                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16575                try {
16576                    proc.thread.scheduleCreateBackupAgent(app,
16577                            compatibilityInfoForPackageLocked(app), backupMode);
16578                } catch (RemoteException e) {
16579                    // Will time out on the backup manager side
16580                }
16581            } else {
16582                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16583            }
16584            // Invariants: at this point, the target app process exists and the application
16585            // is either already running or in the process of coming up.  mBackupTarget and
16586            // mBackupAppName describe the app, so that when it binds back to the AM we
16587            // know that it's scheduled for a backup-agent operation.
16588        }
16589
16590        return true;
16591    }
16592
16593    @Override
16594    public void clearPendingBackup() {
16595        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16596        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16597
16598        synchronized (this) {
16599            mBackupTarget = null;
16600            mBackupAppName = null;
16601        }
16602    }
16603
16604    // A backup agent has just come up
16605    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16606        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16607                + " = " + agent);
16608
16609        synchronized(this) {
16610            if (!agentPackageName.equals(mBackupAppName)) {
16611                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16612                return;
16613            }
16614        }
16615
16616        long oldIdent = Binder.clearCallingIdentity();
16617        try {
16618            IBackupManager bm = IBackupManager.Stub.asInterface(
16619                    ServiceManager.getService(Context.BACKUP_SERVICE));
16620            bm.agentConnected(agentPackageName, agent);
16621        } catch (RemoteException e) {
16622            // can't happen; the backup manager service is local
16623        } catch (Exception e) {
16624            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16625            e.printStackTrace();
16626        } finally {
16627            Binder.restoreCallingIdentity(oldIdent);
16628        }
16629    }
16630
16631    // done with this agent
16632    public void unbindBackupAgent(ApplicationInfo appInfo) {
16633        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16634        if (appInfo == null) {
16635            Slog.w(TAG, "unbind backup agent for null app");
16636            return;
16637        }
16638
16639        synchronized(this) {
16640            try {
16641                if (mBackupAppName == null) {
16642                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16643                    return;
16644                }
16645
16646                if (!mBackupAppName.equals(appInfo.packageName)) {
16647                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16648                    return;
16649                }
16650
16651                // Not backing this app up any more; reset its OOM adjustment
16652                final ProcessRecord proc = mBackupTarget.app;
16653                updateOomAdjLocked(proc);
16654
16655                // If the app crashed during backup, 'thread' will be null here
16656                if (proc.thread != null) {
16657                    try {
16658                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16659                                compatibilityInfoForPackageLocked(appInfo));
16660                    } catch (Exception e) {
16661                        Slog.e(TAG, "Exception when unbinding backup agent:");
16662                        e.printStackTrace();
16663                    }
16664                }
16665            } finally {
16666                mBackupTarget = null;
16667                mBackupAppName = null;
16668            }
16669        }
16670    }
16671    // =========================================================
16672    // BROADCASTS
16673    // =========================================================
16674
16675    boolean isPendingBroadcastProcessLocked(int pid) {
16676        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16677                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16678    }
16679
16680    void skipPendingBroadcastLocked(int pid) {
16681            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16682            for (BroadcastQueue queue : mBroadcastQueues) {
16683                queue.skipPendingBroadcastLocked(pid);
16684            }
16685    }
16686
16687    // The app just attached; send any pending broadcasts that it should receive
16688    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16689        boolean didSomething = false;
16690        for (BroadcastQueue queue : mBroadcastQueues) {
16691            didSomething |= queue.sendPendingBroadcastsLocked(app);
16692        }
16693        return didSomething;
16694    }
16695
16696    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16697            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16698        enforceNotIsolatedCaller("registerReceiver");
16699        ArrayList<Intent> stickyIntents = null;
16700        ProcessRecord callerApp = null;
16701        int callingUid;
16702        int callingPid;
16703        synchronized(this) {
16704            if (caller != null) {
16705                callerApp = getRecordForAppLocked(caller);
16706                if (callerApp == null) {
16707                    throw new SecurityException(
16708                            "Unable to find app for caller " + caller
16709                            + " (pid=" + Binder.getCallingPid()
16710                            + ") when registering receiver " + receiver);
16711                }
16712                if (callerApp.info.uid != Process.SYSTEM_UID &&
16713                        !callerApp.pkgList.containsKey(callerPackage) &&
16714                        !"android".equals(callerPackage)) {
16715                    throw new SecurityException("Given caller package " + callerPackage
16716                            + " is not running in process " + callerApp);
16717                }
16718                callingUid = callerApp.info.uid;
16719                callingPid = callerApp.pid;
16720            } else {
16721                callerPackage = null;
16722                callingUid = Binder.getCallingUid();
16723                callingPid = Binder.getCallingPid();
16724            }
16725
16726            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16727                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16728
16729            Iterator<String> actions = filter.actionsIterator();
16730            if (actions == null) {
16731                ArrayList<String> noAction = new ArrayList<String>(1);
16732                noAction.add(null);
16733                actions = noAction.iterator();
16734            }
16735
16736            // Collect stickies of users
16737            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16738            while (actions.hasNext()) {
16739                String action = actions.next();
16740                for (int id : userIds) {
16741                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16742                    if (stickies != null) {
16743                        ArrayList<Intent> intents = stickies.get(action);
16744                        if (intents != null) {
16745                            if (stickyIntents == null) {
16746                                stickyIntents = new ArrayList<Intent>();
16747                            }
16748                            stickyIntents.addAll(intents);
16749                        }
16750                    }
16751                }
16752            }
16753        }
16754
16755        ArrayList<Intent> allSticky = null;
16756        if (stickyIntents != null) {
16757            final ContentResolver resolver = mContext.getContentResolver();
16758            // Look for any matching sticky broadcasts...
16759            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16760                Intent intent = stickyIntents.get(i);
16761                // If intent has scheme "content", it will need to acccess
16762                // provider that needs to lock mProviderMap in ActivityThread
16763                // and also it may need to wait application response, so we
16764                // cannot lock ActivityManagerService here.
16765                if (filter.match(resolver, intent, true, TAG) >= 0) {
16766                    if (allSticky == null) {
16767                        allSticky = new ArrayList<Intent>();
16768                    }
16769                    allSticky.add(intent);
16770                }
16771            }
16772        }
16773
16774        // The first sticky in the list is returned directly back to the client.
16775        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16776        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16777        if (receiver == null) {
16778            return sticky;
16779        }
16780
16781        synchronized (this) {
16782            if (callerApp != null && (callerApp.thread == null
16783                    || callerApp.thread.asBinder() != caller.asBinder())) {
16784                // Original caller already died
16785                return null;
16786            }
16787            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16788            if (rl == null) {
16789                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16790                        userId, receiver);
16791                if (rl.app != null) {
16792                    rl.app.receivers.add(rl);
16793                } else {
16794                    try {
16795                        receiver.asBinder().linkToDeath(rl, 0);
16796                    } catch (RemoteException e) {
16797                        return sticky;
16798                    }
16799                    rl.linkedToDeath = true;
16800                }
16801                mRegisteredReceivers.put(receiver.asBinder(), rl);
16802            } else if (rl.uid != callingUid) {
16803                throw new IllegalArgumentException(
16804                        "Receiver requested to register for uid " + callingUid
16805                        + " was previously registered for uid " + rl.uid);
16806            } else if (rl.pid != callingPid) {
16807                throw new IllegalArgumentException(
16808                        "Receiver requested to register for pid " + callingPid
16809                        + " was previously registered for pid " + rl.pid);
16810            } else if (rl.userId != userId) {
16811                throw new IllegalArgumentException(
16812                        "Receiver requested to register for user " + userId
16813                        + " was previously registered for user " + rl.userId);
16814            }
16815            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16816                    permission, callingUid, userId);
16817            rl.add(bf);
16818            if (!bf.debugCheck()) {
16819                Slog.w(TAG, "==> For Dynamic broadcast");
16820            }
16821            mReceiverResolver.addFilter(bf);
16822
16823            // Enqueue broadcasts for all existing stickies that match
16824            // this filter.
16825            if (allSticky != null) {
16826                ArrayList receivers = new ArrayList();
16827                receivers.add(bf);
16828
16829                final int stickyCount = allSticky.size();
16830                for (int i = 0; i < stickyCount; i++) {
16831                    Intent intent = allSticky.get(i);
16832                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16833                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16834                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16835                            null, 0, null, null, false, true, true, -1);
16836                    queue.enqueueParallelBroadcastLocked(r);
16837                    queue.scheduleBroadcastsLocked();
16838                }
16839            }
16840
16841            return sticky;
16842        }
16843    }
16844
16845    public void unregisterReceiver(IIntentReceiver receiver) {
16846        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16847
16848        final long origId = Binder.clearCallingIdentity();
16849        try {
16850            boolean doTrim = false;
16851
16852            synchronized(this) {
16853                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16854                if (rl != null) {
16855                    final BroadcastRecord r = rl.curBroadcast;
16856                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16857                        final boolean doNext = r.queue.finishReceiverLocked(
16858                                r, r.resultCode, r.resultData, r.resultExtras,
16859                                r.resultAbort, false);
16860                        if (doNext) {
16861                            doTrim = true;
16862                            r.queue.processNextBroadcast(false);
16863                        }
16864                    }
16865
16866                    if (rl.app != null) {
16867                        rl.app.receivers.remove(rl);
16868                    }
16869                    removeReceiverLocked(rl);
16870                    if (rl.linkedToDeath) {
16871                        rl.linkedToDeath = false;
16872                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16873                    }
16874                }
16875            }
16876
16877            // If we actually concluded any broadcasts, we might now be able
16878            // to trim the recipients' apps from our working set
16879            if (doTrim) {
16880                trimApplications();
16881                return;
16882            }
16883
16884        } finally {
16885            Binder.restoreCallingIdentity(origId);
16886        }
16887    }
16888
16889    void removeReceiverLocked(ReceiverList rl) {
16890        mRegisteredReceivers.remove(rl.receiver.asBinder());
16891        for (int i = rl.size() - 1; i >= 0; i--) {
16892            mReceiverResolver.removeFilter(rl.get(i));
16893        }
16894    }
16895
16896    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16897        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16898            ProcessRecord r = mLruProcesses.get(i);
16899            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16900                try {
16901                    r.thread.dispatchPackageBroadcast(cmd, packages);
16902                } catch (RemoteException ex) {
16903                }
16904            }
16905        }
16906    }
16907
16908    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16909            int callingUid, int[] users) {
16910        // TODO: come back and remove this assumption to triage all broadcasts
16911        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16912
16913        List<ResolveInfo> receivers = null;
16914        try {
16915            HashSet<ComponentName> singleUserReceivers = null;
16916            boolean scannedFirstReceivers = false;
16917            for (int user : users) {
16918                // Skip users that have Shell restrictions, with exception of always permitted
16919                // Shell broadcasts
16920                if (callingUid == Process.SHELL_UID
16921                        && mUserController.hasUserRestriction(
16922                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16923                        && !isPermittedShellBroadcast(intent)) {
16924                    continue;
16925                }
16926                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16927                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16928                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16929                    // If this is not the system user, we need to check for
16930                    // any receivers that should be filtered out.
16931                    for (int i=0; i<newReceivers.size(); i++) {
16932                        ResolveInfo ri = newReceivers.get(i);
16933                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16934                            newReceivers.remove(i);
16935                            i--;
16936                        }
16937                    }
16938                }
16939                if (newReceivers != null && newReceivers.size() == 0) {
16940                    newReceivers = null;
16941                }
16942                if (receivers == null) {
16943                    receivers = newReceivers;
16944                } else if (newReceivers != null) {
16945                    // We need to concatenate the additional receivers
16946                    // found with what we have do far.  This would be easy,
16947                    // but we also need to de-dup any receivers that are
16948                    // singleUser.
16949                    if (!scannedFirstReceivers) {
16950                        // Collect any single user receivers we had already retrieved.
16951                        scannedFirstReceivers = true;
16952                        for (int i=0; i<receivers.size(); i++) {
16953                            ResolveInfo ri = receivers.get(i);
16954                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16955                                ComponentName cn = new ComponentName(
16956                                        ri.activityInfo.packageName, ri.activityInfo.name);
16957                                if (singleUserReceivers == null) {
16958                                    singleUserReceivers = new HashSet<ComponentName>();
16959                                }
16960                                singleUserReceivers.add(cn);
16961                            }
16962                        }
16963                    }
16964                    // Add the new results to the existing results, tracking
16965                    // and de-dupping single user receivers.
16966                    for (int i=0; i<newReceivers.size(); i++) {
16967                        ResolveInfo ri = newReceivers.get(i);
16968                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16969                            ComponentName cn = new ComponentName(
16970                                    ri.activityInfo.packageName, ri.activityInfo.name);
16971                            if (singleUserReceivers == null) {
16972                                singleUserReceivers = new HashSet<ComponentName>();
16973                            }
16974                            if (!singleUserReceivers.contains(cn)) {
16975                                singleUserReceivers.add(cn);
16976                                receivers.add(ri);
16977                            }
16978                        } else {
16979                            receivers.add(ri);
16980                        }
16981                    }
16982                }
16983            }
16984        } catch (RemoteException ex) {
16985            // pm is in same process, this will never happen.
16986        }
16987        return receivers;
16988    }
16989
16990    private boolean isPermittedShellBroadcast(Intent intent) {
16991        // remote bugreport should always be allowed to be taken
16992        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
16993    }
16994
16995    final int broadcastIntentLocked(ProcessRecord callerApp,
16996            String callerPackage, Intent intent, String resolvedType,
16997            IIntentReceiver resultTo, int resultCode, String resultData,
16998            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16999            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17000        intent = new Intent(intent);
17001
17002        // By default broadcasts do not go to stopped apps.
17003        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17004
17005        // If we have not finished booting, don't allow this to launch new processes.
17006        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17007            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17008        }
17009
17010        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17011                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17012                + " ordered=" + ordered + " userid=" + userId);
17013        if ((resultTo != null) && !ordered) {
17014            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17015        }
17016
17017        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17018                ALLOW_NON_FULL, "broadcast", callerPackage);
17019
17020        // Make sure that the user who is receiving this broadcast is running.
17021        // If not, we will just skip it. Make an exception for shutdown broadcasts
17022        // and upgrade steps.
17023
17024        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17025            if ((callingUid != Process.SYSTEM_UID
17026                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17027                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17028                Slog.w(TAG, "Skipping broadcast of " + intent
17029                        + ": user " + userId + " is stopped");
17030                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17031            }
17032        }
17033
17034        BroadcastOptions brOptions = null;
17035        if (bOptions != null) {
17036            brOptions = new BroadcastOptions(bOptions);
17037            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17038                // See if the caller is allowed to do this.  Note we are checking against
17039                // the actual real caller (not whoever provided the operation as say a
17040                // PendingIntent), because that who is actually supplied the arguments.
17041                if (checkComponentPermission(
17042                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17043                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17044                        != PackageManager.PERMISSION_GRANTED) {
17045                    String msg = "Permission Denial: " + intent.getAction()
17046                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17047                            + ", uid=" + callingUid + ")"
17048                            + " requires "
17049                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17050                    Slog.w(TAG, msg);
17051                    throw new SecurityException(msg);
17052                }
17053            }
17054        }
17055
17056        // Verify that protected broadcasts are only being sent by system code,
17057        // and that system code is only sending protected broadcasts.
17058        final String action = intent.getAction();
17059        final boolean isProtectedBroadcast;
17060        try {
17061            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17062        } catch (RemoteException e) {
17063            Slog.w(TAG, "Remote exception", e);
17064            return ActivityManager.BROADCAST_SUCCESS;
17065        }
17066
17067        final boolean isCallerSystem;
17068        switch (UserHandle.getAppId(callingUid)) {
17069            case Process.ROOT_UID:
17070            case Process.SYSTEM_UID:
17071            case Process.PHONE_UID:
17072            case Process.BLUETOOTH_UID:
17073            case Process.NFC_UID:
17074                isCallerSystem = true;
17075                break;
17076            default:
17077                isCallerSystem = (callerApp != null) && callerApp.persistent;
17078                break;
17079        }
17080
17081        if (isCallerSystem) {
17082            if (isProtectedBroadcast
17083                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17084                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17085                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17086                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17087                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17088                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17089                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17090                // Broadcast is either protected, or it's a public action that
17091                // we've relaxed, so it's fine for system internals to send.
17092            } else {
17093                // The vast majority of broadcasts sent from system internals
17094                // should be protected to avoid security holes, so yell loudly
17095                // to ensure we examine these cases.
17096                Log.wtf(TAG, "Sending non-protected broadcast " + action
17097                        + " from system", new Throwable());
17098            }
17099
17100        } else {
17101            if (isProtectedBroadcast) {
17102                String msg = "Permission Denial: not allowed to send broadcast "
17103                        + action + " from pid="
17104                        + callingPid + ", uid=" + callingUid;
17105                Slog.w(TAG, msg);
17106                throw new SecurityException(msg);
17107
17108            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17109                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17110                // Special case for compatibility: we don't want apps to send this,
17111                // but historically it has not been protected and apps may be using it
17112                // to poke their own app widget.  So, instead of making it protected,
17113                // just limit it to the caller.
17114                if (callerApp == null) {
17115                    String msg = "Permission Denial: not allowed to send broadcast "
17116                            + action + " from unknown caller.";
17117                    Slog.w(TAG, msg);
17118                    throw new SecurityException(msg);
17119                } else if (intent.getComponent() != null) {
17120                    // They are good enough to send to an explicit component...  verify
17121                    // it is being sent to the calling app.
17122                    if (!intent.getComponent().getPackageName().equals(
17123                            callerApp.info.packageName)) {
17124                        String msg = "Permission Denial: not allowed to send broadcast "
17125                                + action + " to "
17126                                + intent.getComponent().getPackageName() + " from "
17127                                + callerApp.info.packageName;
17128                        Slog.w(TAG, msg);
17129                        throw new SecurityException(msg);
17130                    }
17131                } else {
17132                    // Limit broadcast to their own package.
17133                    intent.setPackage(callerApp.info.packageName);
17134                }
17135            }
17136        }
17137
17138        if (action != null) {
17139            switch (action) {
17140                case Intent.ACTION_UID_REMOVED:
17141                case Intent.ACTION_PACKAGE_REMOVED:
17142                case Intent.ACTION_PACKAGE_CHANGED:
17143                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17144                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17145                case Intent.ACTION_PACKAGES_SUSPENDED:
17146                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17147                    // Handle special intents: if this broadcast is from the package
17148                    // manager about a package being removed, we need to remove all of
17149                    // its activities from the history stack.
17150                    if (checkComponentPermission(
17151                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17152                            callingPid, callingUid, -1, true)
17153                            != PackageManager.PERMISSION_GRANTED) {
17154                        String msg = "Permission Denial: " + intent.getAction()
17155                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17156                                + ", uid=" + callingUid + ")"
17157                                + " requires "
17158                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17159                        Slog.w(TAG, msg);
17160                        throw new SecurityException(msg);
17161                    }
17162                    switch (action) {
17163                        case Intent.ACTION_UID_REMOVED:
17164                            final Bundle intentExtras = intent.getExtras();
17165                            final int uid = intentExtras != null
17166                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17167                            if (uid >= 0) {
17168                                mBatteryStatsService.removeUid(uid);
17169                                mAppOpsService.uidRemoved(uid);
17170                            }
17171                            break;
17172                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17173                            // If resources are unavailable just force stop all those packages
17174                            // and flush the attribute cache as well.
17175                            String list[] =
17176                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17177                            if (list != null && list.length > 0) {
17178                                for (int i = 0; i < list.length; i++) {
17179                                    forceStopPackageLocked(list[i], -1, false, true, true,
17180                                            false, false, userId, "storage unmount");
17181                                }
17182                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17183                                sendPackageBroadcastLocked(
17184                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17185                                        userId);
17186                            }
17187                            break;
17188                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17189                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17190                            break;
17191                        case Intent.ACTION_PACKAGE_REMOVED:
17192                        case Intent.ACTION_PACKAGE_CHANGED:
17193                            Uri data = intent.getData();
17194                            String ssp;
17195                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17196                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17197                                boolean fullUninstall = removed &&
17198                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17199                                final boolean killProcess =
17200                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17201                                if (killProcess) {
17202                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17203                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17204                                            false, true, true, false, fullUninstall, userId,
17205                                            removed ? "pkg removed" : "pkg changed");
17206                                }
17207                                if (removed) {
17208                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17209                                            new String[] {ssp}, userId);
17210                                    if (fullUninstall) {
17211                                        mAppOpsService.packageRemoved(
17212                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17213
17214                                        // Remove all permissions granted from/to this package
17215                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17216
17217                                        removeTasksByPackageNameLocked(ssp, userId);
17218                                        mBatteryStatsService.notePackageUninstalled(ssp);
17219                                    }
17220                                } else {
17221                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17222                                            intent.getStringArrayExtra(
17223                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17224                                }
17225                            }
17226                            break;
17227                        case Intent.ACTION_PACKAGES_SUSPENDED:
17228                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17229                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17230                                    intent.getAction());
17231                            final String[] packageNames = intent.getStringArrayExtra(
17232                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17233                            final int userHandle = intent.getIntExtra(
17234                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17235
17236                            synchronized(ActivityManagerService.this) {
17237                                mRecentTasks.onPackagesSuspendedChanged(
17238                                        packageNames, suspended, userHandle);
17239                            }
17240                            break;
17241                    }
17242                    break;
17243                case Intent.ACTION_PACKAGE_ADDED:
17244                    // Special case for adding a package: by default turn on compatibility mode.
17245                    Uri data = intent.getData();
17246                    String ssp;
17247                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17248                        final boolean replacing =
17249                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17250                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17251
17252                        try {
17253                            ApplicationInfo ai = AppGlobals.getPackageManager().
17254                                    getApplicationInfo(ssp, 0, 0);
17255                            mBatteryStatsService.notePackageInstalled(ssp,
17256                                    ai != null ? ai.versionCode : 0);
17257                        } catch (RemoteException e) {
17258                        }
17259                    }
17260                    break;
17261                case Intent.ACTION_TIMEZONE_CHANGED:
17262                    // If this is the time zone changed action, queue up a message that will reset
17263                    // the timezone of all currently running processes. This message will get
17264                    // queued up before the broadcast happens.
17265                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17266                    break;
17267                case Intent.ACTION_TIME_CHANGED:
17268                    // If the user set the time, let all running processes know.
17269                    final int is24Hour =
17270                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17271                                    : 0;
17272                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17273                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17274                    synchronized (stats) {
17275                        stats.noteCurrentTimeChangedLocked();
17276                    }
17277                    break;
17278                case Intent.ACTION_CLEAR_DNS_CACHE:
17279                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17280                    break;
17281                case Proxy.PROXY_CHANGE_ACTION:
17282                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17283                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17284                    break;
17285                case android.hardware.Camera.ACTION_NEW_PICTURE:
17286                case android.hardware.Camera.ACTION_NEW_VIDEO:
17287                    // These broadcasts are no longer allowed by the system, since they can
17288                    // cause significant thrashing at a crictical point (using the camera).
17289                    // Apps should use JobScehduler to monitor for media provider changes.
17290                    Slog.w(TAG, action + " no longer allowed; dropping from "
17291                            + UserHandle.formatUid(callingUid));
17292                    // Lie; we don't want to crash the app.
17293                    return ActivityManager.BROADCAST_SUCCESS;
17294            }
17295        }
17296
17297        // Add to the sticky list if requested.
17298        if (sticky) {
17299            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17300                    callingPid, callingUid)
17301                    != PackageManager.PERMISSION_GRANTED) {
17302                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17303                        + callingPid + ", uid=" + callingUid
17304                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17305                Slog.w(TAG, msg);
17306                throw new SecurityException(msg);
17307            }
17308            if (requiredPermissions != null && requiredPermissions.length > 0) {
17309                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17310                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17311                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17312            }
17313            if (intent.getComponent() != null) {
17314                throw new SecurityException(
17315                        "Sticky broadcasts can't target a specific component");
17316            }
17317            // We use userId directly here, since the "all" target is maintained
17318            // as a separate set of sticky broadcasts.
17319            if (userId != UserHandle.USER_ALL) {
17320                // But first, if this is not a broadcast to all users, then
17321                // make sure it doesn't conflict with an existing broadcast to
17322                // all users.
17323                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17324                        UserHandle.USER_ALL);
17325                if (stickies != null) {
17326                    ArrayList<Intent> list = stickies.get(intent.getAction());
17327                    if (list != null) {
17328                        int N = list.size();
17329                        int i;
17330                        for (i=0; i<N; i++) {
17331                            if (intent.filterEquals(list.get(i))) {
17332                                throw new IllegalArgumentException(
17333                                        "Sticky broadcast " + intent + " for user "
17334                                        + userId + " conflicts with existing global broadcast");
17335                            }
17336                        }
17337                    }
17338                }
17339            }
17340            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17341            if (stickies == null) {
17342                stickies = new ArrayMap<>();
17343                mStickyBroadcasts.put(userId, stickies);
17344            }
17345            ArrayList<Intent> list = stickies.get(intent.getAction());
17346            if (list == null) {
17347                list = new ArrayList<>();
17348                stickies.put(intent.getAction(), list);
17349            }
17350            final int stickiesCount = list.size();
17351            int i;
17352            for (i = 0; i < stickiesCount; i++) {
17353                if (intent.filterEquals(list.get(i))) {
17354                    // This sticky already exists, replace it.
17355                    list.set(i, new Intent(intent));
17356                    break;
17357                }
17358            }
17359            if (i >= stickiesCount) {
17360                list.add(new Intent(intent));
17361            }
17362        }
17363
17364        int[] users;
17365        if (userId == UserHandle.USER_ALL) {
17366            // Caller wants broadcast to go to all started users.
17367            users = mUserController.getStartedUserArrayLocked();
17368        } else {
17369            // Caller wants broadcast to go to one specific user.
17370            users = new int[] {userId};
17371        }
17372
17373        // Figure out who all will receive this broadcast.
17374        List receivers = null;
17375        List<BroadcastFilter> registeredReceivers = null;
17376        // Need to resolve the intent to interested receivers...
17377        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17378                 == 0) {
17379            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17380        }
17381        if (intent.getComponent() == null) {
17382            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17383                // Query one target user at a time, excluding shell-restricted users
17384                for (int i = 0; i < users.length; i++) {
17385                    if (mUserController.hasUserRestriction(
17386                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17387                        continue;
17388                    }
17389                    List<BroadcastFilter> registeredReceiversForUser =
17390                            mReceiverResolver.queryIntent(intent,
17391                                    resolvedType, false, users[i]);
17392                    if (registeredReceivers == null) {
17393                        registeredReceivers = registeredReceiversForUser;
17394                    } else if (registeredReceiversForUser != null) {
17395                        registeredReceivers.addAll(registeredReceiversForUser);
17396                    }
17397                }
17398            } else {
17399                registeredReceivers = mReceiverResolver.queryIntent(intent,
17400                        resolvedType, false, userId);
17401            }
17402        }
17403
17404        final boolean replacePending =
17405                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17406
17407        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17408                + " replacePending=" + replacePending);
17409
17410        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17411        if (!ordered && NR > 0) {
17412            // If we are not serializing this broadcast, then send the
17413            // registered receivers separately so they don't wait for the
17414            // components to be launched.
17415            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17416            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17417                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17418                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17419                    resultExtras, ordered, sticky, false, userId);
17420            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17421            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17422            if (!replaced) {
17423                queue.enqueueParallelBroadcastLocked(r);
17424                queue.scheduleBroadcastsLocked();
17425            }
17426            registeredReceivers = null;
17427            NR = 0;
17428        }
17429
17430        // Merge into one list.
17431        int ir = 0;
17432        if (receivers != null) {
17433            // A special case for PACKAGE_ADDED: do not allow the package
17434            // being added to see this broadcast.  This prevents them from
17435            // using this as a back door to get run as soon as they are
17436            // installed.  Maybe in the future we want to have a special install
17437            // broadcast or such for apps, but we'd like to deliberately make
17438            // this decision.
17439            String skipPackages[] = null;
17440            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17441                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17442                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17443                Uri data = intent.getData();
17444                if (data != null) {
17445                    String pkgName = data.getSchemeSpecificPart();
17446                    if (pkgName != null) {
17447                        skipPackages = new String[] { pkgName };
17448                    }
17449                }
17450            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17451                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17452            }
17453            if (skipPackages != null && (skipPackages.length > 0)) {
17454                for (String skipPackage : skipPackages) {
17455                    if (skipPackage != null) {
17456                        int NT = receivers.size();
17457                        for (int it=0; it<NT; it++) {
17458                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17459                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17460                                receivers.remove(it);
17461                                it--;
17462                                NT--;
17463                            }
17464                        }
17465                    }
17466                }
17467            }
17468
17469            int NT = receivers != null ? receivers.size() : 0;
17470            int it = 0;
17471            ResolveInfo curt = null;
17472            BroadcastFilter curr = null;
17473            while (it < NT && ir < NR) {
17474                if (curt == null) {
17475                    curt = (ResolveInfo)receivers.get(it);
17476                }
17477                if (curr == null) {
17478                    curr = registeredReceivers.get(ir);
17479                }
17480                if (curr.getPriority() >= curt.priority) {
17481                    // Insert this broadcast record into the final list.
17482                    receivers.add(it, curr);
17483                    ir++;
17484                    curr = null;
17485                    it++;
17486                    NT++;
17487                } else {
17488                    // Skip to the next ResolveInfo in the final list.
17489                    it++;
17490                    curt = null;
17491                }
17492            }
17493        }
17494        while (ir < NR) {
17495            if (receivers == null) {
17496                receivers = new ArrayList();
17497            }
17498            receivers.add(registeredReceivers.get(ir));
17499            ir++;
17500        }
17501
17502        if ((receivers != null && receivers.size() > 0)
17503                || resultTo != null) {
17504            BroadcastQueue queue = broadcastQueueForIntent(intent);
17505            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17506                    callerPackage, callingPid, callingUid, resolvedType,
17507                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17508                    resultData, resultExtras, ordered, sticky, false, userId);
17509
17510            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17511                    + ": prev had " + queue.mOrderedBroadcasts.size());
17512            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17513                    "Enqueueing broadcast " + r.intent.getAction());
17514
17515            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17516            if (!replaced) {
17517                queue.enqueueOrderedBroadcastLocked(r);
17518                queue.scheduleBroadcastsLocked();
17519            }
17520        }
17521
17522        return ActivityManager.BROADCAST_SUCCESS;
17523    }
17524
17525    final Intent verifyBroadcastLocked(Intent intent) {
17526        // Refuse possible leaked file descriptors
17527        if (intent != null && intent.hasFileDescriptors() == true) {
17528            throw new IllegalArgumentException("File descriptors passed in Intent");
17529        }
17530
17531        int flags = intent.getFlags();
17532
17533        if (!mProcessesReady) {
17534            // if the caller really truly claims to know what they're doing, go
17535            // ahead and allow the broadcast without launching any receivers
17536            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17537                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17538            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17539                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17540                        + " before boot completion");
17541                throw new IllegalStateException("Cannot broadcast before boot completed");
17542            }
17543        }
17544
17545        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17546            throw new IllegalArgumentException(
17547                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17548        }
17549
17550        return intent;
17551    }
17552
17553    public final int broadcastIntent(IApplicationThread caller,
17554            Intent intent, String resolvedType, IIntentReceiver resultTo,
17555            int resultCode, String resultData, Bundle resultExtras,
17556            String[] requiredPermissions, int appOp, Bundle bOptions,
17557            boolean serialized, boolean sticky, int userId) {
17558        enforceNotIsolatedCaller("broadcastIntent");
17559        synchronized(this) {
17560            intent = verifyBroadcastLocked(intent);
17561
17562            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17563            final int callingPid = Binder.getCallingPid();
17564            final int callingUid = Binder.getCallingUid();
17565            final long origId = Binder.clearCallingIdentity();
17566            int res = broadcastIntentLocked(callerApp,
17567                    callerApp != null ? callerApp.info.packageName : null,
17568                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17569                    requiredPermissions, appOp, null, serialized, sticky,
17570                    callingPid, callingUid, userId);
17571            Binder.restoreCallingIdentity(origId);
17572            return res;
17573        }
17574    }
17575
17576
17577    int broadcastIntentInPackage(String packageName, int uid,
17578            Intent intent, String resolvedType, IIntentReceiver resultTo,
17579            int resultCode, String resultData, Bundle resultExtras,
17580            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17581            int userId) {
17582        synchronized(this) {
17583            intent = verifyBroadcastLocked(intent);
17584
17585            final long origId = Binder.clearCallingIdentity();
17586            String[] requiredPermissions = requiredPermission == null ? null
17587                    : new String[] {requiredPermission};
17588            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17589                    resultTo, resultCode, resultData, resultExtras,
17590                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17591                    sticky, -1, uid, userId);
17592            Binder.restoreCallingIdentity(origId);
17593            return res;
17594        }
17595    }
17596
17597    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17598        // Refuse possible leaked file descriptors
17599        if (intent != null && intent.hasFileDescriptors() == true) {
17600            throw new IllegalArgumentException("File descriptors passed in Intent");
17601        }
17602
17603        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17604                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17605
17606        synchronized(this) {
17607            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17608                    != PackageManager.PERMISSION_GRANTED) {
17609                String msg = "Permission Denial: unbroadcastIntent() from pid="
17610                        + Binder.getCallingPid()
17611                        + ", uid=" + Binder.getCallingUid()
17612                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17613                Slog.w(TAG, msg);
17614                throw new SecurityException(msg);
17615            }
17616            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17617            if (stickies != null) {
17618                ArrayList<Intent> list = stickies.get(intent.getAction());
17619                if (list != null) {
17620                    int N = list.size();
17621                    int i;
17622                    for (i=0; i<N; i++) {
17623                        if (intent.filterEquals(list.get(i))) {
17624                            list.remove(i);
17625                            break;
17626                        }
17627                    }
17628                    if (list.size() <= 0) {
17629                        stickies.remove(intent.getAction());
17630                    }
17631                }
17632                if (stickies.size() <= 0) {
17633                    mStickyBroadcasts.remove(userId);
17634                }
17635            }
17636        }
17637    }
17638
17639    void backgroundServicesFinishedLocked(int userId) {
17640        for (BroadcastQueue queue : mBroadcastQueues) {
17641            queue.backgroundServicesFinishedLocked(userId);
17642        }
17643    }
17644
17645    public void finishReceiver(IBinder who, int resultCode, String resultData,
17646            Bundle resultExtras, boolean resultAbort, int flags) {
17647        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17648
17649        // Refuse possible leaked file descriptors
17650        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17651            throw new IllegalArgumentException("File descriptors passed in Bundle");
17652        }
17653
17654        final long origId = Binder.clearCallingIdentity();
17655        try {
17656            boolean doNext = false;
17657            BroadcastRecord r;
17658
17659            synchronized(this) {
17660                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17661                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17662                r = queue.getMatchingOrderedReceiver(who);
17663                if (r != null) {
17664                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17665                        resultData, resultExtras, resultAbort, true);
17666                }
17667            }
17668
17669            if (doNext) {
17670                r.queue.processNextBroadcast(false);
17671            }
17672            trimApplications();
17673        } finally {
17674            Binder.restoreCallingIdentity(origId);
17675        }
17676    }
17677
17678    // =========================================================
17679    // INSTRUMENTATION
17680    // =========================================================
17681
17682    public boolean startInstrumentation(ComponentName className,
17683            String profileFile, int flags, Bundle arguments,
17684            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17685            int userId, String abiOverride) {
17686        enforceNotIsolatedCaller("startInstrumentation");
17687        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17688                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17689        // Refuse possible leaked file descriptors
17690        if (arguments != null && arguments.hasFileDescriptors()) {
17691            throw new IllegalArgumentException("File descriptors passed in Bundle");
17692        }
17693
17694        synchronized(this) {
17695            InstrumentationInfo ii = null;
17696            ApplicationInfo ai = null;
17697            try {
17698                ii = mContext.getPackageManager().getInstrumentationInfo(
17699                    className, STOCK_PM_FLAGS);
17700                ai = AppGlobals.getPackageManager().getApplicationInfo(
17701                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17702            } catch (PackageManager.NameNotFoundException e) {
17703            } catch (RemoteException e) {
17704            }
17705            if (ii == null) {
17706                reportStartInstrumentationFailure(watcher, className,
17707                        "Unable to find instrumentation info for: " + className);
17708                return false;
17709            }
17710            if (ai == null) {
17711                reportStartInstrumentationFailure(watcher, className,
17712                        "Unable to find instrumentation target package: " + ii.targetPackage);
17713                return false;
17714            }
17715            if (!ai.hasCode()) {
17716                reportStartInstrumentationFailure(watcher, className,
17717                        "Instrumentation target has no code: " + ii.targetPackage);
17718                return false;
17719            }
17720
17721            int match = mContext.getPackageManager().checkSignatures(
17722                    ii.targetPackage, ii.packageName);
17723            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17724                String msg = "Permission Denial: starting instrumentation "
17725                        + className + " from pid="
17726                        + Binder.getCallingPid()
17727                        + ", uid=" + Binder.getCallingPid()
17728                        + " not allowed because package " + ii.packageName
17729                        + " does not have a signature matching the target "
17730                        + ii.targetPackage;
17731                reportStartInstrumentationFailure(watcher, className, msg);
17732                throw new SecurityException(msg);
17733            }
17734
17735            final long origId = Binder.clearCallingIdentity();
17736            // Instrumentation can kill and relaunch even persistent processes
17737            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17738                    "start instr");
17739            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17740            app.instrumentationClass = className;
17741            app.instrumentationInfo = ai;
17742            app.instrumentationProfileFile = profileFile;
17743            app.instrumentationArguments = arguments;
17744            app.instrumentationWatcher = watcher;
17745            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17746            app.instrumentationResultClass = className;
17747            Binder.restoreCallingIdentity(origId);
17748        }
17749
17750        return true;
17751    }
17752
17753    /**
17754     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17755     * error to the logs, but if somebody is watching, send the report there too.  This enables
17756     * the "am" command to report errors with more information.
17757     *
17758     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17759     * @param cn The component name of the instrumentation.
17760     * @param report The error report.
17761     */
17762    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17763            ComponentName cn, String report) {
17764        Slog.w(TAG, report);
17765        try {
17766            if (watcher != null) {
17767                Bundle results = new Bundle();
17768                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17769                results.putString("Error", report);
17770                watcher.instrumentationStatus(cn, -1, results);
17771            }
17772        } catch (RemoteException e) {
17773            Slog.w(TAG, e);
17774        }
17775    }
17776
17777    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17778        if (app.instrumentationWatcher != null) {
17779            try {
17780                // NOTE:  IInstrumentationWatcher *must* be oneway here
17781                app.instrumentationWatcher.instrumentationFinished(
17782                    app.instrumentationClass,
17783                    resultCode,
17784                    results);
17785            } catch (RemoteException e) {
17786            }
17787        }
17788
17789        // Can't call out of the system process with a lock held, so post a message.
17790        if (app.instrumentationUiAutomationConnection != null) {
17791            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17792                    app.instrumentationUiAutomationConnection).sendToTarget();
17793        }
17794
17795        app.instrumentationWatcher = null;
17796        app.instrumentationUiAutomationConnection = null;
17797        app.instrumentationClass = null;
17798        app.instrumentationInfo = null;
17799        app.instrumentationProfileFile = null;
17800        app.instrumentationArguments = null;
17801
17802        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17803                "finished inst");
17804    }
17805
17806    public void finishInstrumentation(IApplicationThread target,
17807            int resultCode, Bundle results) {
17808        int userId = UserHandle.getCallingUserId();
17809        // Refuse possible leaked file descriptors
17810        if (results != null && results.hasFileDescriptors()) {
17811            throw new IllegalArgumentException("File descriptors passed in Intent");
17812        }
17813
17814        synchronized(this) {
17815            ProcessRecord app = getRecordForAppLocked(target);
17816            if (app == null) {
17817                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17818                return;
17819            }
17820            final long origId = Binder.clearCallingIdentity();
17821            finishInstrumentationLocked(app, resultCode, results);
17822            Binder.restoreCallingIdentity(origId);
17823        }
17824    }
17825
17826    // =========================================================
17827    // CONFIGURATION
17828    // =========================================================
17829
17830    public ConfigurationInfo getDeviceConfigurationInfo() {
17831        ConfigurationInfo config = new ConfigurationInfo();
17832        synchronized (this) {
17833            config.reqTouchScreen = mConfiguration.touchscreen;
17834            config.reqKeyboardType = mConfiguration.keyboard;
17835            config.reqNavigation = mConfiguration.navigation;
17836            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17837                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17838                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17839            }
17840            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17841                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17842                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17843            }
17844            config.reqGlEsVersion = GL_ES_VERSION;
17845        }
17846        return config;
17847    }
17848
17849    ActivityStack getFocusedStack() {
17850        return mStackSupervisor.getFocusedStack();
17851    }
17852
17853    @Override
17854    public int getFocusedStackId() throws RemoteException {
17855        ActivityStack focusedStack = getFocusedStack();
17856        if (focusedStack != null) {
17857            return focusedStack.getStackId();
17858        }
17859        return -1;
17860    }
17861
17862    public Configuration getConfiguration() {
17863        Configuration ci;
17864        synchronized(this) {
17865            ci = new Configuration(mConfiguration);
17866            ci.userSetLocale = false;
17867        }
17868        return ci;
17869    }
17870
17871    @Override
17872    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17873        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17874        synchronized (this) {
17875            mSuppressResizeConfigChanges = suppress;
17876        }
17877    }
17878
17879    @Override
17880    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17881        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17882        if (fromStackId == HOME_STACK_ID) {
17883            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17884        }
17885        synchronized (this) {
17886            final long origId = Binder.clearCallingIdentity();
17887            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17888            if (stack != null) {
17889                mWindowManager.deferSurfaceLayout();
17890                try {
17891                    if (fromStackId == DOCKED_STACK_ID) {
17892
17893                        // We are moving all tasks from the docked stack to the fullscreen stack,
17894                        // which is dismissing the docked stack, so resize all other stacks to
17895                        // fullscreen here already so we don't end up with resize trashing.
17896                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17897                            if (StackId.isResizeableByDockedStack(i)) {
17898                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17899                                if (otherStack != null) {
17900                                    mStackSupervisor.resizeStackLocked(i,
17901                                            null, null, null, PRESERVE_WINDOWS,
17902                                            true /* allowResizeInDockedMode */);
17903                                }
17904                            }
17905                        }
17906                    }
17907                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17908                    final int size = tasks.size();
17909                    if (onTop) {
17910                        for (int i = 0; i < size; i++) {
17911                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17912                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17913                                    "moveTasksToFullscreenStack", ANIMATE);
17914                        }
17915                    } else {
17916                        for (int i = size - 1; i >= 0; i--) {
17917                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17918                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17919                        }
17920                    }
17921                } finally {
17922                    mWindowManager.continueSurfaceLayout();
17923                }
17924
17925            }
17926            Binder.restoreCallingIdentity(origId);
17927        }
17928    }
17929
17930    @Override
17931    public void updatePersistentConfiguration(Configuration values) {
17932        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17933                "updateConfiguration()");
17934        enforceWriteSettingsPermission("updateConfiguration()");
17935        if (values == null) {
17936            throw new NullPointerException("Configuration must not be null");
17937        }
17938
17939        int userId = UserHandle.getCallingUserId();
17940
17941        synchronized(this) {
17942            final long origId = Binder.clearCallingIdentity();
17943            updateConfigurationLocked(values, null, false, true, userId);
17944            Binder.restoreCallingIdentity(origId);
17945        }
17946    }
17947
17948    private void updateFontScaleIfNeeded() {
17949        final int currentUserId;
17950        synchronized(this) {
17951            currentUserId = mUserController.getCurrentUserIdLocked();
17952        }
17953        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17954                FONT_SCALE, 1.0f, currentUserId);
17955        if (mConfiguration.fontScale != scaleFactor) {
17956            final Configuration configuration = mWindowManager.computeNewConfiguration();
17957            configuration.fontScale = scaleFactor;
17958            updatePersistentConfiguration(configuration);
17959        }
17960    }
17961
17962    private void enforceWriteSettingsPermission(String func) {
17963        int uid = Binder.getCallingUid();
17964        if (uid == Process.ROOT_UID) {
17965            return;
17966        }
17967
17968        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17969                Settings.getPackageNameForUid(mContext, uid), false)) {
17970            return;
17971        }
17972
17973        String msg = "Permission Denial: " + func + " from pid="
17974                + Binder.getCallingPid()
17975                + ", uid=" + uid
17976                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17977        Slog.w(TAG, msg);
17978        throw new SecurityException(msg);
17979    }
17980
17981    public void updateConfiguration(Configuration values) {
17982        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17983                "updateConfiguration()");
17984
17985        synchronized(this) {
17986            if (values == null && mWindowManager != null) {
17987                // sentinel: fetch the current configuration from the window manager
17988                values = mWindowManager.computeNewConfiguration();
17989            }
17990
17991            if (mWindowManager != null) {
17992                mProcessList.applyDisplaySize(mWindowManager);
17993            }
17994
17995            final long origId = Binder.clearCallingIdentity();
17996            if (values != null) {
17997                Settings.System.clearConfiguration(values);
17998            }
17999            updateConfigurationLocked(values, null, false);
18000            Binder.restoreCallingIdentity(origId);
18001        }
18002    }
18003
18004    void updateUserConfigurationLocked() {
18005        Configuration configuration = new Configuration(mConfiguration);
18006        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18007                mUserController.getCurrentUserIdLocked());
18008        updateConfigurationLocked(configuration, null, false);
18009    }
18010
18011    boolean updateConfigurationLocked(Configuration values,
18012            ActivityRecord starting, boolean initLocale) {
18013        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18014        return updateConfigurationLocked(values, starting, initLocale, false,
18015                UserHandle.USER_NULL);
18016    }
18017
18018    // To cache the list of supported system locales
18019    private String[] mSupportedSystemLocales = null;
18020
18021    /**
18022     * Do either or both things: (1) change the current configuration, and (2)
18023     * make sure the given activity is running with the (now) current
18024     * configuration.  Returns true if the activity has been left running, or
18025     * false if <var>starting</var> is being destroyed to match the new
18026     * configuration.
18027     *
18028     * @param userId is only used when persistent parameter is set to true to persist configuration
18029     *               for that particular user
18030     */
18031    private boolean updateConfigurationLocked(Configuration values,
18032            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18033        int changes = 0;
18034
18035        if (values != null) {
18036            Configuration newConfig = new Configuration(mConfiguration);
18037            changes = newConfig.updateFrom(values);
18038            if (changes != 0) {
18039                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18040                        "Updating configuration to: " + values);
18041
18042                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18043
18044                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18045                    final Locale locale;
18046                    if (values.getLocales().size() == 1) {
18047                        // This is an optimization to avoid the JNI call when the result of
18048                        // getFirstMatch() does not depend on the supported locales.
18049                        locale = values.getLocales().get(0);
18050                    } else {
18051                        if (mSupportedSystemLocales == null) {
18052                            mSupportedSystemLocales =
18053                                    Resources.getSystem().getAssets().getLocales();
18054                        }
18055                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18056                    }
18057                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18058                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18059                            locale));
18060                }
18061
18062                mConfigurationSeq++;
18063                if (mConfigurationSeq <= 0) {
18064                    mConfigurationSeq = 1;
18065                }
18066                newConfig.seq = mConfigurationSeq;
18067                mConfiguration = newConfig;
18068                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18069                mUsageStatsService.reportConfigurationChange(newConfig,
18070                        mUserController.getCurrentUserIdLocked());
18071                //mUsageStatsService.noteStartConfig(newConfig);
18072
18073                final Configuration configCopy = new Configuration(mConfiguration);
18074
18075                // TODO: If our config changes, should we auto dismiss any currently
18076                // showing dialogs?
18077                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18078
18079                AttributeCache ac = AttributeCache.instance();
18080                if (ac != null) {
18081                    ac.updateConfiguration(configCopy);
18082                }
18083
18084                // Make sure all resources in our process are updated
18085                // right now, so that anyone who is going to retrieve
18086                // resource values after we return will be sure to get
18087                // the new ones.  This is especially important during
18088                // boot, where the first config change needs to guarantee
18089                // all resources have that config before following boot
18090                // code is executed.
18091                mSystemThread.applyConfigurationToResources(configCopy);
18092
18093                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18094                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18095                    msg.obj = new Configuration(configCopy);
18096                    msg.arg1 = userId;
18097                    mHandler.sendMessage(msg);
18098                }
18099
18100                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18101                if (isDensityChange) {
18102                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18103                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18104                }
18105
18106                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18107                    ProcessRecord app = mLruProcesses.get(i);
18108                    try {
18109                        if (app.thread != null) {
18110                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18111                                    + app.processName + " new config " + mConfiguration);
18112                            app.thread.scheduleConfigurationChanged(configCopy);
18113                        }
18114                    } catch (Exception e) {
18115                    }
18116                }
18117                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18119                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18120                        | Intent.FLAG_RECEIVER_FOREGROUND);
18121                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18122                        null, AppOpsManager.OP_NONE, null, false, false,
18123                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18124                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18125                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18126                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18127                    if (!mProcessesReady) {
18128                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18129                    }
18130                    broadcastIntentLocked(null, null, intent,
18131                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18132                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18133                }
18134            }
18135        }
18136
18137        boolean kept = true;
18138        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18139        // mainStack is null during startup.
18140        if (mainStack != null) {
18141            if (changes != 0 && starting == null) {
18142                // If the configuration changed, and the caller is not already
18143                // in the process of starting an activity, then find the top
18144                // activity to check if its configuration needs to change.
18145                starting = mainStack.topRunningActivityLocked();
18146            }
18147
18148            if (starting != null) {
18149                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18150                // And we need to make sure at this point that all other activities
18151                // are made visible with the correct configuration.
18152                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18153                        !PRESERVE_WINDOWS);
18154            }
18155        }
18156
18157        if (values != null && mWindowManager != null) {
18158            mWindowManager.setNewConfiguration(mConfiguration);
18159        }
18160
18161        return kept;
18162    }
18163
18164    /**
18165     * Decide based on the configuration whether we should shouw the ANR,
18166     * crash, etc dialogs.  The idea is that if there is no affordnace to
18167     * press the on-screen buttons, we shouldn't show the dialog.
18168     *
18169     * A thought: SystemUI might also want to get told about this, the Power
18170     * dialog / global actions also might want different behaviors.
18171     */
18172    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18173        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18174                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18175                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18176        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18177                                    == Configuration.UI_MODE_TYPE_CAR);
18178        return inputMethodExists && uiIsNotCarType && !inVrMode;
18179    }
18180
18181    @Override
18182    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18183        synchronized (this) {
18184            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18185            if (srec != null) {
18186                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18187            }
18188        }
18189        return false;
18190    }
18191
18192    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18193            Intent resultData) {
18194
18195        synchronized (this) {
18196            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18197            if (r != null) {
18198                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18199            }
18200            return false;
18201        }
18202    }
18203
18204    public int getLaunchedFromUid(IBinder activityToken) {
18205        ActivityRecord srec;
18206        synchronized (this) {
18207            srec = ActivityRecord.forTokenLocked(activityToken);
18208        }
18209        if (srec == null) {
18210            return -1;
18211        }
18212        return srec.launchedFromUid;
18213    }
18214
18215    public String getLaunchedFromPackage(IBinder activityToken) {
18216        ActivityRecord srec;
18217        synchronized (this) {
18218            srec = ActivityRecord.forTokenLocked(activityToken);
18219        }
18220        if (srec == null) {
18221            return null;
18222        }
18223        return srec.launchedFromPackage;
18224    }
18225
18226    // =========================================================
18227    // LIFETIME MANAGEMENT
18228    // =========================================================
18229
18230    // Returns which broadcast queue the app is the current [or imminent] receiver
18231    // on, or 'null' if the app is not an active broadcast recipient.
18232    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18233        BroadcastRecord r = app.curReceiver;
18234        if (r != null) {
18235            return r.queue;
18236        }
18237
18238        // It's not the current receiver, but it might be starting up to become one
18239        synchronized (this) {
18240            for (BroadcastQueue queue : mBroadcastQueues) {
18241                r = queue.mPendingBroadcast;
18242                if (r != null && r.curApp == app) {
18243                    // found it; report which queue it's in
18244                    return queue;
18245                }
18246            }
18247        }
18248
18249        return null;
18250    }
18251
18252    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18253            ComponentName targetComponent, String targetProcess) {
18254        if (!mTrackingAssociations) {
18255            return null;
18256        }
18257        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18258                = mAssociations.get(targetUid);
18259        if (components == null) {
18260            components = new ArrayMap<>();
18261            mAssociations.put(targetUid, components);
18262        }
18263        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18264        if (sourceUids == null) {
18265            sourceUids = new SparseArray<>();
18266            components.put(targetComponent, sourceUids);
18267        }
18268        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18269        if (sourceProcesses == null) {
18270            sourceProcesses = new ArrayMap<>();
18271            sourceUids.put(sourceUid, sourceProcesses);
18272        }
18273        Association ass = sourceProcesses.get(sourceProcess);
18274        if (ass == null) {
18275            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18276                    targetProcess);
18277            sourceProcesses.put(sourceProcess, ass);
18278        }
18279        ass.mCount++;
18280        ass.mNesting++;
18281        if (ass.mNesting == 1) {
18282            ass.mStartTime = SystemClock.uptimeMillis();
18283        }
18284        return ass;
18285    }
18286
18287    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18288            ComponentName targetComponent) {
18289        if (!mTrackingAssociations) {
18290            return;
18291        }
18292        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18293                = mAssociations.get(targetUid);
18294        if (components == null) {
18295            return;
18296        }
18297        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18298        if (sourceUids == null) {
18299            return;
18300        }
18301        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18302        if (sourceProcesses == null) {
18303            return;
18304        }
18305        Association ass = sourceProcesses.get(sourceProcess);
18306        if (ass == null || ass.mNesting <= 0) {
18307            return;
18308        }
18309        ass.mNesting--;
18310        if (ass.mNesting == 0) {
18311            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18312        }
18313    }
18314
18315    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18316            boolean doingAll, long now) {
18317        if (mAdjSeq == app.adjSeq) {
18318            // This adjustment has already been computed.
18319            return app.curRawAdj;
18320        }
18321
18322        if (app.thread == null) {
18323            app.adjSeq = mAdjSeq;
18324            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18325            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18326            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18327        }
18328
18329        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18330        app.adjSource = null;
18331        app.adjTarget = null;
18332        app.empty = false;
18333        app.cached = false;
18334
18335        final int activitiesSize = app.activities.size();
18336
18337        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18338            // The max adjustment doesn't allow this app to be anything
18339            // below foreground, so it is not worth doing work for it.
18340            app.adjType = "fixed";
18341            app.adjSeq = mAdjSeq;
18342            app.curRawAdj = app.maxAdj;
18343            app.foregroundActivities = false;
18344            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18345            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18346            // System processes can do UI, and when they do we want to have
18347            // them trim their memory after the user leaves the UI.  To
18348            // facilitate this, here we need to determine whether or not it
18349            // is currently showing UI.
18350            app.systemNoUi = true;
18351            if (app == TOP_APP) {
18352                app.systemNoUi = false;
18353            } else if (activitiesSize > 0) {
18354                for (int j = 0; j < activitiesSize; j++) {
18355                    final ActivityRecord r = app.activities.get(j);
18356                    if (r.visible) {
18357                        app.systemNoUi = false;
18358                    }
18359                }
18360            }
18361            if (!app.systemNoUi) {
18362                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18363            }
18364            return (app.curAdj=app.maxAdj);
18365        }
18366
18367        app.systemNoUi = false;
18368
18369        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18370
18371        // Determine the importance of the process, starting with most
18372        // important to least, and assign an appropriate OOM adjustment.
18373        int adj;
18374        int schedGroup;
18375        int procState;
18376        boolean foregroundActivities = false;
18377        BroadcastQueue queue;
18378        if (app == TOP_APP) {
18379            // The last app on the list is the foreground app.
18380            adj = ProcessList.FOREGROUND_APP_ADJ;
18381            schedGroup = Process.THREAD_GROUP_TOP_APP;
18382            app.adjType = "top-activity";
18383            foregroundActivities = true;
18384            procState = PROCESS_STATE_CUR_TOP;
18385        } else if (app.instrumentationClass != null) {
18386            // Don't want to kill running instrumentation.
18387            adj = ProcessList.FOREGROUND_APP_ADJ;
18388            schedGroup = Process.THREAD_GROUP_DEFAULT;
18389            app.adjType = "instrumentation";
18390            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18391        } else if ((queue = isReceivingBroadcast(app)) != null) {
18392            // An app that is currently receiving a broadcast also
18393            // counts as being in the foreground for OOM killer purposes.
18394            // It's placed in a sched group based on the nature of the
18395            // broadcast as reflected by which queue it's active in.
18396            adj = ProcessList.FOREGROUND_APP_ADJ;
18397            schedGroup = (queue == mFgBroadcastQueue)
18398                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18399            app.adjType = "broadcast";
18400            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18401        } else if (app.executingServices.size() > 0) {
18402            // An app that is currently executing a service callback also
18403            // counts as being in the foreground.
18404            adj = ProcessList.FOREGROUND_APP_ADJ;
18405            schedGroup = app.execServicesFg ?
18406                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18407            app.adjType = "exec-service";
18408            procState = ActivityManager.PROCESS_STATE_SERVICE;
18409            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18410        } else {
18411            // As far as we know the process is empty.  We may change our mind later.
18412            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18413            // At this point we don't actually know the adjustment.  Use the cached adj
18414            // value that the caller wants us to.
18415            adj = cachedAdj;
18416            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18417            app.cached = true;
18418            app.empty = true;
18419            app.adjType = "cch-empty";
18420        }
18421
18422        // Examine all activities if not already foreground.
18423        if (!foregroundActivities && activitiesSize > 0) {
18424            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18425            for (int j = 0; j < activitiesSize; j++) {
18426                final ActivityRecord r = app.activities.get(j);
18427                if (r.app != app) {
18428                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18429                            + app + "?!? Using " + r.app + " instead.");
18430                    continue;
18431                }
18432                if (r.visible) {
18433                    // App has a visible activity; only upgrade adjustment.
18434                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18435                        adj = ProcessList.VISIBLE_APP_ADJ;
18436                        app.adjType = "visible";
18437                    }
18438                    if (procState > PROCESS_STATE_CUR_TOP) {
18439                        procState = PROCESS_STATE_CUR_TOP;
18440                    }
18441                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18442                    app.cached = false;
18443                    app.empty = false;
18444                    foregroundActivities = true;
18445                    if (r.task != null && minLayer > 0) {
18446                        final int layer = r.task.mLayerRank;
18447                        if (layer >= 0 && minLayer > layer) {
18448                            minLayer = layer;
18449                        }
18450                    }
18451                    break;
18452                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18453                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18454                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18455                        app.adjType = "pausing";
18456                    }
18457                    if (procState > PROCESS_STATE_CUR_TOP) {
18458                        procState = PROCESS_STATE_CUR_TOP;
18459                    }
18460                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18461                    app.cached = false;
18462                    app.empty = false;
18463                    foregroundActivities = true;
18464                } else if (r.state == ActivityState.STOPPING) {
18465                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18466                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18467                        app.adjType = "stopping";
18468                    }
18469                    // For the process state, we will at this point consider the
18470                    // process to be cached.  It will be cached either as an activity
18471                    // or empty depending on whether the activity is finishing.  We do
18472                    // this so that we can treat the process as cached for purposes of
18473                    // memory trimming (determing current memory level, trim command to
18474                    // send to process) since there can be an arbitrary number of stopping
18475                    // processes and they should soon all go into the cached state.
18476                    if (!r.finishing) {
18477                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18478                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18479                        }
18480                    }
18481                    app.cached = false;
18482                    app.empty = false;
18483                    foregroundActivities = true;
18484                } else {
18485                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18486                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18487                        app.adjType = "cch-act";
18488                    }
18489                }
18490            }
18491            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18492                adj += minLayer;
18493            }
18494        }
18495
18496        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18497                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18498            if (app.foregroundServices) {
18499                // The user is aware of this app, so make it visible.
18500                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18501                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18502                app.cached = false;
18503                app.adjType = "fg-service";
18504                schedGroup = Process.THREAD_GROUP_DEFAULT;
18505            } else if (app.forcingToForeground != null) {
18506                // The user is aware of this app, so make it visible.
18507                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18508                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18509                app.cached = false;
18510                app.adjType = "force-fg";
18511                app.adjSource = app.forcingToForeground;
18512                schedGroup = Process.THREAD_GROUP_DEFAULT;
18513            }
18514        }
18515
18516        if (app == mHeavyWeightProcess) {
18517            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18518                // We don't want to kill the current heavy-weight process.
18519                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18520                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18521                app.cached = false;
18522                app.adjType = "heavy";
18523            }
18524            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18525                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18526            }
18527        }
18528
18529        if (app == mHomeProcess) {
18530            if (adj > ProcessList.HOME_APP_ADJ) {
18531                // This process is hosting what we currently consider to be the
18532                // home app, so we don't want to let it go into the background.
18533                adj = ProcessList.HOME_APP_ADJ;
18534                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18535                app.cached = false;
18536                app.adjType = "home";
18537            }
18538            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18539                procState = ActivityManager.PROCESS_STATE_HOME;
18540            }
18541        }
18542
18543        if (app == mPreviousProcess && app.activities.size() > 0) {
18544            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18545                // This was the previous process that showed UI to the user.
18546                // We want to try to keep it around more aggressively, to give
18547                // a good experience around switching between two apps.
18548                adj = ProcessList.PREVIOUS_APP_ADJ;
18549                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18550                app.cached = false;
18551                app.adjType = "previous";
18552            }
18553            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18554                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18555            }
18556        }
18557
18558        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18559                + " reason=" + app.adjType);
18560
18561        // By default, we use the computed adjustment.  It may be changed if
18562        // there are applications dependent on our services or providers, but
18563        // this gives us a baseline and makes sure we don't get into an
18564        // infinite recursion.
18565        app.adjSeq = mAdjSeq;
18566        app.curRawAdj = adj;
18567        app.hasStartedServices = false;
18568
18569        if (mBackupTarget != null && app == mBackupTarget.app) {
18570            // If possible we want to avoid killing apps while they're being backed up
18571            if (adj > ProcessList.BACKUP_APP_ADJ) {
18572                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18573                adj = ProcessList.BACKUP_APP_ADJ;
18574                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18575                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18576                }
18577                app.adjType = "backup";
18578                app.cached = false;
18579            }
18580            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18581                procState = ActivityManager.PROCESS_STATE_BACKUP;
18582            }
18583        }
18584
18585        boolean mayBeTop = false;
18586
18587        for (int is = app.services.size()-1;
18588                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18589                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18590                        || procState > ActivityManager.PROCESS_STATE_TOP);
18591                is--) {
18592            ServiceRecord s = app.services.valueAt(is);
18593            if (s.startRequested) {
18594                app.hasStartedServices = true;
18595                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18596                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18597                }
18598                if (app.hasShownUi && app != mHomeProcess) {
18599                    // If this process has shown some UI, let it immediately
18600                    // go to the LRU list because it may be pretty heavy with
18601                    // UI stuff.  We'll tag it with a label just to help
18602                    // debug and understand what is going on.
18603                    if (adj > ProcessList.SERVICE_ADJ) {
18604                        app.adjType = "cch-started-ui-services";
18605                    }
18606                } else {
18607                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18608                        // This service has seen some activity within
18609                        // recent memory, so we will keep its process ahead
18610                        // of the background processes.
18611                        if (adj > ProcessList.SERVICE_ADJ) {
18612                            adj = ProcessList.SERVICE_ADJ;
18613                            app.adjType = "started-services";
18614                            app.cached = false;
18615                        }
18616                    }
18617                    // If we have let the service slide into the background
18618                    // state, still have some text describing what it is doing
18619                    // even though the service no longer has an impact.
18620                    if (adj > ProcessList.SERVICE_ADJ) {
18621                        app.adjType = "cch-started-services";
18622                    }
18623                }
18624            }
18625            for (int conni = s.connections.size()-1;
18626                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18627                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18628                            || procState > ActivityManager.PROCESS_STATE_TOP);
18629                    conni--) {
18630                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18631                for (int i = 0;
18632                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18633                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18634                                || procState > ActivityManager.PROCESS_STATE_TOP);
18635                        i++) {
18636                    // XXX should compute this based on the max of
18637                    // all connected clients.
18638                    ConnectionRecord cr = clist.get(i);
18639                    if (cr.binding.client == app) {
18640                        // Binding to ourself is not interesting.
18641                        continue;
18642                    }
18643                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18644                        ProcessRecord client = cr.binding.client;
18645                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18646                                TOP_APP, doingAll, now);
18647                        int clientProcState = client.curProcState;
18648                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18649                            // If the other app is cached for any reason, for purposes here
18650                            // we are going to consider it empty.  The specific cached state
18651                            // doesn't propagate except under certain conditions.
18652                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18653                        }
18654                        String adjType = null;
18655                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18656                            // Not doing bind OOM management, so treat
18657                            // this guy more like a started service.
18658                            if (app.hasShownUi && app != mHomeProcess) {
18659                                // If this process has shown some UI, let it immediately
18660                                // go to the LRU list because it may be pretty heavy with
18661                                // UI stuff.  We'll tag it with a label just to help
18662                                // debug and understand what is going on.
18663                                if (adj > clientAdj) {
18664                                    adjType = "cch-bound-ui-services";
18665                                }
18666                                app.cached = false;
18667                                clientAdj = adj;
18668                                clientProcState = procState;
18669                            } else {
18670                                if (now >= (s.lastActivity
18671                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18672                                    // This service has not seen activity within
18673                                    // recent memory, so allow it to drop to the
18674                                    // LRU list if there is no other reason to keep
18675                                    // it around.  We'll also tag it with a label just
18676                                    // to help debug and undertand what is going on.
18677                                    if (adj > clientAdj) {
18678                                        adjType = "cch-bound-services";
18679                                    }
18680                                    clientAdj = adj;
18681                                }
18682                            }
18683                        }
18684                        if (adj > clientAdj) {
18685                            // If this process has recently shown UI, and
18686                            // the process that is binding to it is less
18687                            // important than being visible, then we don't
18688                            // care about the binding as much as we care
18689                            // about letting this process get into the LRU
18690                            // list to be killed and restarted if needed for
18691                            // memory.
18692                            if (app.hasShownUi && app != mHomeProcess
18693                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18694                                adjType = "cch-bound-ui-services";
18695                            } else {
18696                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18697                                        |Context.BIND_IMPORTANT)) != 0) {
18698                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18699                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18700                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18701                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18702                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18703                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18704                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18705                                    adj = clientAdj;
18706                                } else {
18707                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18708                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18709                                    }
18710                                }
18711                                if (!client.cached) {
18712                                    app.cached = false;
18713                                }
18714                                adjType = "service";
18715                            }
18716                        }
18717                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18718                            // This will treat important bound services identically to
18719                            // the top app, which may behave differently than generic
18720                            // foreground work.
18721                            if (client.curSchedGroup > schedGroup) {
18722                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18723                                    schedGroup = client.curSchedGroup;
18724                                } else {
18725                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18726                                }
18727                            }
18728                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18729                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18730                                    // Special handling of clients who are in the top state.
18731                                    // We *may* want to consider this process to be in the
18732                                    // top state as well, but only if there is not another
18733                                    // reason for it to be running.  Being on the top is a
18734                                    // special state, meaning you are specifically running
18735                                    // for the current top app.  If the process is already
18736                                    // running in the background for some other reason, it
18737                                    // is more important to continue considering it to be
18738                                    // in the background state.
18739                                    mayBeTop = true;
18740                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18741                                } else {
18742                                    // Special handling for above-top states (persistent
18743                                    // processes).  These should not bring the current process
18744                                    // into the top state, since they are not on top.  Instead
18745                                    // give them the best state after that.
18746                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18747                                        clientProcState =
18748                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18749                                    } else if (mWakefulness
18750                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18751                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18752                                                    != 0) {
18753                                        clientProcState =
18754                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18755                                    } else {
18756                                        clientProcState =
18757                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18758                                    }
18759                                }
18760                            }
18761                        } else {
18762                            if (clientProcState <
18763                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18764                                clientProcState =
18765                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18766                            }
18767                        }
18768                        if (procState > clientProcState) {
18769                            procState = clientProcState;
18770                        }
18771                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18772                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18773                            app.pendingUiClean = true;
18774                        }
18775                        if (adjType != null) {
18776                            app.adjType = adjType;
18777                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18778                                    .REASON_SERVICE_IN_USE;
18779                            app.adjSource = cr.binding.client;
18780                            app.adjSourceProcState = clientProcState;
18781                            app.adjTarget = s.name;
18782                        }
18783                    }
18784                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18785                        app.treatLikeActivity = true;
18786                    }
18787                    final ActivityRecord a = cr.activity;
18788                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18789                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18790                            (a.visible || a.state == ActivityState.RESUMED ||
18791                             a.state == ActivityState.PAUSING)) {
18792                            adj = ProcessList.FOREGROUND_APP_ADJ;
18793                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18794                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18795                                    schedGroup = Process.THREAD_GROUP_TOP_APP;
18796                                } else {
18797                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18798                                }
18799                            }
18800                            app.cached = false;
18801                            app.adjType = "service";
18802                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18803                                    .REASON_SERVICE_IN_USE;
18804                            app.adjSource = a;
18805                            app.adjSourceProcState = procState;
18806                            app.adjTarget = s.name;
18807                        }
18808                    }
18809                }
18810            }
18811        }
18812
18813        for (int provi = app.pubProviders.size()-1;
18814                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18815                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18816                        || procState > ActivityManager.PROCESS_STATE_TOP);
18817                provi--) {
18818            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18819            for (int i = cpr.connections.size()-1;
18820                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18821                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18822                            || procState > ActivityManager.PROCESS_STATE_TOP);
18823                    i--) {
18824                ContentProviderConnection conn = cpr.connections.get(i);
18825                ProcessRecord client = conn.client;
18826                if (client == app) {
18827                    // Being our own client is not interesting.
18828                    continue;
18829                }
18830                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18831                int clientProcState = client.curProcState;
18832                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18833                    // If the other app is cached for any reason, for purposes here
18834                    // we are going to consider it empty.
18835                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18836                }
18837                if (adj > clientAdj) {
18838                    if (app.hasShownUi && app != mHomeProcess
18839                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18840                        app.adjType = "cch-ui-provider";
18841                    } else {
18842                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18843                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18844                        app.adjType = "provider";
18845                    }
18846                    app.cached &= client.cached;
18847                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18848                            .REASON_PROVIDER_IN_USE;
18849                    app.adjSource = client;
18850                    app.adjSourceProcState = clientProcState;
18851                    app.adjTarget = cpr.name;
18852                }
18853                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18854                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18855                        // Special handling of clients who are in the top state.
18856                        // We *may* want to consider this process to be in the
18857                        // top state as well, but only if there is not another
18858                        // reason for it to be running.  Being on the top is a
18859                        // special state, meaning you are specifically running
18860                        // for the current top app.  If the process is already
18861                        // running in the background for some other reason, it
18862                        // is more important to continue considering it to be
18863                        // in the background state.
18864                        mayBeTop = true;
18865                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18866                    } else {
18867                        // Special handling for above-top states (persistent
18868                        // processes).  These should not bring the current process
18869                        // into the top state, since they are not on top.  Instead
18870                        // give them the best state after that.
18871                        clientProcState =
18872                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18873                    }
18874                }
18875                if (procState > clientProcState) {
18876                    procState = clientProcState;
18877                }
18878                if (client.curSchedGroup > schedGroup) {
18879                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18880                }
18881            }
18882            // If the provider has external (non-framework) process
18883            // dependencies, ensure that its adjustment is at least
18884            // FOREGROUND_APP_ADJ.
18885            if (cpr.hasExternalProcessHandles()) {
18886                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18887                    adj = ProcessList.FOREGROUND_APP_ADJ;
18888                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18889                    app.cached = false;
18890                    app.adjType = "provider";
18891                    app.adjTarget = cpr.name;
18892                }
18893                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18894                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18895                }
18896            }
18897        }
18898
18899        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18900            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18901                adj = ProcessList.PREVIOUS_APP_ADJ;
18902                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18903                app.cached = false;
18904                app.adjType = "provider";
18905            }
18906            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18907                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18908            }
18909        }
18910
18911        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18912            // A client of one of our services or providers is in the top state.  We
18913            // *may* want to be in the top state, but not if we are already running in
18914            // the background for some other reason.  For the decision here, we are going
18915            // to pick out a few specific states that we want to remain in when a client
18916            // is top (states that tend to be longer-term) and otherwise allow it to go
18917            // to the top state.
18918            switch (procState) {
18919                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18920                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18921                case ActivityManager.PROCESS_STATE_SERVICE:
18922                    // These all are longer-term states, so pull them up to the top
18923                    // of the background states, but not all the way to the top state.
18924                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18925                    break;
18926                default:
18927                    // Otherwise, top is a better choice, so take it.
18928                    procState = ActivityManager.PROCESS_STATE_TOP;
18929                    break;
18930            }
18931        }
18932
18933        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18934            if (app.hasClientActivities) {
18935                // This is a cached process, but with client activities.  Mark it so.
18936                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18937                app.adjType = "cch-client-act";
18938            } else if (app.treatLikeActivity) {
18939                // This is a cached process, but somebody wants us to treat it like it has
18940                // an activity, okay!
18941                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18942                app.adjType = "cch-as-act";
18943            }
18944        }
18945
18946        if (adj == ProcessList.SERVICE_ADJ) {
18947            if (doingAll) {
18948                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18949                mNewNumServiceProcs++;
18950                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18951                if (!app.serviceb) {
18952                    // This service isn't far enough down on the LRU list to
18953                    // normally be a B service, but if we are low on RAM and it
18954                    // is large we want to force it down since we would prefer to
18955                    // keep launcher over it.
18956                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18957                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18958                        app.serviceHighRam = true;
18959                        app.serviceb = true;
18960                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18961                    } else {
18962                        mNewNumAServiceProcs++;
18963                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18964                    }
18965                } else {
18966                    app.serviceHighRam = false;
18967                }
18968            }
18969            if (app.serviceb) {
18970                adj = ProcessList.SERVICE_B_ADJ;
18971            }
18972        }
18973
18974        app.curRawAdj = adj;
18975
18976        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18977        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18978        if (adj > app.maxAdj) {
18979            adj = app.maxAdj;
18980            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18981                schedGroup = Process.THREAD_GROUP_DEFAULT;
18982            }
18983        }
18984
18985        // Do final modification to adj.  Everything we do between here and applying
18986        // the final setAdj must be done in this function, because we will also use
18987        // it when computing the final cached adj later.  Note that we don't need to
18988        // worry about this for max adj above, since max adj will always be used to
18989        // keep it out of the cached vaues.
18990        app.curAdj = app.modifyRawOomAdj(adj);
18991        app.curSchedGroup = schedGroup;
18992        app.curProcState = procState;
18993        app.foregroundActivities = foregroundActivities;
18994
18995        return app.curRawAdj;
18996    }
18997
18998    /**
18999     * Record new PSS sample for a process.
19000     */
19001    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19002            long now) {
19003        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19004                swapPss * 1024);
19005        proc.lastPssTime = now;
19006        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19007        if (DEBUG_PSS) Slog.d(TAG_PSS,
19008                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19009                + " state=" + ProcessList.makeProcStateString(procState));
19010        if (proc.initialIdlePss == 0) {
19011            proc.initialIdlePss = pss;
19012        }
19013        proc.lastPss = pss;
19014        proc.lastSwapPss = swapPss;
19015        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19016            proc.lastCachedPss = pss;
19017            proc.lastCachedSwapPss = swapPss;
19018        }
19019
19020        final SparseArray<Pair<Long, String>> watchUids
19021                = mMemWatchProcesses.getMap().get(proc.processName);
19022        Long check = null;
19023        if (watchUids != null) {
19024            Pair<Long, String> val = watchUids.get(proc.uid);
19025            if (val == null) {
19026                val = watchUids.get(0);
19027            }
19028            if (val != null) {
19029                check = val.first;
19030            }
19031        }
19032        if (check != null) {
19033            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19034                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19035                if (!isDebuggable) {
19036                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19037                        isDebuggable = true;
19038                    }
19039                }
19040                if (isDebuggable) {
19041                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19042                    final ProcessRecord myProc = proc;
19043                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19044                    mMemWatchDumpProcName = proc.processName;
19045                    mMemWatchDumpFile = heapdumpFile.toString();
19046                    mMemWatchDumpPid = proc.pid;
19047                    mMemWatchDumpUid = proc.uid;
19048                    BackgroundThread.getHandler().post(new Runnable() {
19049                        @Override
19050                        public void run() {
19051                            revokeUriPermission(ActivityThread.currentActivityThread()
19052                                            .getApplicationThread(),
19053                                    DumpHeapActivity.JAVA_URI,
19054                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19055                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19056                                    UserHandle.myUserId());
19057                            ParcelFileDescriptor fd = null;
19058                            try {
19059                                heapdumpFile.delete();
19060                                fd = ParcelFileDescriptor.open(heapdumpFile,
19061                                        ParcelFileDescriptor.MODE_CREATE |
19062                                                ParcelFileDescriptor.MODE_TRUNCATE |
19063                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19064                                                ParcelFileDescriptor.MODE_APPEND);
19065                                IApplicationThread thread = myProc.thread;
19066                                if (thread != null) {
19067                                    try {
19068                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19069                                                "Requesting dump heap from "
19070                                                + myProc + " to " + heapdumpFile);
19071                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19072                                    } catch (RemoteException e) {
19073                                    }
19074                                }
19075                            } catch (FileNotFoundException e) {
19076                                e.printStackTrace();
19077                            } finally {
19078                                if (fd != null) {
19079                                    try {
19080                                        fd.close();
19081                                    } catch (IOException e) {
19082                                    }
19083                                }
19084                            }
19085                        }
19086                    });
19087                } else {
19088                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19089                            + ", but debugging not enabled");
19090                }
19091            }
19092        }
19093    }
19094
19095    /**
19096     * Schedule PSS collection of a process.
19097     */
19098    void requestPssLocked(ProcessRecord proc, int procState) {
19099        if (mPendingPssProcesses.contains(proc)) {
19100            return;
19101        }
19102        if (mPendingPssProcesses.size() == 0) {
19103            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19104        }
19105        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19106        proc.pssProcState = procState;
19107        mPendingPssProcesses.add(proc);
19108    }
19109
19110    /**
19111     * Schedule PSS collection of all processes.
19112     */
19113    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19114        if (!always) {
19115            if (now < (mLastFullPssTime +
19116                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19117                return;
19118            }
19119        }
19120        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19121        mLastFullPssTime = now;
19122        mFullPssPending = true;
19123        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19124        mPendingPssProcesses.clear();
19125        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19126            ProcessRecord app = mLruProcesses.get(i);
19127            if (app.thread == null
19128                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19129                continue;
19130            }
19131            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19132                app.pssProcState = app.setProcState;
19133                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19134                        mTestPssMode, isSleeping(), now);
19135                mPendingPssProcesses.add(app);
19136            }
19137        }
19138        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19139    }
19140
19141    public void setTestPssMode(boolean enabled) {
19142        synchronized (this) {
19143            mTestPssMode = enabled;
19144            if (enabled) {
19145                // Whenever we enable the mode, we want to take a snapshot all of current
19146                // process mem use.
19147                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19148            }
19149        }
19150    }
19151
19152    /**
19153     * Ask a given process to GC right now.
19154     */
19155    final void performAppGcLocked(ProcessRecord app) {
19156        try {
19157            app.lastRequestedGc = SystemClock.uptimeMillis();
19158            if (app.thread != null) {
19159                if (app.reportLowMemory) {
19160                    app.reportLowMemory = false;
19161                    app.thread.scheduleLowMemory();
19162                } else {
19163                    app.thread.processInBackground();
19164                }
19165            }
19166        } catch (Exception e) {
19167            // whatever.
19168        }
19169    }
19170
19171    /**
19172     * Returns true if things are idle enough to perform GCs.
19173     */
19174    private final boolean canGcNowLocked() {
19175        boolean processingBroadcasts = false;
19176        for (BroadcastQueue q : mBroadcastQueues) {
19177            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19178                processingBroadcasts = true;
19179            }
19180        }
19181        return !processingBroadcasts
19182                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19183    }
19184
19185    /**
19186     * Perform GCs on all processes that are waiting for it, but only
19187     * if things are idle.
19188     */
19189    final void performAppGcsLocked() {
19190        final int N = mProcessesToGc.size();
19191        if (N <= 0) {
19192            return;
19193        }
19194        if (canGcNowLocked()) {
19195            while (mProcessesToGc.size() > 0) {
19196                ProcessRecord proc = mProcessesToGc.remove(0);
19197                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19198                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19199                            <= SystemClock.uptimeMillis()) {
19200                        // To avoid spamming the system, we will GC processes one
19201                        // at a time, waiting a few seconds between each.
19202                        performAppGcLocked(proc);
19203                        scheduleAppGcsLocked();
19204                        return;
19205                    } else {
19206                        // It hasn't been long enough since we last GCed this
19207                        // process...  put it in the list to wait for its time.
19208                        addProcessToGcListLocked(proc);
19209                        break;
19210                    }
19211                }
19212            }
19213
19214            scheduleAppGcsLocked();
19215        }
19216    }
19217
19218    /**
19219     * If all looks good, perform GCs on all processes waiting for them.
19220     */
19221    final void performAppGcsIfAppropriateLocked() {
19222        if (canGcNowLocked()) {
19223            performAppGcsLocked();
19224            return;
19225        }
19226        // Still not idle, wait some more.
19227        scheduleAppGcsLocked();
19228    }
19229
19230    /**
19231     * Schedule the execution of all pending app GCs.
19232     */
19233    final void scheduleAppGcsLocked() {
19234        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19235
19236        if (mProcessesToGc.size() > 0) {
19237            // Schedule a GC for the time to the next process.
19238            ProcessRecord proc = mProcessesToGc.get(0);
19239            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19240
19241            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19242            long now = SystemClock.uptimeMillis();
19243            if (when < (now+GC_TIMEOUT)) {
19244                when = now + GC_TIMEOUT;
19245            }
19246            mHandler.sendMessageAtTime(msg, when);
19247        }
19248    }
19249
19250    /**
19251     * Add a process to the array of processes waiting to be GCed.  Keeps the
19252     * list in sorted order by the last GC time.  The process can't already be
19253     * on the list.
19254     */
19255    final void addProcessToGcListLocked(ProcessRecord proc) {
19256        boolean added = false;
19257        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19258            if (mProcessesToGc.get(i).lastRequestedGc <
19259                    proc.lastRequestedGc) {
19260                added = true;
19261                mProcessesToGc.add(i+1, proc);
19262                break;
19263            }
19264        }
19265        if (!added) {
19266            mProcessesToGc.add(0, proc);
19267        }
19268    }
19269
19270    /**
19271     * Set up to ask a process to GC itself.  This will either do it
19272     * immediately, or put it on the list of processes to gc the next
19273     * time things are idle.
19274     */
19275    final void scheduleAppGcLocked(ProcessRecord app) {
19276        long now = SystemClock.uptimeMillis();
19277        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19278            return;
19279        }
19280        if (!mProcessesToGc.contains(app)) {
19281            addProcessToGcListLocked(app);
19282            scheduleAppGcsLocked();
19283        }
19284    }
19285
19286    final void checkExcessivePowerUsageLocked(boolean doKills) {
19287        updateCpuStatsNow();
19288
19289        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19290        boolean doWakeKills = doKills;
19291        boolean doCpuKills = doKills;
19292        if (mLastPowerCheckRealtime == 0) {
19293            doWakeKills = false;
19294        }
19295        if (mLastPowerCheckUptime == 0) {
19296            doCpuKills = false;
19297        }
19298        if (stats.isScreenOn()) {
19299            doWakeKills = false;
19300        }
19301        final long curRealtime = SystemClock.elapsedRealtime();
19302        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19303        final long curUptime = SystemClock.uptimeMillis();
19304        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19305        mLastPowerCheckRealtime = curRealtime;
19306        mLastPowerCheckUptime = curUptime;
19307        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19308            doWakeKills = false;
19309        }
19310        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19311            doCpuKills = false;
19312        }
19313        int i = mLruProcesses.size();
19314        while (i > 0) {
19315            i--;
19316            ProcessRecord app = mLruProcesses.get(i);
19317            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19318                long wtime;
19319                synchronized (stats) {
19320                    wtime = stats.getProcessWakeTime(app.info.uid,
19321                            app.pid, curRealtime);
19322                }
19323                long wtimeUsed = wtime - app.lastWakeTime;
19324                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19325                if (DEBUG_POWER) {
19326                    StringBuilder sb = new StringBuilder(128);
19327                    sb.append("Wake for ");
19328                    app.toShortString(sb);
19329                    sb.append(": over ");
19330                    TimeUtils.formatDuration(realtimeSince, sb);
19331                    sb.append(" used ");
19332                    TimeUtils.formatDuration(wtimeUsed, sb);
19333                    sb.append(" (");
19334                    sb.append((wtimeUsed*100)/realtimeSince);
19335                    sb.append("%)");
19336                    Slog.i(TAG_POWER, sb.toString());
19337                    sb.setLength(0);
19338                    sb.append("CPU for ");
19339                    app.toShortString(sb);
19340                    sb.append(": over ");
19341                    TimeUtils.formatDuration(uptimeSince, sb);
19342                    sb.append(" used ");
19343                    TimeUtils.formatDuration(cputimeUsed, sb);
19344                    sb.append(" (");
19345                    sb.append((cputimeUsed*100)/uptimeSince);
19346                    sb.append("%)");
19347                    Slog.i(TAG_POWER, sb.toString());
19348                }
19349                // If a process has held a wake lock for more
19350                // than 50% of the time during this period,
19351                // that sounds bad.  Kill!
19352                if (doWakeKills && realtimeSince > 0
19353                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19354                    synchronized (stats) {
19355                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19356                                realtimeSince, wtimeUsed);
19357                    }
19358                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19359                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19360                } else if (doCpuKills && uptimeSince > 0
19361                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19362                    synchronized (stats) {
19363                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19364                                uptimeSince, cputimeUsed);
19365                    }
19366                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19367                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19368                } else {
19369                    app.lastWakeTime = wtime;
19370                    app.lastCpuTime = app.curCpuTime;
19371                }
19372            }
19373        }
19374    }
19375
19376    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19377            long nowElapsed) {
19378        boolean success = true;
19379
19380        if (app.curRawAdj != app.setRawAdj) {
19381            app.setRawAdj = app.curRawAdj;
19382        }
19383
19384        int changes = 0;
19385
19386        if (app.curAdj != app.setAdj) {
19387            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19388            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19389                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19390                    + app.adjType);
19391            app.setAdj = app.curAdj;
19392        }
19393
19394        if (app.setSchedGroup != app.curSchedGroup) {
19395            app.setSchedGroup = app.curSchedGroup;
19396            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19397                    "Setting process group of " + app.processName
19398                    + " to " + app.curSchedGroup);
19399            if (app.waitingToKill != null && app.curReceiver == null
19400                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19401                app.kill(app.waitingToKill, true);
19402                success = false;
19403            } else {
19404                if (true) {
19405                    long oldId = Binder.clearCallingIdentity();
19406                    try {
19407                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19408                    } catch (Exception e) {
19409                        Slog.w(TAG, "Failed setting process group of " + app.pid
19410                                + " to " + app.curSchedGroup);
19411                        e.printStackTrace();
19412                    } finally {
19413                        Binder.restoreCallingIdentity(oldId);
19414                    }
19415                } else {
19416                    if (app.thread != null) {
19417                        try {
19418                            app.thread.setSchedulingGroup(app.curSchedGroup);
19419                        } catch (RemoteException e) {
19420                        }
19421                    }
19422                }
19423            }
19424        }
19425        if (app.repForegroundActivities != app.foregroundActivities) {
19426            app.repForegroundActivities = app.foregroundActivities;
19427            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19428        }
19429        if (app.repProcState != app.curProcState) {
19430            app.repProcState = app.curProcState;
19431            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19432            if (app.thread != null) {
19433                try {
19434                    if (false) {
19435                        //RuntimeException h = new RuntimeException("here");
19436                        Slog.i(TAG, "Sending new process state " + app.repProcState
19437                                + " to " + app /*, h*/);
19438                    }
19439                    app.thread.setProcessState(app.repProcState);
19440                } catch (RemoteException e) {
19441                }
19442            }
19443        }
19444        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19445                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19446            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19447                // Experimental code to more aggressively collect pss while
19448                // running test...  the problem is that this tends to collect
19449                // the data right when a process is transitioning between process
19450                // states, which well tend to give noisy data.
19451                long start = SystemClock.uptimeMillis();
19452                long pss = Debug.getPss(app.pid, mTmpLong, null);
19453                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19454                mPendingPssProcesses.remove(app);
19455                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19456                        + " to " + app.curProcState + ": "
19457                        + (SystemClock.uptimeMillis()-start) + "ms");
19458            }
19459            app.lastStateTime = now;
19460            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19461                    mTestPssMode, isSleeping(), now);
19462            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19463                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19464                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19465                    + (app.nextPssTime-now) + ": " + app);
19466        } else {
19467            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19468                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19469                    mTestPssMode)))) {
19470                requestPssLocked(app, app.setProcState);
19471                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19472                        mTestPssMode, isSleeping(), now);
19473            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19474                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19475        }
19476        if (app.setProcState != app.curProcState) {
19477            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19478                    "Proc state change of " + app.processName
19479                            + " to " + app.curProcState);
19480            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19481            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19482            if (setImportant && !curImportant) {
19483                // This app is no longer something we consider important enough to allow to
19484                // use arbitrary amounts of battery power.  Note
19485                // its current wake lock time to later know to kill it if
19486                // it is not behaving well.
19487                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19488                synchronized (stats) {
19489                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19490                            app.pid, nowElapsed);
19491                }
19492                app.lastCpuTime = app.curCpuTime;
19493
19494            }
19495            // Inform UsageStats of important process state change
19496            // Must be called before updating setProcState
19497            maybeUpdateUsageStatsLocked(app, nowElapsed);
19498
19499            app.setProcState = app.curProcState;
19500            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19501                app.notCachedSinceIdle = false;
19502            }
19503            if (!doingAll) {
19504                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19505            } else {
19506                app.procStateChanged = true;
19507            }
19508        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19509                > USAGE_STATS_INTERACTION_INTERVAL) {
19510            // For apps that sit around for a long time in the interactive state, we need
19511            // to report this at least once a day so they don't go idle.
19512            maybeUpdateUsageStatsLocked(app, nowElapsed);
19513        }
19514
19515        if (changes != 0) {
19516            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19517                    "Changes in " + app + ": " + changes);
19518            int i = mPendingProcessChanges.size()-1;
19519            ProcessChangeItem item = null;
19520            while (i >= 0) {
19521                item = mPendingProcessChanges.get(i);
19522                if (item.pid == app.pid) {
19523                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19524                            "Re-using existing item: " + item);
19525                    break;
19526                }
19527                i--;
19528            }
19529            if (i < 0) {
19530                // No existing item in pending changes; need a new one.
19531                final int NA = mAvailProcessChanges.size();
19532                if (NA > 0) {
19533                    item = mAvailProcessChanges.remove(NA-1);
19534                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19535                            "Retrieving available item: " + item);
19536                } else {
19537                    item = new ProcessChangeItem();
19538                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19539                            "Allocating new item: " + item);
19540                }
19541                item.changes = 0;
19542                item.pid = app.pid;
19543                item.uid = app.info.uid;
19544                if (mPendingProcessChanges.size() == 0) {
19545                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19546                            "*** Enqueueing dispatch processes changed!");
19547                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19548                }
19549                mPendingProcessChanges.add(item);
19550            }
19551            item.changes |= changes;
19552            item.processState = app.repProcState;
19553            item.foregroundActivities = app.repForegroundActivities;
19554            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19555                    "Item " + Integer.toHexString(System.identityHashCode(item))
19556                    + " " + app.toShortString() + ": changes=" + item.changes
19557                    + " procState=" + item.processState
19558                    + " foreground=" + item.foregroundActivities
19559                    + " type=" + app.adjType + " source=" + app.adjSource
19560                    + " target=" + app.adjTarget);
19561        }
19562
19563        return success;
19564    }
19565
19566    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19567        final UidRecord.ChangeItem pendingChange;
19568        if (uidRec == null || uidRec.pendingChange == null) {
19569            if (mPendingUidChanges.size() == 0) {
19570                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19571                        "*** Enqueueing dispatch uid changed!");
19572                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19573            }
19574            final int NA = mAvailUidChanges.size();
19575            if (NA > 0) {
19576                pendingChange = mAvailUidChanges.remove(NA-1);
19577                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19578                        "Retrieving available item: " + pendingChange);
19579            } else {
19580                pendingChange = new UidRecord.ChangeItem();
19581                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19582                        "Allocating new item: " + pendingChange);
19583            }
19584            if (uidRec != null) {
19585                uidRec.pendingChange = pendingChange;
19586                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19587                    // If this uid is going away, and we haven't yet reported it is gone,
19588                    // then do so now.
19589                    change = UidRecord.CHANGE_GONE_IDLE;
19590                }
19591            } else if (uid < 0) {
19592                throw new IllegalArgumentException("No UidRecord or uid");
19593            }
19594            pendingChange.uidRecord = uidRec;
19595            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19596            mPendingUidChanges.add(pendingChange);
19597        } else {
19598            pendingChange = uidRec.pendingChange;
19599            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19600                change = UidRecord.CHANGE_GONE_IDLE;
19601            }
19602        }
19603        pendingChange.change = change;
19604        pendingChange.processState = uidRec != null
19605                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19606    }
19607
19608    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19609            String authority) {
19610        if (app == null) return;
19611        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19612            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19613            if (userState == null) return;
19614            final long now = SystemClock.elapsedRealtime();
19615            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19616            if (lastReported == null || lastReported < now - 60 * 1000L) {
19617                mUsageStatsService.reportContentProviderUsage(
19618                        authority, providerPkgName, app.userId);
19619                userState.mProviderLastReportedFg.put(authority, now);
19620            }
19621        }
19622    }
19623
19624    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19625        if (DEBUG_USAGE_STATS) {
19626            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19627                    + "] state changes: old = " + app.setProcState + ", new = "
19628                    + app.curProcState);
19629        }
19630        if (mUsageStatsService == null) {
19631            return;
19632        }
19633        boolean isInteraction;
19634        // To avoid some abuse patterns, we are going to be careful about what we consider
19635        // to be an app interaction.  Being the top activity doesn't count while the display
19636        // is sleeping, nor do short foreground services.
19637        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19638            isInteraction = true;
19639            app.fgInteractionTime = 0;
19640        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19641            if (app.fgInteractionTime == 0) {
19642                app.fgInteractionTime = nowElapsed;
19643                isInteraction = false;
19644            } else {
19645                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19646            }
19647        } else {
19648            isInteraction = app.curProcState
19649                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19650            app.fgInteractionTime = 0;
19651        }
19652        if (isInteraction && (!app.reportedInteraction
19653                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19654            app.interactionEventTime = nowElapsed;
19655            String[] packages = app.getPackageList();
19656            if (packages != null) {
19657                for (int i = 0; i < packages.length; i++) {
19658                    mUsageStatsService.reportEvent(packages[i], app.userId,
19659                            UsageEvents.Event.SYSTEM_INTERACTION);
19660                }
19661            }
19662        }
19663        app.reportedInteraction = isInteraction;
19664        if (!isInteraction) {
19665            app.interactionEventTime = 0;
19666        }
19667    }
19668
19669    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19670        if (proc.thread != null) {
19671            if (proc.baseProcessTracker != null) {
19672                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19673            }
19674        }
19675    }
19676
19677    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19678            ProcessRecord TOP_APP, boolean doingAll, long now) {
19679        if (app.thread == null) {
19680            return false;
19681        }
19682
19683        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19684
19685        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19686    }
19687
19688    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19689            boolean oomAdj) {
19690        if (isForeground != proc.foregroundServices) {
19691            proc.foregroundServices = isForeground;
19692            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19693                    proc.info.uid);
19694            if (isForeground) {
19695                if (curProcs == null) {
19696                    curProcs = new ArrayList<ProcessRecord>();
19697                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19698                }
19699                if (!curProcs.contains(proc)) {
19700                    curProcs.add(proc);
19701                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19702                            proc.info.packageName, proc.info.uid);
19703                }
19704            } else {
19705                if (curProcs != null) {
19706                    if (curProcs.remove(proc)) {
19707                        mBatteryStatsService.noteEvent(
19708                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19709                                proc.info.packageName, proc.info.uid);
19710                        if (curProcs.size() <= 0) {
19711                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19712                        }
19713                    }
19714                }
19715            }
19716            if (oomAdj) {
19717                updateOomAdjLocked();
19718            }
19719        }
19720    }
19721
19722    private final ActivityRecord resumedAppLocked() {
19723        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19724        String pkg;
19725        int uid;
19726        if (act != null) {
19727            pkg = act.packageName;
19728            uid = act.info.applicationInfo.uid;
19729        } else {
19730            pkg = null;
19731            uid = -1;
19732        }
19733        // Has the UID or resumed package name changed?
19734        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19735                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19736            if (mCurResumedPackage != null) {
19737                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19738                        mCurResumedPackage, mCurResumedUid);
19739            }
19740            mCurResumedPackage = pkg;
19741            mCurResumedUid = uid;
19742            if (mCurResumedPackage != null) {
19743                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19744                        mCurResumedPackage, mCurResumedUid);
19745            }
19746        }
19747        return act;
19748    }
19749
19750    final boolean updateOomAdjLocked(ProcessRecord app) {
19751        final ActivityRecord TOP_ACT = resumedAppLocked();
19752        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19753        final boolean wasCached = app.cached;
19754
19755        mAdjSeq++;
19756
19757        // This is the desired cached adjusment we want to tell it to use.
19758        // If our app is currently cached, we know it, and that is it.  Otherwise,
19759        // we don't know it yet, and it needs to now be cached we will then
19760        // need to do a complete oom adj.
19761        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19762                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19763        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19764                SystemClock.uptimeMillis());
19765        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19766            // Changed to/from cached state, so apps after it in the LRU
19767            // list may also be changed.
19768            updateOomAdjLocked();
19769        }
19770        return success;
19771    }
19772
19773    final void updateOomAdjLocked() {
19774        final ActivityRecord TOP_ACT = resumedAppLocked();
19775        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19776        final long now = SystemClock.uptimeMillis();
19777        final long nowElapsed = SystemClock.elapsedRealtime();
19778        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19779        final int N = mLruProcesses.size();
19780
19781        if (false) {
19782            RuntimeException e = new RuntimeException();
19783            e.fillInStackTrace();
19784            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19785        }
19786
19787        // Reset state in all uid records.
19788        for (int i=mActiveUids.size()-1; i>=0; i--) {
19789            final UidRecord uidRec = mActiveUids.valueAt(i);
19790            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19791                    "Starting update of " + uidRec);
19792            uidRec.reset();
19793        }
19794
19795        mStackSupervisor.rankTaskLayersIfNeeded();
19796
19797        mAdjSeq++;
19798        mNewNumServiceProcs = 0;
19799        mNewNumAServiceProcs = 0;
19800
19801        final int emptyProcessLimit;
19802        final int cachedProcessLimit;
19803        if (mProcessLimit <= 0) {
19804            emptyProcessLimit = cachedProcessLimit = 0;
19805        } else if (mProcessLimit == 1) {
19806            emptyProcessLimit = 1;
19807            cachedProcessLimit = 0;
19808        } else {
19809            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19810            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19811        }
19812
19813        // Let's determine how many processes we have running vs.
19814        // how many slots we have for background processes; we may want
19815        // to put multiple processes in a slot of there are enough of
19816        // them.
19817        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19818                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19819        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19820        if (numEmptyProcs > cachedProcessLimit) {
19821            // If there are more empty processes than our limit on cached
19822            // processes, then use the cached process limit for the factor.
19823            // This ensures that the really old empty processes get pushed
19824            // down to the bottom, so if we are running low on memory we will
19825            // have a better chance at keeping around more cached processes
19826            // instead of a gazillion empty processes.
19827            numEmptyProcs = cachedProcessLimit;
19828        }
19829        int emptyFactor = numEmptyProcs/numSlots;
19830        if (emptyFactor < 1) emptyFactor = 1;
19831        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19832        if (cachedFactor < 1) cachedFactor = 1;
19833        int stepCached = 0;
19834        int stepEmpty = 0;
19835        int numCached = 0;
19836        int numEmpty = 0;
19837        int numTrimming = 0;
19838
19839        mNumNonCachedProcs = 0;
19840        mNumCachedHiddenProcs = 0;
19841
19842        // First update the OOM adjustment for each of the
19843        // application processes based on their current state.
19844        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19845        int nextCachedAdj = curCachedAdj+1;
19846        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19847        int nextEmptyAdj = curEmptyAdj+2;
19848        for (int i=N-1; i>=0; i--) {
19849            ProcessRecord app = mLruProcesses.get(i);
19850            if (!app.killedByAm && app.thread != null) {
19851                app.procStateChanged = false;
19852                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19853
19854                // If we haven't yet assigned the final cached adj
19855                // to the process, do that now.
19856                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19857                    switch (app.curProcState) {
19858                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19859                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19860                            // This process is a cached process holding activities...
19861                            // assign it the next cached value for that type, and then
19862                            // step that cached level.
19863                            app.curRawAdj = curCachedAdj;
19864                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19865                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19866                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19867                                    + ")");
19868                            if (curCachedAdj != nextCachedAdj) {
19869                                stepCached++;
19870                                if (stepCached >= cachedFactor) {
19871                                    stepCached = 0;
19872                                    curCachedAdj = nextCachedAdj;
19873                                    nextCachedAdj += 2;
19874                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19875                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19876                                    }
19877                                }
19878                            }
19879                            break;
19880                        default:
19881                            // For everything else, assign next empty cached process
19882                            // level and bump that up.  Note that this means that
19883                            // long-running services that have dropped down to the
19884                            // cached level will be treated as empty (since their process
19885                            // state is still as a service), which is what we want.
19886                            app.curRawAdj = curEmptyAdj;
19887                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19888                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19889                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19890                                    + ")");
19891                            if (curEmptyAdj != nextEmptyAdj) {
19892                                stepEmpty++;
19893                                if (stepEmpty >= emptyFactor) {
19894                                    stepEmpty = 0;
19895                                    curEmptyAdj = nextEmptyAdj;
19896                                    nextEmptyAdj += 2;
19897                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19898                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19899                                    }
19900                                }
19901                            }
19902                            break;
19903                    }
19904                }
19905
19906                applyOomAdjLocked(app, true, now, nowElapsed);
19907
19908                // Count the number of process types.
19909                switch (app.curProcState) {
19910                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19911                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19912                        mNumCachedHiddenProcs++;
19913                        numCached++;
19914                        if (numCached > cachedProcessLimit) {
19915                            app.kill("cached #" + numCached, true);
19916                        }
19917                        break;
19918                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19919                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19920                                && app.lastActivityTime < oldTime) {
19921                            app.kill("empty for "
19922                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19923                                    / 1000) + "s", true);
19924                        } else {
19925                            numEmpty++;
19926                            if (numEmpty > emptyProcessLimit) {
19927                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19928                            }
19929                        }
19930                        break;
19931                    default:
19932                        mNumNonCachedProcs++;
19933                        break;
19934                }
19935
19936                if (app.isolated && app.services.size() <= 0) {
19937                    // If this is an isolated process, and there are no
19938                    // services running in it, then the process is no longer
19939                    // needed.  We agressively kill these because we can by
19940                    // definition not re-use the same process again, and it is
19941                    // good to avoid having whatever code was running in them
19942                    // left sitting around after no longer needed.
19943                    app.kill("isolated not needed", true);
19944                } else {
19945                    // Keeping this process, update its uid.
19946                    final UidRecord uidRec = app.uidRecord;
19947                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19948                        uidRec.curProcState = app.curProcState;
19949                    }
19950                }
19951
19952                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19953                        && !app.killedByAm) {
19954                    numTrimming++;
19955                }
19956            }
19957        }
19958
19959        mNumServiceProcs = mNewNumServiceProcs;
19960
19961        // Now determine the memory trimming level of background processes.
19962        // Unfortunately we need to start at the back of the list to do this
19963        // properly.  We only do this if the number of background apps we
19964        // are managing to keep around is less than half the maximum we desire;
19965        // if we are keeping a good number around, we'll let them use whatever
19966        // memory they want.
19967        final int numCachedAndEmpty = numCached + numEmpty;
19968        int memFactor;
19969        if (numCached <= ProcessList.TRIM_CACHED_APPS
19970                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19971            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19972                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19973            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19974                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19975            } else {
19976                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19977            }
19978        } else {
19979            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19980        }
19981        // We always allow the memory level to go up (better).  We only allow it to go
19982        // down if we are in a state where that is allowed, *and* the total number of processes
19983        // has gone down since last time.
19984        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19985                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19986                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19987        if (memFactor > mLastMemoryLevel) {
19988            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19989                memFactor = mLastMemoryLevel;
19990                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19991            }
19992        }
19993        mLastMemoryLevel = memFactor;
19994        mLastNumProcesses = mLruProcesses.size();
19995        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19996        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19997        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19998            if (mLowRamStartTime == 0) {
19999                mLowRamStartTime = now;
20000            }
20001            int step = 0;
20002            int fgTrimLevel;
20003            switch (memFactor) {
20004                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20005                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20006                    break;
20007                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20008                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20009                    break;
20010                default:
20011                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20012                    break;
20013            }
20014            int factor = numTrimming/3;
20015            int minFactor = 2;
20016            if (mHomeProcess != null) minFactor++;
20017            if (mPreviousProcess != null) minFactor++;
20018            if (factor < minFactor) factor = minFactor;
20019            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20020            for (int i=N-1; i>=0; i--) {
20021                ProcessRecord app = mLruProcesses.get(i);
20022                if (allChanged || app.procStateChanged) {
20023                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20024                    app.procStateChanged = false;
20025                }
20026                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20027                        && !app.killedByAm) {
20028                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20029                        try {
20030                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20031                                    "Trimming memory of " + app.processName + " to " + curLevel);
20032                            app.thread.scheduleTrimMemory(curLevel);
20033                        } catch (RemoteException e) {
20034                        }
20035                        if (false) {
20036                            // For now we won't do this; our memory trimming seems
20037                            // to be good enough at this point that destroying
20038                            // activities causes more harm than good.
20039                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20040                                    && app != mHomeProcess && app != mPreviousProcess) {
20041                                // Need to do this on its own message because the stack may not
20042                                // be in a consistent state at this point.
20043                                // For these apps we will also finish their activities
20044                                // to help them free memory.
20045                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20046                            }
20047                        }
20048                    }
20049                    app.trimMemoryLevel = curLevel;
20050                    step++;
20051                    if (step >= factor) {
20052                        step = 0;
20053                        switch (curLevel) {
20054                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20055                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20056                                break;
20057                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20058                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20059                                break;
20060                        }
20061                    }
20062                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20063                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20064                            && app.thread != null) {
20065                        try {
20066                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20067                                    "Trimming memory of heavy-weight " + app.processName
20068                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20069                            app.thread.scheduleTrimMemory(
20070                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20071                        } catch (RemoteException e) {
20072                        }
20073                    }
20074                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20075                } else {
20076                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20077                            || app.systemNoUi) && app.pendingUiClean) {
20078                        // If this application is now in the background and it
20079                        // had done UI, then give it the special trim level to
20080                        // have it free UI resources.
20081                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20082                        if (app.trimMemoryLevel < level && app.thread != null) {
20083                            try {
20084                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20085                                        "Trimming memory of bg-ui " + app.processName
20086                                        + " to " + level);
20087                                app.thread.scheduleTrimMemory(level);
20088                            } catch (RemoteException e) {
20089                            }
20090                        }
20091                        app.pendingUiClean = false;
20092                    }
20093                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20094                        try {
20095                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20096                                    "Trimming memory of fg " + app.processName
20097                                    + " to " + fgTrimLevel);
20098                            app.thread.scheduleTrimMemory(fgTrimLevel);
20099                        } catch (RemoteException e) {
20100                        }
20101                    }
20102                    app.trimMemoryLevel = fgTrimLevel;
20103                }
20104            }
20105        } else {
20106            if (mLowRamStartTime != 0) {
20107                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20108                mLowRamStartTime = 0;
20109            }
20110            for (int i=N-1; i>=0; i--) {
20111                ProcessRecord app = mLruProcesses.get(i);
20112                if (allChanged || app.procStateChanged) {
20113                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20114                    app.procStateChanged = false;
20115                }
20116                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20117                        || app.systemNoUi) && app.pendingUiClean) {
20118                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20119                            && app.thread != null) {
20120                        try {
20121                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20122                                    "Trimming memory of ui hidden " + app.processName
20123                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20124                            app.thread.scheduleTrimMemory(
20125                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20126                        } catch (RemoteException e) {
20127                        }
20128                    }
20129                    app.pendingUiClean = false;
20130                }
20131                app.trimMemoryLevel = 0;
20132            }
20133        }
20134
20135        if (mAlwaysFinishActivities) {
20136            // Need to do this on its own message because the stack may not
20137            // be in a consistent state at this point.
20138            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20139        }
20140
20141        if (allChanged) {
20142            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20143        }
20144
20145        // Update from any uid changes.
20146        for (int i=mActiveUids.size()-1; i>=0; i--) {
20147            final UidRecord uidRec = mActiveUids.valueAt(i);
20148            int uidChange = UidRecord.CHANGE_PROCSTATE;
20149            if (uidRec.setProcState != uidRec.curProcState) {
20150                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20151                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20152                        + " to " + uidRec.curProcState);
20153                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20154                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20155                        uidRec.lastBackgroundTime = nowElapsed;
20156                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20157                            // Note: the background settle time is in elapsed realtime, while
20158                            // the handler time base is uptime.  All this means is that we may
20159                            // stop background uids later than we had intended, but that only
20160                            // happens because the device was sleeping so we are okay anyway.
20161                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20162                        }
20163                    }
20164                } else {
20165                    if (uidRec.idle) {
20166                        uidChange = UidRecord.CHANGE_ACTIVE;
20167                        uidRec.idle = false;
20168                    }
20169                    uidRec.lastBackgroundTime = 0;
20170                }
20171                uidRec.setProcState = uidRec.curProcState;
20172                enqueueUidChangeLocked(uidRec, -1, uidChange);
20173                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20174            }
20175        }
20176
20177        if (mProcessStats.shouldWriteNowLocked(now)) {
20178            mHandler.post(new Runnable() {
20179                @Override public void run() {
20180                    synchronized (ActivityManagerService.this) {
20181                        mProcessStats.writeStateAsyncLocked();
20182                    }
20183                }
20184            });
20185        }
20186
20187        if (DEBUG_OOM_ADJ) {
20188            final long duration = SystemClock.uptimeMillis() - now;
20189            if (false) {
20190                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20191                        new RuntimeException("here").fillInStackTrace());
20192            } else {
20193                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20194            }
20195        }
20196    }
20197
20198    final void idleUids() {
20199        synchronized (this) {
20200            final long nowElapsed = SystemClock.elapsedRealtime();
20201            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20202            long nextTime = 0;
20203            for (int i=mActiveUids.size()-1; i>=0; i--) {
20204                final UidRecord uidRec = mActiveUids.valueAt(i);
20205                final long bgTime = uidRec.lastBackgroundTime;
20206                if (bgTime > 0 && !uidRec.idle) {
20207                    if (bgTime <= maxBgTime) {
20208                        uidRec.idle = true;
20209                        doStopUidLocked(uidRec.uid, uidRec);
20210                    } else {
20211                        if (nextTime == 0 || nextTime > bgTime) {
20212                            nextTime = bgTime;
20213                        }
20214                    }
20215                }
20216            }
20217            if (nextTime > 0) {
20218                mHandler.removeMessages(IDLE_UIDS_MSG);
20219                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20220                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20221            }
20222        }
20223    }
20224
20225    final void runInBackgroundDisabled(int uid) {
20226        synchronized (this) {
20227            UidRecord uidRec = mActiveUids.get(uid);
20228            if (uidRec != null) {
20229                // This uid is actually running...  should it be considered background now?
20230                if (uidRec.idle) {
20231                    doStopUidLocked(uidRec.uid, uidRec);
20232                }
20233            } else {
20234                // This uid isn't actually running...  still send a report about it being "stopped".
20235                doStopUidLocked(uid, null);
20236            }
20237        }
20238    }
20239
20240    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20241        mServices.stopInBackgroundLocked(uid);
20242        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20243    }
20244
20245    final void trimApplications() {
20246        synchronized (this) {
20247            int i;
20248
20249            // First remove any unused application processes whose package
20250            // has been removed.
20251            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20252                final ProcessRecord app = mRemovedProcesses.get(i);
20253                if (app.activities.size() == 0
20254                        && app.curReceiver == null && app.services.size() == 0) {
20255                    Slog.i(
20256                        TAG, "Exiting empty application process "
20257                        + app.processName + " ("
20258                        + (app.thread != null ? app.thread.asBinder() : null)
20259                        + ")\n");
20260                    if (app.pid > 0 && app.pid != MY_PID) {
20261                        app.kill("empty", false);
20262                    } else {
20263                        try {
20264                            app.thread.scheduleExit();
20265                        } catch (Exception e) {
20266                            // Ignore exceptions.
20267                        }
20268                    }
20269                    cleanUpApplicationRecordLocked(app, false, true, -1);
20270                    mRemovedProcesses.remove(i);
20271
20272                    if (app.persistent) {
20273                        addAppLocked(app.info, false, null /* ABI override */);
20274                    }
20275                }
20276            }
20277
20278            // Now update the oom adj for all processes.
20279            updateOomAdjLocked();
20280        }
20281    }
20282
20283    /** This method sends the specified signal to each of the persistent apps */
20284    public void signalPersistentProcesses(int sig) throws RemoteException {
20285        if (sig != Process.SIGNAL_USR1) {
20286            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20287        }
20288
20289        synchronized (this) {
20290            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20291                    != PackageManager.PERMISSION_GRANTED) {
20292                throw new SecurityException("Requires permission "
20293                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20294            }
20295
20296            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20297                ProcessRecord r = mLruProcesses.get(i);
20298                if (r.thread != null && r.persistent) {
20299                    Process.sendSignal(r.pid, sig);
20300                }
20301            }
20302        }
20303    }
20304
20305    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20306        if (proc == null || proc == mProfileProc) {
20307            proc = mProfileProc;
20308            profileType = mProfileType;
20309            clearProfilerLocked();
20310        }
20311        if (proc == null) {
20312            return;
20313        }
20314        try {
20315            proc.thread.profilerControl(false, null, profileType);
20316        } catch (RemoteException e) {
20317            throw new IllegalStateException("Process disappeared");
20318        }
20319    }
20320
20321    private void clearProfilerLocked() {
20322        if (mProfileFd != null) {
20323            try {
20324                mProfileFd.close();
20325            } catch (IOException e) {
20326            }
20327        }
20328        mProfileApp = null;
20329        mProfileProc = null;
20330        mProfileFile = null;
20331        mProfileType = 0;
20332        mAutoStopProfiler = false;
20333        mSamplingInterval = 0;
20334    }
20335
20336    public boolean profileControl(String process, int userId, boolean start,
20337            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20338
20339        try {
20340            synchronized (this) {
20341                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20342                // its own permission.
20343                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20344                        != PackageManager.PERMISSION_GRANTED) {
20345                    throw new SecurityException("Requires permission "
20346                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20347                }
20348
20349                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20350                    throw new IllegalArgumentException("null profile info or fd");
20351                }
20352
20353                ProcessRecord proc = null;
20354                if (process != null) {
20355                    proc = findProcessLocked(process, userId, "profileControl");
20356                }
20357
20358                if (start && (proc == null || proc.thread == null)) {
20359                    throw new IllegalArgumentException("Unknown process: " + process);
20360                }
20361
20362                if (start) {
20363                    stopProfilerLocked(null, 0);
20364                    setProfileApp(proc.info, proc.processName, profilerInfo);
20365                    mProfileProc = proc;
20366                    mProfileType = profileType;
20367                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20368                    try {
20369                        fd = fd.dup();
20370                    } catch (IOException e) {
20371                        fd = null;
20372                    }
20373                    profilerInfo.profileFd = fd;
20374                    proc.thread.profilerControl(start, profilerInfo, profileType);
20375                    fd = null;
20376                    mProfileFd = null;
20377                } else {
20378                    stopProfilerLocked(proc, profileType);
20379                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20380                        try {
20381                            profilerInfo.profileFd.close();
20382                        } catch (IOException e) {
20383                        }
20384                    }
20385                }
20386
20387                return true;
20388            }
20389        } catch (RemoteException e) {
20390            throw new IllegalStateException("Process disappeared");
20391        } finally {
20392            if (profilerInfo != null && profilerInfo.profileFd != null) {
20393                try {
20394                    profilerInfo.profileFd.close();
20395                } catch (IOException e) {
20396                }
20397            }
20398        }
20399    }
20400
20401    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20402        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20403                userId, true, ALLOW_FULL_ONLY, callName, null);
20404        ProcessRecord proc = null;
20405        try {
20406            int pid = Integer.parseInt(process);
20407            synchronized (mPidsSelfLocked) {
20408                proc = mPidsSelfLocked.get(pid);
20409            }
20410        } catch (NumberFormatException e) {
20411        }
20412
20413        if (proc == null) {
20414            ArrayMap<String, SparseArray<ProcessRecord>> all
20415                    = mProcessNames.getMap();
20416            SparseArray<ProcessRecord> procs = all.get(process);
20417            if (procs != null && procs.size() > 0) {
20418                proc = procs.valueAt(0);
20419                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20420                    for (int i=1; i<procs.size(); i++) {
20421                        ProcessRecord thisProc = procs.valueAt(i);
20422                        if (thisProc.userId == userId) {
20423                            proc = thisProc;
20424                            break;
20425                        }
20426                    }
20427                }
20428            }
20429        }
20430
20431        return proc;
20432    }
20433
20434    public boolean dumpHeap(String process, int userId, boolean managed,
20435            String path, ParcelFileDescriptor fd) throws RemoteException {
20436
20437        try {
20438            synchronized (this) {
20439                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20440                // its own permission (same as profileControl).
20441                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20442                        != PackageManager.PERMISSION_GRANTED) {
20443                    throw new SecurityException("Requires permission "
20444                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20445                }
20446
20447                if (fd == null) {
20448                    throw new IllegalArgumentException("null fd");
20449                }
20450
20451                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20452                if (proc == null || proc.thread == null) {
20453                    throw new IllegalArgumentException("Unknown process: " + process);
20454                }
20455
20456                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20457                if (!isDebuggable) {
20458                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20459                        throw new SecurityException("Process not debuggable: " + proc);
20460                    }
20461                }
20462
20463                proc.thread.dumpHeap(managed, path, fd);
20464                fd = null;
20465                return true;
20466            }
20467        } catch (RemoteException e) {
20468            throw new IllegalStateException("Process disappeared");
20469        } finally {
20470            if (fd != null) {
20471                try {
20472                    fd.close();
20473                } catch (IOException e) {
20474                }
20475            }
20476        }
20477    }
20478
20479    @Override
20480    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20481            String reportPackage) {
20482        if (processName != null) {
20483            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20484                    "setDumpHeapDebugLimit()");
20485        } else {
20486            synchronized (mPidsSelfLocked) {
20487                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20488                if (proc == null) {
20489                    throw new SecurityException("No process found for calling pid "
20490                            + Binder.getCallingPid());
20491                }
20492                if (!Build.IS_DEBUGGABLE
20493                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20494                    throw new SecurityException("Not running a debuggable build");
20495                }
20496                processName = proc.processName;
20497                uid = proc.uid;
20498                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20499                    throw new SecurityException("Package " + reportPackage + " is not running in "
20500                            + proc);
20501                }
20502            }
20503        }
20504        synchronized (this) {
20505            if (maxMemSize > 0) {
20506                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20507            } else {
20508                if (uid != 0) {
20509                    mMemWatchProcesses.remove(processName, uid);
20510                } else {
20511                    mMemWatchProcesses.getMap().remove(processName);
20512                }
20513            }
20514        }
20515    }
20516
20517    @Override
20518    public void dumpHeapFinished(String path) {
20519        synchronized (this) {
20520            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20521                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20522                        + " does not match last pid " + mMemWatchDumpPid);
20523                return;
20524            }
20525            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20526                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20527                        + " does not match last path " + mMemWatchDumpFile);
20528                return;
20529            }
20530            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20531            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20532        }
20533    }
20534
20535    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20536    public void monitor() {
20537        synchronized (this) { }
20538    }
20539
20540    void onCoreSettingsChange(Bundle settings) {
20541        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20542            ProcessRecord processRecord = mLruProcesses.get(i);
20543            try {
20544                if (processRecord.thread != null) {
20545                    processRecord.thread.setCoreSettings(settings);
20546                }
20547            } catch (RemoteException re) {
20548                /* ignore */
20549            }
20550        }
20551    }
20552
20553    // Multi-user methods
20554
20555    /**
20556     * Start user, if its not already running, but don't bring it to foreground.
20557     */
20558    @Override
20559    public boolean startUserInBackground(final int userId) {
20560        return mUserController.startUser(userId, /* foreground */ false);
20561    }
20562
20563    @Override
20564    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20565        return mUserController.unlockUser(userId, token, secret);
20566    }
20567
20568    @Override
20569    public boolean switchUser(final int targetUserId) {
20570        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20571        UserInfo currentUserInfo;
20572        UserInfo targetUserInfo;
20573        synchronized (this) {
20574            int currentUserId = mUserController.getCurrentUserIdLocked();
20575            currentUserInfo = mUserController.getUserInfo(currentUserId);
20576            targetUserInfo = mUserController.getUserInfo(targetUserId);
20577            if (targetUserInfo == null) {
20578                Slog.w(TAG, "No user info for user #" + targetUserId);
20579                return false;
20580            }
20581            if (!targetUserInfo.supportsSwitchTo()) {
20582                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20583                return false;
20584            }
20585            if (targetUserInfo.isManagedProfile()) {
20586                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20587                return false;
20588            }
20589            mUserController.setTargetUserIdLocked(targetUserId);
20590        }
20591        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20592        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20593        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20594        return true;
20595    }
20596
20597    void scheduleStartProfilesLocked() {
20598        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20599            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20600                    DateUtils.SECOND_IN_MILLIS);
20601        }
20602    }
20603
20604    @Override
20605    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20606        return mUserController.stopUser(userId, force, callback);
20607    }
20608
20609    @Override
20610    public UserInfo getCurrentUser() {
20611        return mUserController.getCurrentUser();
20612    }
20613
20614    @Override
20615    public boolean isUserRunning(int userId, int flags) {
20616        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20617                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20618            String msg = "Permission Denial: isUserRunning() from pid="
20619                    + Binder.getCallingPid()
20620                    + ", uid=" + Binder.getCallingUid()
20621                    + " requires " + INTERACT_ACROSS_USERS;
20622            Slog.w(TAG, msg);
20623            throw new SecurityException(msg);
20624        }
20625        synchronized (this) {
20626            return mUserController.isUserRunningLocked(userId, flags);
20627        }
20628    }
20629
20630    @Override
20631    public int[] getRunningUserIds() {
20632        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20633                != PackageManager.PERMISSION_GRANTED) {
20634            String msg = "Permission Denial: isUserRunning() from pid="
20635                    + Binder.getCallingPid()
20636                    + ", uid=" + Binder.getCallingUid()
20637                    + " requires " + INTERACT_ACROSS_USERS;
20638            Slog.w(TAG, msg);
20639            throw new SecurityException(msg);
20640        }
20641        synchronized (this) {
20642            return mUserController.getStartedUserArrayLocked();
20643        }
20644    }
20645
20646    @Override
20647    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20648        mUserController.registerUserSwitchObserver(observer);
20649    }
20650
20651    @Override
20652    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20653        mUserController.unregisterUserSwitchObserver(observer);
20654    }
20655
20656    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20657        if (info == null) return null;
20658        ApplicationInfo newInfo = new ApplicationInfo(info);
20659        newInfo.initForUser(userId);
20660        return newInfo;
20661    }
20662
20663    public boolean isUserStopped(int userId) {
20664        synchronized (this) {
20665            return mUserController.getStartedUserStateLocked(userId) == null;
20666        }
20667    }
20668
20669    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20670        if (aInfo == null
20671                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20672            return aInfo;
20673        }
20674
20675        ActivityInfo info = new ActivityInfo(aInfo);
20676        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20677        return info;
20678    }
20679
20680    private boolean processSanityChecksLocked(ProcessRecord process) {
20681        if (process == null || process.thread == null) {
20682            return false;
20683        }
20684
20685        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20686        if (!isDebuggable) {
20687            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20688                return false;
20689            }
20690        }
20691
20692        return true;
20693    }
20694
20695    public boolean startBinderTracking() throws RemoteException {
20696        synchronized (this) {
20697            mBinderTransactionTrackingEnabled = true;
20698            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20699            // permission (same as profileControl).
20700            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20701                    != PackageManager.PERMISSION_GRANTED) {
20702                throw new SecurityException("Requires permission "
20703                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20704            }
20705
20706            for (int i = 0; i < mLruProcesses.size(); i++) {
20707                ProcessRecord process = mLruProcesses.get(i);
20708                if (!processSanityChecksLocked(process)) {
20709                    continue;
20710                }
20711                try {
20712                    process.thread.startBinderTracking();
20713                } catch (RemoteException e) {
20714                    Log.v(TAG, "Process disappared");
20715                }
20716            }
20717            return true;
20718        }
20719    }
20720
20721    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20722        try {
20723            synchronized (this) {
20724                mBinderTransactionTrackingEnabled = false;
20725                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20726                // permission (same as profileControl).
20727                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20728                        != PackageManager.PERMISSION_GRANTED) {
20729                    throw new SecurityException("Requires permission "
20730                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20731                }
20732
20733                if (fd == null) {
20734                    throw new IllegalArgumentException("null fd");
20735                }
20736
20737                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20738                pw.println("Binder transaction traces for all processes.\n");
20739                for (ProcessRecord process : mLruProcesses) {
20740                    if (!processSanityChecksLocked(process)) {
20741                        continue;
20742                    }
20743
20744                    pw.println("Traces for process: " + process.processName);
20745                    pw.flush();
20746                    try {
20747                        TransferPipe tp = new TransferPipe();
20748                        try {
20749                            process.thread.stopBinderTrackingAndDump(
20750                                    tp.getWriteFd().getFileDescriptor());
20751                            tp.go(fd.getFileDescriptor());
20752                        } finally {
20753                            tp.kill();
20754                        }
20755                    } catch (IOException e) {
20756                        pw.println("Failure while dumping IPC traces from " + process +
20757                                ".  Exception: " + e);
20758                        pw.flush();
20759                    } catch (RemoteException e) {
20760                        pw.println("Got a RemoteException while dumping IPC traces from " +
20761                                process + ".  Exception: " + e);
20762                        pw.flush();
20763                    }
20764                }
20765                fd = null;
20766                return true;
20767            }
20768        } finally {
20769            if (fd != null) {
20770                try {
20771                    fd.close();
20772                } catch (IOException e) {
20773                }
20774            }
20775        }
20776    }
20777
20778    private final class LocalService extends ActivityManagerInternal {
20779        @Override
20780        public void onWakefulnessChanged(int wakefulness) {
20781            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20782        }
20783
20784        @Override
20785        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20786                String processName, String abiOverride, int uid, Runnable crashHandler) {
20787            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20788                    processName, abiOverride, uid, crashHandler);
20789        }
20790
20791        @Override
20792        public SleepToken acquireSleepToken(String tag) {
20793            Preconditions.checkNotNull(tag);
20794
20795            synchronized (ActivityManagerService.this) {
20796                SleepTokenImpl token = new SleepTokenImpl(tag);
20797                mSleepTokens.add(token);
20798                updateSleepIfNeededLocked();
20799                return token;
20800            }
20801        }
20802
20803        @Override
20804        public ComponentName getHomeActivityForUser(int userId) {
20805            synchronized (ActivityManagerService.this) {
20806                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20807                return homeActivity == null ? null : homeActivity.realActivity;
20808            }
20809        }
20810
20811        @Override
20812        public void onUserRemoved(int userId) {
20813            synchronized (ActivityManagerService.this) {
20814                ActivityManagerService.this.onUserStoppedLocked(userId);
20815            }
20816        }
20817
20818        @Override
20819        public void onLocalVoiceInteractionStarted(IBinder activity,
20820                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20821            synchronized (ActivityManagerService.this) {
20822                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20823                        voiceSession, voiceInteractor);
20824            }
20825        }
20826
20827        @Override
20828        public void notifyStartingWindowDrawn() {
20829            synchronized (ActivityManagerService.this) {
20830                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20831            }
20832        }
20833
20834        @Override
20835        public void notifyAppTransitionStarting(int reason) {
20836            synchronized (ActivityManagerService.this) {
20837                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20838            }
20839        }
20840    }
20841
20842    private final class SleepTokenImpl extends SleepToken {
20843        private final String mTag;
20844        private final long mAcquireTime;
20845
20846        public SleepTokenImpl(String tag) {
20847            mTag = tag;
20848            mAcquireTime = SystemClock.uptimeMillis();
20849        }
20850
20851        @Override
20852        public void release() {
20853            synchronized (ActivityManagerService.this) {
20854                if (mSleepTokens.remove(this)) {
20855                    updateSleepIfNeededLocked();
20856                }
20857            }
20858        }
20859
20860        @Override
20861        public String toString() {
20862            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20863        }
20864    }
20865
20866    /**
20867     * An implementation of IAppTask, that allows an app to manage its own tasks via
20868     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20869     * only the process that calls getAppTasks() can call the AppTask methods.
20870     */
20871    class AppTaskImpl extends IAppTask.Stub {
20872        private int mTaskId;
20873        private int mCallingUid;
20874
20875        public AppTaskImpl(int taskId, int callingUid) {
20876            mTaskId = taskId;
20877            mCallingUid = callingUid;
20878        }
20879
20880        private void checkCaller() {
20881            if (mCallingUid != Binder.getCallingUid()) {
20882                throw new SecurityException("Caller " + mCallingUid
20883                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20884            }
20885        }
20886
20887        @Override
20888        public void finishAndRemoveTask() {
20889            checkCaller();
20890
20891            synchronized (ActivityManagerService.this) {
20892                long origId = Binder.clearCallingIdentity();
20893                try {
20894                    // We remove the task from recents to preserve backwards
20895                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20896                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20897                    }
20898                } finally {
20899                    Binder.restoreCallingIdentity(origId);
20900                }
20901            }
20902        }
20903
20904        @Override
20905        public ActivityManager.RecentTaskInfo getTaskInfo() {
20906            checkCaller();
20907
20908            synchronized (ActivityManagerService.this) {
20909                long origId = Binder.clearCallingIdentity();
20910                try {
20911                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20912                    if (tr == null) {
20913                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20914                    }
20915                    return createRecentTaskInfoFromTaskRecord(tr);
20916                } finally {
20917                    Binder.restoreCallingIdentity(origId);
20918                }
20919            }
20920        }
20921
20922        @Override
20923        public void moveToFront() {
20924            checkCaller();
20925            // Will bring task to front if it already has a root activity.
20926            final long origId = Binder.clearCallingIdentity();
20927            try {
20928                startActivityFromRecentsInner(mTaskId, null);
20929            } finally {
20930                Binder.restoreCallingIdentity(origId);
20931            }
20932        }
20933
20934        @Override
20935        public int startActivity(IBinder whoThread, String callingPackage,
20936                Intent intent, String resolvedType, Bundle bOptions) {
20937            checkCaller();
20938
20939            int callingUser = UserHandle.getCallingUserId();
20940            TaskRecord tr;
20941            IApplicationThread appThread;
20942            synchronized (ActivityManagerService.this) {
20943                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20944                if (tr == null) {
20945                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20946                }
20947                appThread = ApplicationThreadNative.asInterface(whoThread);
20948                if (appThread == null) {
20949                    throw new IllegalArgumentException("Bad app thread " + appThread);
20950                }
20951            }
20952            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20953                    resolvedType, null, null, null, null, 0, 0, null, null,
20954                    null, bOptions, false, callingUser, null, tr);
20955        }
20956
20957        @Override
20958        public void setExcludeFromRecents(boolean exclude) {
20959            checkCaller();
20960
20961            synchronized (ActivityManagerService.this) {
20962                long origId = Binder.clearCallingIdentity();
20963                try {
20964                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20965                    if (tr == null) {
20966                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20967                    }
20968                    Intent intent = tr.getBaseIntent();
20969                    if (exclude) {
20970                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20971                    } else {
20972                        intent.setFlags(intent.getFlags()
20973                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20974                    }
20975                } finally {
20976                    Binder.restoreCallingIdentity(origId);
20977                }
20978            }
20979        }
20980    }
20981
20982    /**
20983     * Kill processes for the user with id userId and that depend on the package named packageName
20984     */
20985    @Override
20986    public void killPackageDependents(String packageName, int userId) {
20987        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20988        if (packageName == null) {
20989            throw new NullPointerException(
20990                    "Cannot kill the dependents of a package without its name.");
20991        }
20992
20993        long callingId = Binder.clearCallingIdentity();
20994        IPackageManager pm = AppGlobals.getPackageManager();
20995        int pkgUid = -1;
20996        try {
20997            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20998        } catch (RemoteException e) {
20999        }
21000        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21001            throw new IllegalArgumentException(
21002                    "Cannot kill dependents of non-existing package " + packageName);
21003        }
21004        try {
21005            synchronized(this) {
21006                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21007                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21008                        "dep: " + packageName);
21009            }
21010        } finally {
21011            Binder.restoreCallingIdentity(callingId);
21012        }
21013    }
21014}
21015