ActivityManagerService.java revision 78f16950c62c68ccc6a5547f7388afd9b1c77fde
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.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519    static final int FIRST_COMPAT_MODE_MSG = 300;
1520    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522    static ServiceThread sKillThread = null;
1523    static KillHandler sKillHandler = null;
1524
1525    CompatModeDialog mCompatModeDialog;
1526    long mLastMemUsageReportTime = 0;
1527
1528    /**
1529     * Flag whether the current user is a "monkey", i.e. whether
1530     * the UI is driven by a UI automation tool.
1531     */
1532    private boolean mUserIsMonkey;
1533
1534    /** Flag whether the device has a Recents UI */
1535    boolean mHasRecents;
1536
1537    /** The dimensions of the thumbnails in the Recents UI. */
1538    int mThumbnailWidth;
1539    int mThumbnailHeight;
1540    float mFullscreenThumbnailScale;
1541
1542    final ServiceThread mHandlerThread;
1543    final MainHandler mHandler;
1544    final UiHandler mUiHandler;
1545
1546    PackageManagerInternal mPackageManagerInt;
1547
1548    // VoiceInteraction session ID that changes for each new request except when
1549    // being called for multiwindow assist in a single session.
1550    private int mViSessionId = 1000;
1551
1552    final class KillHandler extends Handler {
1553        static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555        public KillHandler(Looper looper) {
1556            super(looper, null, true);
1557        }
1558
1559        @Override
1560        public void handleMessage(Message msg) {
1561            switch (msg.what) {
1562                case KILL_PROCESS_GROUP_MSG:
1563                {
1564                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                }
1568                break;
1569
1570                default:
1571                    super.handleMessage(msg);
1572            }
1573        }
1574    }
1575
1576    final class UiHandler extends Handler {
1577        public UiHandler() {
1578            super(com.android.server.UiThread.get().getLooper(), null, true);
1579        }
1580
1581        @Override
1582        public void handleMessage(Message msg) {
1583            switch (msg.what) {
1584            case SHOW_ERROR_UI_MSG: {
1585                mAppErrors.handleShowAppErrorUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_NOT_RESPONDING_UI_MSG: {
1589                mAppErrors.handleShowAnrUi(msg);
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord proc = (ProcessRecord) data.get("app");
1596                    if (proc == null) {
1597                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                        break;
1599                    }
1600                    if (proc.crashDialog != null) {
1601                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                        return;
1603                    }
1604                    AppErrorResult res = (AppErrorResult) data.get("result");
1605                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                        Dialog d = new StrictModeViolationDialog(mContext,
1607                                ActivityManagerService.this, res, proc);
1608                        d.show();
1609                        proc.crashDialog = d;
1610                    } else {
1611                        // The device is asleep, so just pretend that the user
1612                        // saw a crash dialog and hit "force quit".
1613                        res.set(0);
1614                    }
1615                }
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_FACTORY_ERROR_UI_MSG: {
1619                Dialog d = new FactoryErrorDialog(
1620                    mContext, msg.getData().getCharSequence("msg"));
1621                d.show();
1622                ensureBootCompleted();
1623            } break;
1624            case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ProcessRecord app = (ProcessRecord)msg.obj;
1627                    if (msg.arg1 != 0) {
1628                        if (!app.waitedForDebugger) {
1629                            Dialog d = new AppWaitingForDebuggerDialog(
1630                                    ActivityManagerService.this,
1631                                    mContext, app);
1632                            app.waitDialog = d;
1633                            app.waitedForDebugger = true;
1634                            d.show();
1635                        }
1636                    } else {
1637                        if (app.waitDialog != null) {
1638                            app.waitDialog.dismiss();
1639                            app.waitDialog = null;
1640                        }
1641                    }
1642                }
1643            } break;
1644            case SHOW_UID_ERROR_UI_MSG: {
1645                if (mShowDialogs) {
1646                    AlertDialog d = new BaseErrorDialog(mContext);
1647                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                    d.setCancelable(false);
1649                    d.setTitle(mContext.getText(R.string.android_system_label));
1650                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                    d.show();
1654                }
1655            } break;
1656            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                if (mShowDialogs) {
1658                    AlertDialog d = new BaseErrorDialog(mContext);
1659                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                    d.setCancelable(false);
1661                    d.setTitle(mContext.getText(R.string.android_system_label));
1662                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                    d.show();
1666                }
1667            } break;
1668            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                synchronized (ActivityManagerService.this) {
1670                    ActivityRecord ar = (ActivityRecord) msg.obj;
1671                    if (mCompatModeDialog != null) {
1672                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                ar.info.applicationInfo.packageName)) {
1674                            return;
1675                        }
1676                        mCompatModeDialog.dismiss();
1677                        mCompatModeDialog = null;
1678                    }
1679                    if (ar != null && false) {
1680                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                ar.packageName)) {
1682                            int mode = mCompatModePackages.computeCompatModeLocked(
1683                                    ar.info.applicationInfo);
1684                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                mCompatModeDialog = new CompatModeDialog(
1687                                        ActivityManagerService.this, mContext,
1688                                        ar.info.applicationInfo);
1689                                mCompatModeDialog.show();
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case START_USER_SWITCH_UI_MSG: {
1697                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                break;
1699            }
1700            case DISMISS_DIALOG_UI_MSG: {
1701                final Dialog d = (Dialog) msg.obj;
1702                d.dismiss();
1703                break;
1704            }
1705            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                dispatchProcessesChanged();
1707                break;
1708            }
1709            case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                final int pid = msg.arg1;
1711                final int uid = msg.arg2;
1712                dispatchProcessDied(pid, uid);
1713                break;
1714            }
1715            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                dispatchUidsChanged();
1717            } break;
1718            }
1719        }
1720    }
1721
1722    final class MainHandler extends Handler {
1723        public MainHandler(Looper looper) {
1724            super(looper, null, true);
1725        }
1726
1727        @Override
1728        public void handleMessage(Message msg) {
1729            switch (msg.what) {
1730            case UPDATE_CONFIGURATION_MSG: {
1731                final ContentResolver resolver = mContext.getContentResolver();
1732                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                        msg.arg1);
1734            } break;
1735            case GC_BACKGROUND_PROCESSES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    performAppGcsIfAppropriateLocked();
1738                }
1739            } break;
1740            case SERVICE_TIMEOUT_MSG: {
1741                if (mDidDexOpt) {
1742                    mDidDexOpt = false;
1743                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                    nmsg.obj = msg.obj;
1745                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                    return;
1747                }
1748                mServices.serviceTimeout((ProcessRecord)msg.obj);
1749            } break;
1750            case UPDATE_TIME_ZONE: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimeZone();
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763            } break;
1764            case CLEAR_DNS_CACHE_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.clearDnsCache();
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case UPDATE_HTTP_PROXY_MSG: {
1779                ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                String host = "";
1781                String port = "";
1782                String exclList = "";
1783                Uri pacFileUrl = Uri.EMPTY;
1784                if (proxy != null) {
1785                    host = proxy.getHost();
1786                    port = Integer.toString(proxy.getPort());
1787                    exclList = proxy.getExclusionListAsString();
1788                    pacFileUrl = proxy.getPacFileUrl();
1789                }
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update http proxy for: " +
1798                                        r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case PROC_START_TIMEOUT_MSG: {
1805                if (mDidDexOpt) {
1806                    mDidDexOpt = false;
1807                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                    nmsg.obj = msg.obj;
1809                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                    return;
1811                }
1812                ProcessRecord app = (ProcessRecord)msg.obj;
1813                synchronized (ActivityManagerService.this) {
1814                    processStartTimedOutLocked(app);
1815                }
1816            } break;
1817            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                ProcessRecord app = (ProcessRecord)msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    processContentProviderPublishTimedOutLocked(app);
1821                }
1822            } break;
1823            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                }
1827            } break;
1828            case KILL_APPLICATION_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    int appid = msg.arg1;
1831                    boolean restart = (msg.arg2 == 1);
1832                    Bundle bundle = (Bundle)msg.obj;
1833                    String pkg = bundle.getString("pkg");
1834                    String reason = bundle.getString("reason");
1835                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                            false, UserHandle.USER_ALL, reason);
1837                }
1838            } break;
1839            case FINALIZE_PENDING_INTENT_MSG: {
1840                ((PendingIntentRecord)msg.obj).completeFinalize();
1841            } break;
1842            case POST_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847
1848                ActivityRecord root = (ActivityRecord)msg.obj;
1849                ProcessRecord process = root.app;
1850                if (process == null) {
1851                    return;
1852                }
1853
1854                try {
1855                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                    String text = mContext.getString(R.string.heavy_weight_notification,
1857                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                    Notification notification = new Notification.Builder(context)
1859                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                            .setWhen(0)
1861                            .setOngoing(true)
1862                            .setTicker(text)
1863                            .setColor(mContext.getColor(
1864                                    com.android.internal.R.color.system_notification_accent_color))
1865                            .setContentTitle(text)
1866                            .setContentText(
1867                                    mContext.getText(R.string.heavy_weight_notification_detail))
1868                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                    new UserHandle(root.userId)))
1871                            .build();
1872                    try {
1873                        int[] outId = new int[1];
1874                        inm.enqueueNotificationWithTag("android", "android", null,
1875                                R.string.heavy_weight_notification,
1876                                notification, outId, root.userId);
1877                    } catch (RuntimeException e) {
1878                        Slog.w(ActivityManagerService.TAG,
1879                                "Error showing notification for heavy-weight app", e);
1880                    } catch (RemoteException e) {
1881                    }
1882                } catch (NameNotFoundException e) {
1883                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                }
1885            } break;
1886            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891                try {
1892                    inm.cancelNotificationWithTag("android", null,
1893                            R.string.heavy_weight_notification,  msg.arg1);
1894                } catch (RuntimeException e) {
1895                    Slog.w(ActivityManagerService.TAG,
1896                            "Error canceling notification for service", e);
1897                } catch (RemoteException e) {
1898                }
1899            } break;
1900            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    checkExcessivePowerUsageLocked(true);
1903                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                }
1907            } break;
1908            case REPORT_MEM_USAGE_MSG: {
1909                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                Thread thread = new Thread() {
1911                    @Override public void run() {
1912                        reportMemUsage(memInfos);
1913                    }
1914                };
1915                thread.start();
1916                break;
1917            }
1918            case REPORT_USER_SWITCH_MSG: {
1919                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case CONTINUE_USER_SWITCH_MSG: {
1923                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case USER_SWITCH_TIMEOUT_MSG: {
1927                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                break;
1929            }
1930            case IMMERSIVE_MODE_LOCK_MSG: {
1931                final boolean nextState = (msg.arg1 != 0);
1932                if (mUpdateLock.isHeld() != nextState) {
1933                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                            "Applying new update lock state '" + nextState
1935                            + "' for " + (ActivityRecord)msg.obj);
1936                    if (nextState) {
1937                        mUpdateLock.acquire();
1938                    } else {
1939                        mUpdateLock.release();
1940                    }
1941                }
1942                break;
1943            }
1944            case PERSIST_URI_GRANTS_MSG: {
1945                writeGrantedUriPermissions();
1946                break;
1947            }
1948            case REQUEST_ALL_PSS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                }
1952                break;
1953            }
1954            case START_PROFILES_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    mUserController.startProfilesLocked();
1957                }
1958                break;
1959            }
1960            case UPDATE_TIME: {
1961                synchronized (ActivityManagerService.this) {
1962                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                        ProcessRecord r = mLruProcesses.get(i);
1964                        if (r.thread != null) {
1965                            try {
1966                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                            } catch (RemoteException ex) {
1968                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                            }
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case SYSTEM_USER_START_MSG: {
1976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                        Integer.toString(msg.arg1), msg.arg1);
1978                mSystemServiceManager.startUser(msg.arg1);
1979                break;
1980            }
1981            case SYSTEM_USER_UNLOCK_MSG: {
1982                final int userId = msg.arg1;
1983                mSystemServiceManager.unlockUser(userId);
1984                synchronized (ActivityManagerService.this) {
1985                    mRecentTasks.loadUserRecentsLocked(userId);
1986                }
1987                if (userId == UserHandle.USER_SYSTEM) {
1988                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                }
1990                installEncryptionUnawareProviders(userId);
1991                mUserController.finishUserUnlocked((UserState) msg.obj);
1992                break;
1993            }
1994            case SYSTEM_USER_CURRENT_MSG: {
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                        Integer.toString(msg.arg2), msg.arg2);
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                        Integer.toString(msg.arg1), msg.arg1);
2001                mSystemServiceManager.switchUser(msg.arg1);
2002                break;
2003            }
2004            case ENTER_ANIMATION_COMPLETE_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                    if (r != null && r.app != null && r.app.thread != null) {
2008                        try {
2009                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                        } catch (RemoteException e) {
2011                        }
2012                    }
2013                }
2014                break;
2015            }
2016            case FINISH_BOOTING_MSG: {
2017                if (msg.arg1 != 0) {
2018                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                    finishBooting();
2020                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                }
2022                if (msg.arg2 != 0) {
2023                    enableScreenAfterBoot();
2024                }
2025                break;
2026            }
2027            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                try {
2029                    Locale l = (Locale) msg.obj;
2030                    IBinder service = ServiceManager.getService("mount");
2031                    IMountService mountService = IMountService.Stub.asInterface(service);
2032                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                } catch (RemoteException e) {
2035                    Log.e(TAG, "Error storing locale for decryption UI", e);
2036                }
2037                break;
2038            }
2039            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                        } catch (RemoteException e){
2060                            // Handled by the RemoteCallbackList
2061                        }
2062                    }
2063                    mTaskStackListeners.finishBroadcast();
2064                }
2065                break;
2066            }
2067            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                        try {
2071                            // Make a one-way callback to the listener
2072                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                        } catch (RemoteException e){
2074                            // Handled by the RemoteCallbackList
2075                        }
2076                    }
2077                    mTaskStackListeners.finishBroadcast();
2078                }
2079                break;
2080            }
2081            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                    (String) msg.obj, msg.arg1);
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                    synchronized (ActivityManagerService.this) {
2112                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                            try {
2114                                // Make a one-way callback to the listener
2115                                mTaskStackListeners.getBroadcastItem(i)
2116                                        .onActivityDismissingDockedStack();
2117                            } catch (RemoteException e){
2118                                // Handled by the RemoteCallbackList
2119                            }
2120                        }
2121                        mTaskStackListeners.finishBroadcast();
2122                    }
2123                    break;
2124                }
2125            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                final int uid = msg.arg1;
2127                final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                synchronized (mPidsSelfLocked) {
2130                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                        if (p.uid == uid) {
2133                            try {
2134                                p.thread.notifyCleartextNetwork(firstPacket);
2135                            } catch (RemoteException ignored) {
2136                            }
2137                        }
2138                    }
2139                }
2140                break;
2141            }
2142            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                final String procName;
2144                final int uid;
2145                final long memLimit;
2146                final String reportPackage;
2147                synchronized (ActivityManagerService.this) {
2148                    procName = mMemWatchDumpProcName;
2149                    uid = mMemWatchDumpUid;
2150                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                    if (val == null) {
2152                        val = mMemWatchProcesses.get(procName, 0);
2153                    }
2154                    if (val != null) {
2155                        memLimit = val.first;
2156                        reportPackage = val.second;
2157                    } else {
2158                        memLimit = 0;
2159                        reportPackage = null;
2160                    }
2161                }
2162                if (procName == null) {
2163                    return;
2164                }
2165
2166                if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                        "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                INotificationManager inm = NotificationManager.getService();
2170                if (inm == null) {
2171                    return;
2172                }
2173
2174                String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                Intent deleteIntent = new Intent();
2178                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                Intent intent = new Intent();
2180                intent.setClassName("android", DumpHeapActivity.class.getName());
2181                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                if (reportPackage != null) {
2184                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                }
2186                int userId = UserHandle.getUserId(uid);
2187                Notification notification = new Notification.Builder(mContext)
2188                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                        .setWhen(0)
2190                        .setOngoing(true)
2191                        .setAutoCancel(true)
2192                        .setTicker(text)
2193                        .setColor(mContext.getColor(
2194                                com.android.internal.R.color.system_notification_accent_color))
2195                        .setContentTitle(text)
2196                        .setContentText(
2197                                mContext.getText(R.string.dump_heap_notification_detail))
2198                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                new UserHandle(userId)))
2201                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                deleteIntent, 0, UserHandle.SYSTEM))
2203                        .build();
2204
2205                try {
2206                    int[] outId = new int[1];
2207                    inm.enqueueNotificationWithTag("android", "android", null,
2208                            R.string.dump_heap_notification,
2209                            notification, outId, userId);
2210                } catch (RuntimeException e) {
2211                    Slog.w(ActivityManagerService.TAG,
2212                            "Error showing notification for dump heap", e);
2213                } catch (RemoteException e) {
2214                }
2215            } break;
2216            case DELETE_DUMPHEAP_MSG: {
2217                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                        DumpHeapActivity.JAVA_URI,
2219                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                        UserHandle.myUserId());
2222                synchronized (ActivityManagerService.this) {
2223                    mMemWatchDumpFile = null;
2224                    mMemWatchDumpProcName = null;
2225                    mMemWatchDumpPid = -1;
2226                    mMemWatchDumpUid = -1;
2227                }
2228            } break;
2229            case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231            } break;
2232            case REPORT_TIME_TRACKER_MSG: {
2233                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                tracker.deliverResult(mContext);
2235            } break;
2236            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                mUserController.dispatchUserSwitchComplete(msg.arg1);
2238            } break;
2239            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                try {
2242                    connection.shutdown();
2243                } catch (RemoteException e) {
2244                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                }
2246                // Only a UiAutomation can set this flag and now that
2247                // it is finished we make sure it is reset to its default.
2248                mUserIsMonkey = false;
2249            } break;
2250            case APP_BOOST_DEACTIVATE_MSG: {
2251                synchronized(ActivityManagerService.this) {
2252                    if (mIsBoosted) {
2253                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                            nativeMigrateFromBoost();
2255                            mIsBoosted = false;
2256                            mBoostStartTime = 0;
2257                        } else {
2258                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                        }
2261                    }
2262                }
2263            } break;
2264            case IDLE_UIDS_MSG: {
2265                idleUids();
2266            } break;
2267            case LOG_STACK_STATE: {
2268                synchronized (ActivityManagerService.this) {
2269                    mStackSupervisor.logStackState();
2270                }
2271            } break;
2272            case VR_MODE_CHANGE_MSG: {
2273                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                    }
2288                }
2289                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290            } break;
2291            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                if (needsVrMode) {
2295                    VrManagerInternal vrService =
2296                            LocalServices.getService(VrManagerInternal.class);
2297                    boolean enable = msg.arg1 == 1;
2298                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2299                            r.info.getComponentName());
2300                }
2301            } break;
2302            }
2303        }
2304    };
2305
2306    static final int COLLECT_PSS_BG_MSG = 1;
2307
2308    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2309        @Override
2310        public void handleMessage(Message msg) {
2311            switch (msg.what) {
2312            case COLLECT_PSS_BG_MSG: {
2313                long start = SystemClock.uptimeMillis();
2314                MemInfoReader memInfo = null;
2315                synchronized (ActivityManagerService.this) {
2316                    if (mFullPssPending) {
2317                        mFullPssPending = false;
2318                        memInfo = new MemInfoReader();
2319                    }
2320                }
2321                if (memInfo != null) {
2322                    updateCpuStatsNow();
2323                    long nativeTotalPss = 0;
2324                    synchronized (mProcessCpuTracker) {
2325                        final int N = mProcessCpuTracker.countStats();
2326                        for (int j=0; j<N; j++) {
2327                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2328                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2329                                // This is definitely an application process; skip it.
2330                                continue;
2331                            }
2332                            synchronized (mPidsSelfLocked) {
2333                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2334                                    // This is one of our own processes; skip it.
2335                                    continue;
2336                                }
2337                            }
2338                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2339                        }
2340                    }
2341                    memInfo.readMemInfo();
2342                    synchronized (ActivityManagerService.this) {
2343                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2344                                + (SystemClock.uptimeMillis()-start) + "ms");
2345                        final long cachedKb = memInfo.getCachedSizeKb();
2346                        final long freeKb = memInfo.getFreeSizeKb();
2347                        final long zramKb = memInfo.getZramTotalSizeKb();
2348                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2349                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2350                                kernelKb*1024, nativeTotalPss*1024);
2351                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2352                                nativeTotalPss);
2353                    }
2354                }
2355
2356                int num = 0;
2357                long[] tmp = new long[2];
2358                do {
2359                    ProcessRecord proc;
2360                    int procState;
2361                    int pid;
2362                    long lastPssTime;
2363                    synchronized (ActivityManagerService.this) {
2364                        if (mPendingPssProcesses.size() <= 0) {
2365                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2366                                    "Collected PSS of " + num + " processes in "
2367                                    + (SystemClock.uptimeMillis() - start) + "ms");
2368                            mPendingPssProcesses.clear();
2369                            return;
2370                        }
2371                        proc = mPendingPssProcesses.remove(0);
2372                        procState = proc.pssProcState;
2373                        lastPssTime = proc.lastPssTime;
2374                        if (proc.thread != null && procState == proc.setProcState
2375                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2376                                        < SystemClock.uptimeMillis()) {
2377                            pid = proc.pid;
2378                        } else {
2379                            proc = null;
2380                            pid = 0;
2381                        }
2382                    }
2383                    if (proc != null) {
2384                        long pss = Debug.getPss(pid, tmp, null);
2385                        synchronized (ActivityManagerService.this) {
2386                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2387                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2388                                num++;
2389                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2390                                        SystemClock.uptimeMillis());
2391                            }
2392                        }
2393                    }
2394                } while (true);
2395            }
2396            }
2397        }
2398    };
2399
2400    public void setSystemProcess() {
2401        try {
2402            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2403            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2404            ServiceManager.addService("meminfo", new MemBinder(this));
2405            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2406            ServiceManager.addService("dbinfo", new DbBinder(this));
2407            if (MONITOR_CPU_USAGE) {
2408                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2409            }
2410            ServiceManager.addService("permission", new PermissionController(this));
2411            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2412
2413            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2414                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2415            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2416
2417            synchronized (this) {
2418                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2419                app.persistent = true;
2420                app.pid = MY_PID;
2421                app.maxAdj = ProcessList.SYSTEM_ADJ;
2422                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2423                synchronized (mPidsSelfLocked) {
2424                    mPidsSelfLocked.put(app.pid, app);
2425                }
2426                updateLruProcessLocked(app, false, null);
2427                updateOomAdjLocked();
2428            }
2429        } catch (PackageManager.NameNotFoundException e) {
2430            throw new RuntimeException(
2431                    "Unable to find android system package", e);
2432        }
2433    }
2434
2435    public void setWindowManager(WindowManagerService wm) {
2436        mWindowManager = wm;
2437        mStackSupervisor.setWindowManager(wm);
2438        mActivityStarter.setWindowManager(wm);
2439    }
2440
2441    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2442        mUsageStatsService = usageStatsManager;
2443    }
2444
2445    public void startObservingNativeCrashes() {
2446        final NativeCrashListener ncl = new NativeCrashListener(this);
2447        ncl.start();
2448    }
2449
2450    public IAppOpsService getAppOpsService() {
2451        return mAppOpsService;
2452    }
2453
2454    static class MemBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        MemBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump meminfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2471        }
2472    }
2473
2474    static class GraphicsBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        GraphicsBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2491        }
2492    }
2493
2494    static class DbBinder extends Binder {
2495        ActivityManagerService mActivityManagerService;
2496        DbBinder(ActivityManagerService activityManagerService) {
2497            mActivityManagerService = activityManagerService;
2498        }
2499
2500        @Override
2501        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                    != PackageManager.PERMISSION_GRANTED) {
2504                pw.println("Permission Denial: can't dump dbinfo from from pid="
2505                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                        + " without permission " + android.Manifest.permission.DUMP);
2507                return;
2508            }
2509
2510            mActivityManagerService.dumpDbInfo(fd, pw, args);
2511        }
2512    }
2513
2514    static class CpuBinder extends Binder {
2515        ActivityManagerService mActivityManagerService;
2516        CpuBinder(ActivityManagerService activityManagerService) {
2517            mActivityManagerService = activityManagerService;
2518        }
2519
2520        @Override
2521        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                    != PackageManager.PERMISSION_GRANTED) {
2524                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2525                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                        + " without permission " + android.Manifest.permission.DUMP);
2527                return;
2528            }
2529
2530            synchronized (mActivityManagerService.mProcessCpuTracker) {
2531                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2532                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2533                        SystemClock.uptimeMillis()));
2534            }
2535        }
2536    }
2537
2538    public static final class Lifecycle extends SystemService {
2539        private final ActivityManagerService mService;
2540
2541        public Lifecycle(Context context) {
2542            super(context);
2543            mService = new ActivityManagerService(context);
2544        }
2545
2546        @Override
2547        public void onStart() {
2548            mService.start();
2549        }
2550
2551        public ActivityManagerService getService() {
2552            return mService;
2553        }
2554    }
2555
2556    // Note: This method is invoked on the main thread but may need to attach various
2557    // handlers to other threads.  So take care to be explicit about the looper.
2558    public ActivityManagerService(Context systemContext) {
2559        mContext = systemContext;
2560        mFactoryTest = FactoryTest.getMode();
2561        mSystemThread = ActivityThread.currentActivityThread();
2562
2563        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2564
2565        mHandlerThread = new ServiceThread(TAG,
2566                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2567        mHandlerThread.start();
2568        mHandler = new MainHandler(mHandlerThread.getLooper());
2569        mUiHandler = new UiHandler();
2570
2571        /* static; one-time init here */
2572        if (sKillHandler == null) {
2573            sKillThread = new ServiceThread(TAG + ":kill",
2574                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2575            sKillThread.start();
2576            sKillHandler = new KillHandler(sKillThread.getLooper());
2577        }
2578
2579        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580                "foreground", BROADCAST_FG_TIMEOUT, false);
2581        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2582                "background", BROADCAST_BG_TIMEOUT, true);
2583        mBroadcastQueues[0] = mFgBroadcastQueue;
2584        mBroadcastQueues[1] = mBgBroadcastQueue;
2585
2586        mServices = new ActiveServices(this);
2587        mProviderMap = new ProviderMap(this);
2588        mAppErrors = new AppErrors(mContext, this);
2589
2590        // TODO: Move creation of battery stats service outside of activity manager service.
2591        File dataDir = Environment.getDataDirectory();
2592        File systemDir = new File(dataDir, "system");
2593        systemDir.mkdirs();
2594        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2595        mBatteryStatsService.getActiveStatistics().readLocked();
2596        mBatteryStatsService.scheduleWriteToDisk();
2597        mOnBattery = DEBUG_POWER ? true
2598                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2599        mBatteryStatsService.getActiveStatistics().setCallback(this);
2600
2601        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2602
2603        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2604        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2605                new IAppOpsCallback.Stub() {
2606                    @Override public void opChanged(int op, int uid, String packageName) {
2607                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2608                            if (mAppOpsService.checkOperation(op, uid, packageName)
2609                                    != AppOpsManager.MODE_ALLOWED) {
2610                                runInBackgroundDisabled(uid);
2611                            }
2612                        }
2613                    }
2614                });
2615
2616        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2617
2618        mUserController = new UserController(this);
2619
2620        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2621            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2622
2623        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2624
2625        mConfiguration.setToDefaults();
2626        mConfiguration.setLocales(LocaleList.getDefault());
2627
2628        mConfigurationSeq = mConfiguration.seq = 1;
2629        mProcessCpuTracker.init();
2630
2631        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2632        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2633        mStackSupervisor = new ActivityStackSupervisor(this);
2634        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637        mProcessCpuThread = new Thread("CpuTracker") {
2638            @Override
2639            public void run() {
2640                while (true) {
2641                    try {
2642                        try {
2643                            synchronized(this) {
2644                                final long now = SystemClock.uptimeMillis();
2645                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                //        + ", write delay=" + nextWriteDelay);
2649                                if (nextWriteDelay < nextCpuDelay) {
2650                                    nextCpuDelay = nextWriteDelay;
2651                                }
2652                                if (nextCpuDelay > 0) {
2653                                    mProcessCpuMutexFree.set(true);
2654                                    this.wait(nextCpuDelay);
2655                                }
2656                            }
2657                        } catch (InterruptedException e) {
2658                        }
2659                        updateCpuStatsNow();
2660                    } catch (Exception e) {
2661                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                    }
2663                }
2664            }
2665        };
2666
2667        Watchdog.getInstance().addMonitor(this);
2668        Watchdog.getInstance().addThread(mHandler);
2669    }
2670
2671    public void setSystemServiceManager(SystemServiceManager mgr) {
2672        mSystemServiceManager = mgr;
2673    }
2674
2675    public void setInstaller(Installer installer) {
2676        mInstaller = installer;
2677    }
2678
2679    private void start() {
2680        Process.removeAllProcessGroups();
2681        mProcessCpuThread.start();
2682
2683        mBatteryStatsService.publish(mContext);
2684        mAppOpsService.publish(mContext);
2685        Slog.d("AppOps", "AppOpsService published");
2686        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687    }
2688
2689    void onUserStoppedLocked(int userId) {
2690        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691    }
2692
2693    public void initPowerManagement() {
2694        mStackSupervisor.initPowerManagement();
2695        mBatteryStatsService.initPowerManagement();
2696        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699        mVoiceWakeLock.setReferenceCounted(false);
2700    }
2701
2702    @Override
2703    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704            throws RemoteException {
2705        if (code == SYSPROPS_TRANSACTION) {
2706            // We need to tell all apps about the system property change.
2707            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708            synchronized(this) {
2709                final int NP = mProcessNames.getMap().size();
2710                for (int ip=0; ip<NP; ip++) {
2711                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                    final int NA = apps.size();
2713                    for (int ia=0; ia<NA; ia++) {
2714                        ProcessRecord app = apps.valueAt(ia);
2715                        if (app.thread != null) {
2716                            procs.add(app.thread.asBinder());
2717                        }
2718                    }
2719                }
2720            }
2721
2722            int N = procs.size();
2723            for (int i=0; i<N; i++) {
2724                Parcel data2 = Parcel.obtain();
2725                try {
2726                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                } catch (RemoteException e) {
2728                }
2729                data2.recycle();
2730            }
2731        }
2732        try {
2733            return super.onTransact(code, data, reply, flags);
2734        } catch (RuntimeException e) {
2735            // The activity manager only throws security exceptions, so let's
2736            // log all others.
2737            if (!(e instanceof SecurityException)) {
2738                Slog.wtf(TAG, "Activity Manager Crash", e);
2739            }
2740            throw e;
2741        }
2742    }
2743
2744    void updateCpuStats() {
2745        final long now = SystemClock.uptimeMillis();
2746        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747            return;
2748        }
2749        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750            synchronized (mProcessCpuThread) {
2751                mProcessCpuThread.notify();
2752            }
2753        }
2754    }
2755
2756    void updateCpuStatsNow() {
2757        synchronized (mProcessCpuTracker) {
2758            mProcessCpuMutexFree.set(false);
2759            final long now = SystemClock.uptimeMillis();
2760            boolean haveNewCpuStats = false;
2761
2762            if (MONITOR_CPU_USAGE &&
2763                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                mLastCpuTime.set(now);
2765                mProcessCpuTracker.update();
2766                if (mProcessCpuTracker.hasGoodLastStats()) {
2767                    haveNewCpuStats = true;
2768                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                    //Slog.i(TAG, "Total CPU usage: "
2770                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                    // Slog the cpu usage if the property is set.
2773                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                        int user = mProcessCpuTracker.getLastUserTime();
2775                        int system = mProcessCpuTracker.getLastSystemTime();
2776                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                        int irq = mProcessCpuTracker.getLastIrqTime();
2778                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                        int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                        int total = user + system + iowait + irq + softIrq + idle;
2782                        if (total == 0) total = 1;
2783
2784                        EventLog.writeEvent(EventLogTags.CPU,
2785                                ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                (user * 100) / total,
2787                                (system * 100) / total,
2788                                (iowait * 100) / total,
2789                                (irq * 100) / total,
2790                                (softIrq * 100) / total);
2791                    }
2792                }
2793            }
2794
2795            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796            synchronized(bstats) {
2797                synchronized(mPidsSelfLocked) {
2798                    if (haveNewCpuStats) {
2799                        if (bstats.startAddingCpuLocked()) {
2800                            int totalUTime = 0;
2801                            int totalSTime = 0;
2802                            final int N = mProcessCpuTracker.countStats();
2803                            for (int i=0; i<N; i++) {
2804                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                if (!st.working) {
2806                                    continue;
2807                                }
2808                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                totalUTime += st.rel_utime;
2810                                totalSTime += st.rel_stime;
2811                                if (pr != null) {
2812                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                    if (ps == null || !ps.isActive()) {
2814                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                pr.info.uid, pr.processName);
2816                                    }
2817                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                } else {
2820                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                    if (ps == null || !ps.isActive()) {
2822                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                bstats.mapUid(st.uid), st.name);
2824                                    }
2825                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                }
2827                            }
2828                            final int userTime = mProcessCpuTracker.getLastUserTime();
2829                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                        }
2837                    }
2838                }
2839
2840                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                    mLastWriteTime = now;
2842                    mBatteryStatsService.scheduleWriteToDisk();
2843                }
2844            }
2845        }
2846    }
2847
2848    @Override
2849    public void batteryNeedsCpuUpdate() {
2850        updateCpuStatsNow();
2851    }
2852
2853    @Override
2854    public void batteryPowerChanged(boolean onBattery) {
2855        // When plugging in, update the CPU stats first before changing
2856        // the plug state.
2857        updateCpuStatsNow();
2858        synchronized (this) {
2859            synchronized(mPidsSelfLocked) {
2860                mOnBattery = DEBUG_POWER ? true : onBattery;
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batterySendBroadcast(Intent intent) {
2867        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                AppOpsManager.OP_NONE, null, false, false,
2869                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870    }
2871
2872    /**
2873     * Initialize the application bind args. These are passed to each
2874     * process when the bindApplication() IPC is sent to the process. They're
2875     * lazily setup to make sure the services are running when they're asked for.
2876     */
2877    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878        if (mAppBindArgs == null) {
2879            mAppBindArgs = new HashMap<>();
2880
2881            // Isolated processes won't get this optimization, so that we don't
2882            // violate the rules about which services they have access to.
2883            if (!isolated) {
2884                // Setup the application init args
2885                mAppBindArgs.put("package", ServiceManager.getService("package"));
2886                mAppBindArgs.put("window", ServiceManager.getService("window"));
2887                mAppBindArgs.put(Context.ALARM_SERVICE,
2888                        ServiceManager.getService(Context.ALARM_SERVICE));
2889            }
2890        }
2891        return mAppBindArgs;
2892    }
2893
2894    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2895        if (r == null || mFocusedActivity == r) {
2896            return false;
2897        }
2898
2899        if (!r.isFocusable()) {
2900            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2901            return false;
2902        }
2903
2904        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2905
2906        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2907        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2908                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2909        mDoingSetFocusedActivity = true;
2910
2911        final ActivityRecord last = mFocusedActivity;
2912        mFocusedActivity = r;
2913        if (r.task.isApplicationTask()) {
2914            if (mCurAppTimeTracker != r.appTimeTracker) {
2915                // We are switching app tracking.  Complete the current one.
2916                if (mCurAppTimeTracker != null) {
2917                    mCurAppTimeTracker.stop();
2918                    mHandler.obtainMessage(
2919                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2920                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2921                    mCurAppTimeTracker = null;
2922                }
2923                if (r.appTimeTracker != null) {
2924                    mCurAppTimeTracker = r.appTimeTracker;
2925                    startTimeTrackingFocusedActivityLocked();
2926                }
2927            } else {
2928                startTimeTrackingFocusedActivityLocked();
2929            }
2930        } else {
2931            r.appTimeTracker = null;
2932        }
2933        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2934        // TODO: Probably not, because we don't want to resume voice on switching
2935        // back to this activity
2936        if (r.task.voiceInteractor != null) {
2937            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2938        } else {
2939            finishRunningVoiceLocked();
2940            IVoiceInteractionSession session;
2941            if (last != null && ((session = last.task.voiceSession) != null
2942                    || (session = last.voiceSession) != null)) {
2943                // We had been in a voice interaction session, but now focused has
2944                // move to something different.  Just finish the session, we can't
2945                // return to it and retain the proper state and synchronization with
2946                // the voice interaction service.
2947                finishVoiceTask(session);
2948            }
2949        }
2950        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2951            mWindowManager.setFocusedApp(r.appToken, true);
2952        }
2953        applyUpdateLockStateLocked(r);
2954        applyUpdateVrModeLocked(r);
2955        if (mFocusedActivity.userId != mLastFocusedUserId) {
2956            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2957            mHandler.obtainMessage(
2958                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2959            mLastFocusedUserId = mFocusedActivity.userId;
2960        }
2961
2962        // Log a warning if the focused app is changed during the process. This could
2963        // indicate a problem of the focus setting logic!
2964        if (mFocusedActivity != r) Slog.w(TAG,
2965                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2966        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2967
2968        EventLogTags.writeAmFocusedActivity(
2969                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2970                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2971                reason);
2972        return true;
2973    }
2974
2975    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2976        if (mFocusedActivity != goingAway) {
2977            return;
2978        }
2979
2980        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2981        if (focusedStack != null) {
2982            final ActivityRecord top = focusedStack.topActivity();
2983            if (top != null && top.userId != mLastFocusedUserId) {
2984                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2985                mHandler.sendMessage(
2986                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2987                mLastFocusedUserId = top.userId;
2988            }
2989        }
2990
2991        // Try to move focus to another activity if possible.
2992        if (setFocusedActivityLocked(
2993                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2994            return;
2995        }
2996
2997        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2998                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2999        mFocusedActivity = null;
3000        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3001    }
3002
3003    @Override
3004    public void setFocusedStack(int stackId) {
3005        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3006        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3007        final long callingId = Binder.clearCallingIdentity();
3008        try {
3009            synchronized (this) {
3010                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3011                if (stack == null) {
3012                    return;
3013                }
3014                final ActivityRecord r = stack.topRunningActivityLocked();
3015                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3016                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3017                }
3018            }
3019        } finally {
3020            Binder.restoreCallingIdentity(callingId);
3021        }
3022    }
3023
3024    @Override
3025    public void setFocusedTask(int taskId) {
3026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3027        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3028        final long callingId = Binder.clearCallingIdentity();
3029        try {
3030            synchronized (this) {
3031                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3032                if (task == null) {
3033                    return;
3034                }
3035                final ActivityRecord r = task.topRunningActivityLocked();
3036                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3037                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3038                }
3039            }
3040        } finally {
3041            Binder.restoreCallingIdentity(callingId);
3042        }
3043    }
3044
3045    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3046    @Override
3047    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3049        synchronized (this) {
3050            if (listener != null) {
3051                mTaskStackListeners.register(listener);
3052            }
3053        }
3054    }
3055
3056    @Override
3057    public void notifyActivityDrawn(IBinder token) {
3058        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3059        synchronized (this) {
3060            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3061            if (r != null) {
3062                r.task.stack.notifyActivityDrawnLocked(r);
3063            }
3064        }
3065    }
3066
3067    final void applyUpdateLockStateLocked(ActivityRecord r) {
3068        // Modifications to the UpdateLock state are done on our handler, outside
3069        // the activity manager's locks.  The new state is determined based on the
3070        // state *now* of the relevant activity record.  The object is passed to
3071        // the handler solely for logging detail, not to be consulted/modified.
3072        final boolean nextState = r != null && r.immersive;
3073        mHandler.sendMessage(
3074                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3075    }
3076
3077    final void applyUpdateVrModeLocked(ActivityRecord r) {
3078        mHandler.sendMessage(
3079                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3080    }
3081
3082    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3083        mHandler.sendMessage(
3084                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3085    }
3086
3087    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3088        Message msg = Message.obtain();
3089        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3090        msg.obj = r.task.askedCompatMode ? null : r;
3091        mUiHandler.sendMessage(msg);
3092    }
3093
3094    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3095            String what, Object obj, ProcessRecord srcApp) {
3096        app.lastActivityTime = now;
3097
3098        if (app.activities.size() > 0) {
3099            // Don't want to touch dependent processes that are hosting activities.
3100            return index;
3101        }
3102
3103        int lrui = mLruProcesses.lastIndexOf(app);
3104        if (lrui < 0) {
3105            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3106                    + what + " " + obj + " from " + srcApp);
3107            return index;
3108        }
3109
3110        if (lrui >= index) {
3111            // Don't want to cause this to move dependent processes *back* in the
3112            // list as if they were less frequently used.
3113            return index;
3114        }
3115
3116        if (lrui >= mLruProcessActivityStart) {
3117            // Don't want to touch dependent processes that are hosting activities.
3118            return index;
3119        }
3120
3121        mLruProcesses.remove(lrui);
3122        if (index > 0) {
3123            index--;
3124        }
3125        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3126                + " in LRU list: " + app);
3127        mLruProcesses.add(index, app);
3128        return index;
3129    }
3130
3131    static void killProcessGroup(int uid, int pid) {
3132        if (sKillHandler != null) {
3133            sKillHandler.sendMessage(
3134                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3135        } else {
3136            Slog.w(TAG, "Asked to kill process group before system bringup!");
3137            Process.killProcessGroup(uid, pid);
3138        }
3139    }
3140
3141    final void removeLruProcessLocked(ProcessRecord app) {
3142        int lrui = mLruProcesses.lastIndexOf(app);
3143        if (lrui >= 0) {
3144            if (!app.killed) {
3145                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3146                Process.killProcessQuiet(app.pid);
3147                killProcessGroup(app.uid, app.pid);
3148            }
3149            if (lrui <= mLruProcessActivityStart) {
3150                mLruProcessActivityStart--;
3151            }
3152            if (lrui <= mLruProcessServiceStart) {
3153                mLruProcessServiceStart--;
3154            }
3155            mLruProcesses.remove(lrui);
3156        }
3157    }
3158
3159    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3160            ProcessRecord client) {
3161        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3162                || app.treatLikeActivity;
3163        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3164        if (!activityChange && hasActivity) {
3165            // The process has activities, so we are only allowing activity-based adjustments
3166            // to move it.  It should be kept in the front of the list with other
3167            // processes that have activities, and we don't want those to change their
3168            // order except due to activity operations.
3169            return;
3170        }
3171
3172        mLruSeq++;
3173        final long now = SystemClock.uptimeMillis();
3174        app.lastActivityTime = now;
3175
3176        // First a quick reject: if the app is already at the position we will
3177        // put it, then there is nothing to do.
3178        if (hasActivity) {
3179            final int N = mLruProcesses.size();
3180            if (N > 0 && mLruProcesses.get(N-1) == app) {
3181                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3182                return;
3183            }
3184        } else {
3185            if (mLruProcessServiceStart > 0
3186                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3187                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3188                return;
3189            }
3190        }
3191
3192        int lrui = mLruProcesses.lastIndexOf(app);
3193
3194        if (app.persistent && lrui >= 0) {
3195            // We don't care about the position of persistent processes, as long as
3196            // they are in the list.
3197            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3198            return;
3199        }
3200
3201        /* In progress: compute new position first, so we can avoid doing work
3202           if the process is not actually going to move.  Not yet working.
3203        int addIndex;
3204        int nextIndex;
3205        boolean inActivity = false, inService = false;
3206        if (hasActivity) {
3207            // Process has activities, put it at the very tipsy-top.
3208            addIndex = mLruProcesses.size();
3209            nextIndex = mLruProcessServiceStart;
3210            inActivity = true;
3211        } else if (hasService) {
3212            // Process has services, put it at the top of the service list.
3213            addIndex = mLruProcessActivityStart;
3214            nextIndex = mLruProcessServiceStart;
3215            inActivity = true;
3216            inService = true;
3217        } else  {
3218            // Process not otherwise of interest, it goes to the top of the non-service area.
3219            addIndex = mLruProcessServiceStart;
3220            if (client != null) {
3221                int clientIndex = mLruProcesses.lastIndexOf(client);
3222                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3223                        + app);
3224                if (clientIndex >= 0 && addIndex > clientIndex) {
3225                    addIndex = clientIndex;
3226                }
3227            }
3228            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3229        }
3230
3231        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3232                + mLruProcessActivityStart + "): " + app);
3233        */
3234
3235        if (lrui >= 0) {
3236            if (lrui < mLruProcessActivityStart) {
3237                mLruProcessActivityStart--;
3238            }
3239            if (lrui < mLruProcessServiceStart) {
3240                mLruProcessServiceStart--;
3241            }
3242            /*
3243            if (addIndex > lrui) {
3244                addIndex--;
3245            }
3246            if (nextIndex > lrui) {
3247                nextIndex--;
3248            }
3249            */
3250            mLruProcesses.remove(lrui);
3251        }
3252
3253        /*
3254        mLruProcesses.add(addIndex, app);
3255        if (inActivity) {
3256            mLruProcessActivityStart++;
3257        }
3258        if (inService) {
3259            mLruProcessActivityStart++;
3260        }
3261        */
3262
3263        int nextIndex;
3264        if (hasActivity) {
3265            final int N = mLruProcesses.size();
3266            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3267                // Process doesn't have activities, but has clients with
3268                // activities...  move it up, but one below the top (the top
3269                // should always have a real activity).
3270                if (DEBUG_LRU) Slog.d(TAG_LRU,
3271                        "Adding to second-top of LRU activity list: " + app);
3272                mLruProcesses.add(N - 1, app);
3273                // To keep it from spamming the LRU list (by making a bunch of clients),
3274                // we will push down any other entries owned by the app.
3275                final int uid = app.info.uid;
3276                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3277                    ProcessRecord subProc = mLruProcesses.get(i);
3278                    if (subProc.info.uid == uid) {
3279                        // We want to push this one down the list.  If the process after
3280                        // it is for the same uid, however, don't do so, because we don't
3281                        // want them internally to be re-ordered.
3282                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3283                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3284                                    "Pushing uid " + uid + " swapping at " + i + ": "
3285                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3286                            ProcessRecord tmp = mLruProcesses.get(i);
3287                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3288                            mLruProcesses.set(i - 1, tmp);
3289                            i--;
3290                        }
3291                    } else {
3292                        // A gap, we can stop here.
3293                        break;
3294                    }
3295                }
3296            } else {
3297                // Process has activities, put it at the very tipsy-top.
3298                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3299                mLruProcesses.add(app);
3300            }
3301            nextIndex = mLruProcessServiceStart;
3302        } else if (hasService) {
3303            // Process has services, put it at the top of the service list.
3304            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3305            mLruProcesses.add(mLruProcessActivityStart, app);
3306            nextIndex = mLruProcessServiceStart;
3307            mLruProcessActivityStart++;
3308        } else  {
3309            // Process not otherwise of interest, it goes to the top of the non-service area.
3310            int index = mLruProcessServiceStart;
3311            if (client != null) {
3312                // If there is a client, don't allow the process to be moved up higher
3313                // in the list than that client.
3314                int clientIndex = mLruProcesses.lastIndexOf(client);
3315                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3316                        + " when updating " + app);
3317                if (clientIndex <= lrui) {
3318                    // Don't allow the client index restriction to push it down farther in the
3319                    // list than it already is.
3320                    clientIndex = lrui;
3321                }
3322                if (clientIndex >= 0 && index > clientIndex) {
3323                    index = clientIndex;
3324                }
3325            }
3326            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3327            mLruProcesses.add(index, app);
3328            nextIndex = index-1;
3329            mLruProcessActivityStart++;
3330            mLruProcessServiceStart++;
3331        }
3332
3333        // If the app is currently using a content provider or service,
3334        // bump those processes as well.
3335        for (int j=app.connections.size()-1; j>=0; j--) {
3336            ConnectionRecord cr = app.connections.valueAt(j);
3337            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3338                    && cr.binding.service.app != null
3339                    && cr.binding.service.app.lruSeq != mLruSeq
3340                    && !cr.binding.service.app.persistent) {
3341                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3342                        "service connection", cr, app);
3343            }
3344        }
3345        for (int j=app.conProviders.size()-1; j>=0; j--) {
3346            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3347            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3348                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3349                        "provider reference", cpr, app);
3350            }
3351        }
3352    }
3353
3354    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3355        if (uid == Process.SYSTEM_UID) {
3356            // The system gets to run in any process.  If there are multiple
3357            // processes with the same uid, just pick the first (this
3358            // should never happen).
3359            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3360            if (procs == null) return null;
3361            final int procCount = procs.size();
3362            for (int i = 0; i < procCount; i++) {
3363                final int procUid = procs.keyAt(i);
3364                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3365                    // Don't use an app process or different user process for system component.
3366                    continue;
3367                }
3368                return procs.valueAt(i);
3369            }
3370        }
3371        ProcessRecord proc = mProcessNames.get(processName, uid);
3372        if (false && proc != null && !keepIfLarge
3373                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3374                && proc.lastCachedPss >= 4000) {
3375            // Turn this condition on to cause killing to happen regularly, for testing.
3376            if (proc.baseProcessTracker != null) {
3377                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3378            }
3379            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3380        } else if (proc != null && !keepIfLarge
3381                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3382                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3383            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3384            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3385                if (proc.baseProcessTracker != null) {
3386                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3387                }
3388                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3389            }
3390        }
3391        return proc;
3392    }
3393
3394    void notifyPackageUse(String packageName, int reason) {
3395        IPackageManager pm = AppGlobals.getPackageManager();
3396        try {
3397            pm.notifyPackageUse(packageName, reason);
3398        } catch (RemoteException e) {
3399        }
3400    }
3401
3402    boolean isNextTransitionForward() {
3403        int transit = mWindowManager.getPendingAppTransition();
3404        return transit == TRANSIT_ACTIVITY_OPEN
3405                || transit == TRANSIT_TASK_OPEN
3406                || transit == TRANSIT_TASK_TO_FRONT;
3407    }
3408
3409    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3410            String processName, String abiOverride, int uid, Runnable crashHandler) {
3411        synchronized(this) {
3412            ApplicationInfo info = new ApplicationInfo();
3413            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3414            // For isolated processes, the former contains the parent's uid and the latter the
3415            // actual uid of the isolated process.
3416            // In the special case introduced by this method (which is, starting an isolated
3417            // process directly from the SystemServer without an actual parent app process) the
3418            // closest thing to a parent's uid is SYSTEM_UID.
3419            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3420            // the |isolated| logic in the ProcessRecord constructor.
3421            info.uid = Process.SYSTEM_UID;
3422            info.processName = processName;
3423            info.className = entryPoint;
3424            info.packageName = "android";
3425            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3426                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3427                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3428                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3429                    crashHandler);
3430            return proc != null ? proc.pid : 0;
3431        }
3432    }
3433
3434    final ProcessRecord startProcessLocked(String processName,
3435            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3436            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3437            boolean isolated, boolean keepIfLarge) {
3438        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3439                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3440                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3441                null /* crashHandler */);
3442    }
3443
3444    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3445            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3446            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3447            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3448        long startTime = SystemClock.elapsedRealtime();
3449        ProcessRecord app;
3450        if (!isolated) {
3451            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3452            checkTime(startTime, "startProcess: after getProcessRecord");
3453
3454            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3455                // If we are in the background, then check to see if this process
3456                // is bad.  If so, we will just silently fail.
3457                if (mAppErrors.isBadProcessLocked(info)) {
3458                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3459                            + "/" + info.processName);
3460                    return null;
3461                }
3462            } else {
3463                // When the user is explicitly starting a process, then clear its
3464                // crash count so that we won't make it bad until they see at
3465                // least one crash dialog again, and make the process good again
3466                // if it had been bad.
3467                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3468                        + "/" + info.processName);
3469                mAppErrors.resetProcessCrashTimeLocked(info);
3470                if (mAppErrors.isBadProcessLocked(info)) {
3471                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3472                            UserHandle.getUserId(info.uid), info.uid,
3473                            info.processName);
3474                    mAppErrors.clearBadProcessLocked(info);
3475                    if (app != null) {
3476                        app.bad = false;
3477                    }
3478                }
3479            }
3480        } else {
3481            // If this is an isolated process, it can't re-use an existing process.
3482            app = null;
3483        }
3484
3485        // app launch boost for big.little configurations
3486        // use cpusets to migrate freshly launched tasks to big cores
3487        synchronized(ActivityManagerService.this) {
3488            nativeMigrateToBoost();
3489            mIsBoosted = true;
3490            mBoostStartTime = SystemClock.uptimeMillis();
3491            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3492            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3493        }
3494
3495        // We don't have to do anything more if:
3496        // (1) There is an existing application record; and
3497        // (2) The caller doesn't think it is dead, OR there is no thread
3498        //     object attached to it so we know it couldn't have crashed; and
3499        // (3) There is a pid assigned to it, so it is either starting or
3500        //     already running.
3501        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3502                + " app=" + app + " knownToBeDead=" + knownToBeDead
3503                + " thread=" + (app != null ? app.thread : null)
3504                + " pid=" + (app != null ? app.pid : -1));
3505        if (app != null && app.pid > 0) {
3506            if (!knownToBeDead || app.thread == null) {
3507                // We already have the app running, or are waiting for it to
3508                // come up (we have a pid but not yet its thread), so keep it.
3509                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3510                // If this is a new package in the process, add the package to the list
3511                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3512                checkTime(startTime, "startProcess: done, added package to proc");
3513                return app;
3514            }
3515
3516            // An application record is attached to a previous process,
3517            // clean it up now.
3518            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3519            checkTime(startTime, "startProcess: bad proc running, killing");
3520            killProcessGroup(app.uid, app.pid);
3521            handleAppDiedLocked(app, true, true);
3522            checkTime(startTime, "startProcess: done killing old proc");
3523        }
3524
3525        String hostingNameStr = hostingName != null
3526                ? hostingName.flattenToShortString() : null;
3527
3528        if (app == null) {
3529            checkTime(startTime, "startProcess: creating new process record");
3530            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3531            if (app == null) {
3532                Slog.w(TAG, "Failed making new process record for "
3533                        + processName + "/" + info.uid + " isolated=" + isolated);
3534                return null;
3535            }
3536            app.crashHandler = crashHandler;
3537            checkTime(startTime, "startProcess: done creating new process record");
3538        } else {
3539            // If this is a new package in the process, add the package to the list
3540            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3541            checkTime(startTime, "startProcess: added package to existing proc");
3542        }
3543
3544        // If the system is not ready yet, then hold off on starting this
3545        // process until it is.
3546        if (!mProcessesReady
3547                && !isAllowedWhileBooting(info)
3548                && !allowWhileBooting) {
3549            if (!mProcessesOnHold.contains(app)) {
3550                mProcessesOnHold.add(app);
3551            }
3552            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3553                    "System not ready, putting on hold: " + app);
3554            checkTime(startTime, "startProcess: returning with proc on hold");
3555            return app;
3556        }
3557
3558        checkTime(startTime, "startProcess: stepping in to startProcess");
3559        startProcessLocked(
3560                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3561        checkTime(startTime, "startProcess: done starting proc!");
3562        return (app.pid != 0) ? app : null;
3563    }
3564
3565    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3566        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3567    }
3568
3569    private final void startProcessLocked(ProcessRecord app,
3570            String hostingType, String hostingNameStr) {
3571        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3572                null /* entryPoint */, null /* entryPointArgs */);
3573    }
3574
3575    private final void startProcessLocked(ProcessRecord app, String hostingType,
3576            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3577        long startTime = SystemClock.elapsedRealtime();
3578        if (app.pid > 0 && app.pid != MY_PID) {
3579            checkTime(startTime, "startProcess: removing from pids map");
3580            synchronized (mPidsSelfLocked) {
3581                mPidsSelfLocked.remove(app.pid);
3582                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3583            }
3584            checkTime(startTime, "startProcess: done removing from pids map");
3585            app.setPid(0);
3586        }
3587
3588        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3589                "startProcessLocked removing on hold: " + app);
3590        mProcessesOnHold.remove(app);
3591
3592        checkTime(startTime, "startProcess: starting to update cpu stats");
3593        updateCpuStats();
3594        checkTime(startTime, "startProcess: done updating cpu stats");
3595
3596        try {
3597            try {
3598                final int userId = UserHandle.getUserId(app.uid);
3599                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3600            } catch (RemoteException e) {
3601                throw e.rethrowAsRuntimeException();
3602            }
3603
3604            int uid = app.uid;
3605            int[] gids = null;
3606            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3607            if (!app.isolated) {
3608                int[] permGids = null;
3609                try {
3610                    checkTime(startTime, "startProcess: getting gids from package manager");
3611                    final IPackageManager pm = AppGlobals.getPackageManager();
3612                    permGids = pm.getPackageGids(app.info.packageName,
3613                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3614                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3615                            MountServiceInternal.class);
3616                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3617                            app.info.packageName);
3618                } catch (RemoteException e) {
3619                    throw e.rethrowAsRuntimeException();
3620                }
3621
3622                /*
3623                 * Add shared application and profile GIDs so applications can share some
3624                 * resources like shared libraries and access user-wide resources
3625                 */
3626                if (ArrayUtils.isEmpty(permGids)) {
3627                    gids = new int[2];
3628                } else {
3629                    gids = new int[permGids.length + 2];
3630                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3631                }
3632                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3633                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3634            }
3635            checkTime(startTime, "startProcess: building args");
3636            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3637                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3638                        && mTopComponent != null
3639                        && app.processName.equals(mTopComponent.getPackageName())) {
3640                    uid = 0;
3641                }
3642                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3643                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3644                    uid = 0;
3645                }
3646            }
3647            int debugFlags = 0;
3648            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3649                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3650                // Also turn on CheckJNI for debuggable apps. It's quite
3651                // awkward to turn on otherwise.
3652                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3653            }
3654            // Run the app in safe mode if its manifest requests so or the
3655            // system is booted in safe mode.
3656            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3657                mSafeMode == true) {
3658                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3659            }
3660            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3661                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3662            }
3663            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3664            if ("true".equals(genDebugInfoProperty)) {
3665                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3669            }
3670            if ("1".equals(SystemProperties.get("debug.assert"))) {
3671                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3672            }
3673            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3674                // Enable all debug flags required by the native debugger.
3675                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3676                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3677                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3678                mNativeDebuggingApp = null;
3679            }
3680
3681            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3682            if (requiredAbi == null) {
3683                requiredAbi = Build.SUPPORTED_ABIS[0];
3684            }
3685
3686            String instructionSet = null;
3687            if (app.info.primaryCpuAbi != null) {
3688                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3689            }
3690
3691            app.gids = gids;
3692            app.requiredAbi = requiredAbi;
3693            app.instructionSet = instructionSet;
3694
3695            // Start the process.  It will either succeed and return a result containing
3696            // the PID of the new process, or else throw a RuntimeException.
3697            boolean isActivityProcess = (entryPoint == null);
3698            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3699            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3700                    app.processName);
3701            checkTime(startTime, "startProcess: asking zygote to start proc");
3702            Process.ProcessStartResult startResult = Process.start(entryPoint,
3703                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3704                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3705                    app.info.dataDir, entryPointArgs);
3706            checkTime(startTime, "startProcess: returned from zygote!");
3707            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3708
3709            if (app.isolated) {
3710                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3711            }
3712            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3713            checkTime(startTime, "startProcess: done updating battery stats");
3714
3715            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3716                    UserHandle.getUserId(uid), startResult.pid, uid,
3717                    app.processName, hostingType,
3718                    hostingNameStr != null ? hostingNameStr : "");
3719
3720            try {
3721                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3722                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3723            } catch (RemoteException ex) {
3724                // Ignore
3725            }
3726
3727            if (app.persistent) {
3728                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3729            }
3730
3731            checkTime(startTime, "startProcess: building log message");
3732            StringBuilder buf = mStringBuilder;
3733            buf.setLength(0);
3734            buf.append("Start proc ");
3735            buf.append(startResult.pid);
3736            buf.append(':');
3737            buf.append(app.processName);
3738            buf.append('/');
3739            UserHandle.formatUid(buf, uid);
3740            if (!isActivityProcess) {
3741                buf.append(" [");
3742                buf.append(entryPoint);
3743                buf.append("]");
3744            }
3745            buf.append(" for ");
3746            buf.append(hostingType);
3747            if (hostingNameStr != null) {
3748                buf.append(" ");
3749                buf.append(hostingNameStr);
3750            }
3751            Slog.i(TAG, buf.toString());
3752            app.setPid(startResult.pid);
3753            app.usingWrapper = startResult.usingWrapper;
3754            app.removed = false;
3755            app.killed = false;
3756            app.killedByAm = false;
3757            checkTime(startTime, "startProcess: starting to update pids map");
3758            synchronized (mPidsSelfLocked) {
3759                this.mPidsSelfLocked.put(startResult.pid, app);
3760                if (isActivityProcess) {
3761                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3762                    msg.obj = app;
3763                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3764                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3765                }
3766            }
3767            checkTime(startTime, "startProcess: done updating pids map");
3768        } catch (RuntimeException e) {
3769            Slog.e(TAG, "Failure starting process " + app.processName, e);
3770
3771            // Something went very wrong while trying to start this process; one
3772            // common case is when the package is frozen due to an active
3773            // upgrade. To recover, clean up any active bookkeeping related to
3774            // starting this process. (We already invoked this method once when
3775            // the package was initially frozen through KILL_APPLICATION_MSG, so
3776            // it doesn't hurt to use it again.)
3777            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3778                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3779        }
3780    }
3781
3782    void updateUsageStats(ActivityRecord component, boolean resumed) {
3783        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3784                "updateUsageStats: comp=" + component + "res=" + resumed);
3785        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3786        if (resumed) {
3787            if (mUsageStatsService != null) {
3788                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3789                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3790            }
3791            synchronized (stats) {
3792                stats.noteActivityResumedLocked(component.app.uid);
3793            }
3794        } else {
3795            if (mUsageStatsService != null) {
3796                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3798            }
3799            synchronized (stats) {
3800                stats.noteActivityPausedLocked(component.app.uid);
3801            }
3802        }
3803    }
3804
3805    Intent getHomeIntent() {
3806        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3807        intent.setComponent(mTopComponent);
3808        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3809        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3810            intent.addCategory(Intent.CATEGORY_HOME);
3811        }
3812        return intent;
3813    }
3814
3815    boolean startHomeActivityLocked(int userId, String reason) {
3816        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3817                && mTopAction == null) {
3818            // We are running in factory test mode, but unable to find
3819            // the factory test app, so just sit around displaying the
3820            // error message and don't try to start anything.
3821            return false;
3822        }
3823        Intent intent = getHomeIntent();
3824        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3825        if (aInfo != null) {
3826            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3827            // Don't do this if the home app is currently being
3828            // instrumented.
3829            aInfo = new ActivityInfo(aInfo);
3830            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3831            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3832                    aInfo.applicationInfo.uid, true);
3833            if (app == null || app.instrumentationClass == null) {
3834                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3835                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3836            }
3837        } else {
3838            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3839        }
3840
3841        return true;
3842    }
3843
3844    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3845        ActivityInfo ai = null;
3846        ComponentName comp = intent.getComponent();
3847        try {
3848            if (comp != null) {
3849                // Factory test.
3850                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3851            } else {
3852                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3853                        intent,
3854                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3855                        flags, userId);
3856
3857                if (info != null) {
3858                    ai = info.activityInfo;
3859                }
3860            }
3861        } catch (RemoteException e) {
3862            // ignore
3863        }
3864
3865        return ai;
3866    }
3867
3868    /**
3869     * Starts the "new version setup screen" if appropriate.
3870     */
3871    void startSetupActivityLocked() {
3872        // Only do this once per boot.
3873        if (mCheckedForSetup) {
3874            return;
3875        }
3876
3877        // We will show this screen if the current one is a different
3878        // version than the last one shown, and we are not running in
3879        // low-level factory test mode.
3880        final ContentResolver resolver = mContext.getContentResolver();
3881        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3882                Settings.Global.getInt(resolver,
3883                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3884            mCheckedForSetup = true;
3885
3886            // See if we should be showing the platform update setup UI.
3887            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3888            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3889                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3890            if (!ris.isEmpty()) {
3891                final ResolveInfo ri = ris.get(0);
3892                String vers = ri.activityInfo.metaData != null
3893                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3894                        : null;
3895                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3896                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3897                            Intent.METADATA_SETUP_VERSION);
3898                }
3899                String lastVers = Settings.Secure.getString(
3900                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3901                if (vers != null && !vers.equals(lastVers)) {
3902                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3903                    intent.setComponent(new ComponentName(
3904                            ri.activityInfo.packageName, ri.activityInfo.name));
3905                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3906                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3907                            null, 0, 0, 0, null, false, false, null, null, null);
3908                }
3909            }
3910        }
3911    }
3912
3913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3915    }
3916
3917    void enforceNotIsolatedCaller(String caller) {
3918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3919            throw new SecurityException("Isolated process not allowed to call " + caller);
3920        }
3921    }
3922
3923    void enforceShellRestriction(String restriction, int userHandle) {
3924        if (Binder.getCallingUid() == Process.SHELL_UID) {
3925            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3926                throw new SecurityException("Shell does not have permission to access user "
3927                        + userHandle);
3928            }
3929        }
3930    }
3931
3932    @Override
3933    public int getFrontActivityScreenCompatMode() {
3934        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3935        synchronized (this) {
3936            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3937        }
3938    }
3939
3940    @Override
3941    public void setFrontActivityScreenCompatMode(int mode) {
3942        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3943                "setFrontActivityScreenCompatMode");
3944        synchronized (this) {
3945            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3946        }
3947    }
3948
3949    @Override
3950    public int getPackageScreenCompatMode(String packageName) {
3951        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3952        synchronized (this) {
3953            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3954        }
3955    }
3956
3957    @Override
3958    public void setPackageScreenCompatMode(String packageName, int mode) {
3959        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3960                "setPackageScreenCompatMode");
3961        synchronized (this) {
3962            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3963        }
3964    }
3965
3966    @Override
3967    public boolean getPackageAskScreenCompat(String packageName) {
3968        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3969        synchronized (this) {
3970            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3971        }
3972    }
3973
3974    @Override
3975    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3976        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977                "setPackageAskScreenCompat");
3978        synchronized (this) {
3979            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3980        }
3981    }
3982
3983    private boolean hasUsageStatsPermission(String callingPackage) {
3984        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3985                Binder.getCallingUid(), callingPackage);
3986        if (mode == AppOpsManager.MODE_DEFAULT) {
3987            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3988                    == PackageManager.PERMISSION_GRANTED;
3989        }
3990        return mode == AppOpsManager.MODE_ALLOWED;
3991    }
3992
3993    @Override
3994    public int getPackageProcessState(String packageName, String callingPackage) {
3995        if (!hasUsageStatsPermission(callingPackage)) {
3996            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3997                    "getPackageProcessState");
3998        }
3999
4000        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4001        synchronized (this) {
4002            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003                final ProcessRecord proc = mLruProcesses.get(i);
4004                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4005                        || procState > proc.setProcState) {
4006                    boolean found = false;
4007                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4008                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4009                            procState = proc.setProcState;
4010                            found = true;
4011                        }
4012                    }
4013                    if (proc.pkgDeps != null && !found) {
4014                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4015                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4016                                procState = proc.setProcState;
4017                                break;
4018                            }
4019                        }
4020                    }
4021                }
4022            }
4023        }
4024        return procState;
4025    }
4026
4027    @Override
4028    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4029        synchronized (this) {
4030            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4031            if (app == null) {
4032                return false;
4033            }
4034            if (app.trimMemoryLevel < level && app.thread != null &&
4035                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4036                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4037                try {
4038                    app.thread.scheduleTrimMemory(level);
4039                    app.trimMemoryLevel = level;
4040                    return true;
4041                } catch (RemoteException e) {
4042                    // Fallthrough to failure case.
4043                }
4044            }
4045        }
4046        return false;
4047    }
4048
4049    private void dispatchProcessesChanged() {
4050        int N;
4051        synchronized (this) {
4052            N = mPendingProcessChanges.size();
4053            if (mActiveProcessChanges.length < N) {
4054                mActiveProcessChanges = new ProcessChangeItem[N];
4055            }
4056            mPendingProcessChanges.toArray(mActiveProcessChanges);
4057            mPendingProcessChanges.clear();
4058            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059                    "*** Delivering " + N + " process changes");
4060        }
4061
4062        int i = mProcessObservers.beginBroadcast();
4063        while (i > 0) {
4064            i--;
4065            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066            if (observer != null) {
4067                try {
4068                    for (int j=0; j<N; j++) {
4069                        ProcessChangeItem item = mActiveProcessChanges[j];
4070                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073                                    + item.uid + ": " + item.foregroundActivities);
4074                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075                                    item.foregroundActivities);
4076                        }
4077                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080                                    + ": " + item.processState);
4081                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4082                        }
4083                    }
4084                } catch (RemoteException e) {
4085                }
4086            }
4087        }
4088        mProcessObservers.finishBroadcast();
4089
4090        synchronized (this) {
4091            for (int j=0; j<N; j++) {
4092                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4093            }
4094        }
4095    }
4096
4097    private void dispatchProcessDied(int pid, int uid) {
4098        int i = mProcessObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102            if (observer != null) {
4103                try {
4104                    observer.onProcessDied(pid, uid);
4105                } catch (RemoteException e) {
4106                }
4107            }
4108        }
4109        mProcessObservers.finishBroadcast();
4110    }
4111
4112    private void dispatchUidsChanged() {
4113        int N;
4114        synchronized (this) {
4115            N = mPendingUidChanges.size();
4116            if (mActiveUidChanges.length < N) {
4117                mActiveUidChanges = new UidRecord.ChangeItem[N];
4118            }
4119            for (int i=0; i<N; i++) {
4120                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121                mActiveUidChanges[i] = change;
4122                if (change.uidRecord != null) {
4123                    change.uidRecord.pendingChange = null;
4124                    change.uidRecord = null;
4125                }
4126            }
4127            mPendingUidChanges.clear();
4128            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                    "*** Delivering " + N + " uid changes");
4130        }
4131
4132        if (mLocalPowerManager != null) {
4133            for (int j=0; j<N; j++) {
4134                UidRecord.ChangeItem item = mActiveUidChanges[j];
4135                if (item.change == UidRecord.CHANGE_GONE
4136                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4137                    mLocalPowerManager.uidGone(item.uid);
4138                } else {
4139                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4140                }
4141            }
4142        }
4143
4144        int i = mUidObservers.beginBroadcast();
4145        while (i > 0) {
4146            i--;
4147            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4148            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4149            if (observer != null) {
4150                try {
4151                    for (int j=0; j<N; j++) {
4152                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4153                        final int change = item.change;
4154                        UidRecord validateUid = null;
4155                        if (VALIDATE_UID_STATES && i == 0) {
4156                            validateUid = mValidateUids.get(item.uid);
4157                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4158                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4159                                validateUid = new UidRecord(item.uid);
4160                                mValidateUids.put(item.uid, validateUid);
4161                            }
4162                        }
4163                        if (change == UidRecord.CHANGE_IDLE
4164                                || change == UidRecord.CHANGE_GONE_IDLE) {
4165                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4166                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                                        "UID idle uid=" + item.uid);
4168                                observer.onUidIdle(item.uid);
4169                            }
4170                            if (VALIDATE_UID_STATES && i == 0) {
4171                                if (validateUid != null) {
4172                                    validateUid.idle = true;
4173                                }
4174                            }
4175                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4176                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4177                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178                                        "UID active uid=" + item.uid);
4179                                observer.onUidActive(item.uid);
4180                            }
4181                            if (VALIDATE_UID_STATES && i == 0) {
4182                                validateUid.idle = false;
4183                            }
4184                        }
4185                        if (change == UidRecord.CHANGE_GONE
4186                                || change == UidRecord.CHANGE_GONE_IDLE) {
4187                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4188                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4189                                        "UID gone uid=" + item.uid);
4190                                observer.onUidGone(item.uid);
4191                            }
4192                            if (VALIDATE_UID_STATES && i == 0) {
4193                                if (validateUid != null) {
4194                                    mValidateUids.remove(item.uid);
4195                                }
4196                            }
4197                        } else {
4198                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4199                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                                        "UID CHANGED uid=" + item.uid
4201                                                + ": " + item.processState);
4202                                observer.onUidStateChanged(item.uid, item.processState);
4203                            }
4204                            if (VALIDATE_UID_STATES && i == 0) {
4205                                validateUid.curProcState = validateUid.setProcState
4206                                        = item.processState;
4207                            }
4208                        }
4209                    }
4210                } catch (RemoteException e) {
4211                }
4212            }
4213        }
4214        mUidObservers.finishBroadcast();
4215
4216        synchronized (this) {
4217            for (int j=0; j<N; j++) {
4218                mAvailUidChanges.add(mActiveUidChanges[j]);
4219            }
4220        }
4221    }
4222
4223    @Override
4224    public final int startActivity(IApplicationThread caller, String callingPackage,
4225            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4226            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4227        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4228                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4229                UserHandle.getCallingUserId());
4230    }
4231
4232    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4233        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4234        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4235                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4236                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4237
4238        // TODO: Switch to user app stacks here.
4239        String mimeType = intent.getType();
4240        final Uri data = intent.getData();
4241        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4242            mimeType = getProviderMimeType(data, userId);
4243        }
4244        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4245
4246        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4247        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4248                null, 0, 0, null, null, null, null, false, userId, container, null);
4249    }
4250
4251    @Override
4252    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4253            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4254            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4255        enforceNotIsolatedCaller("startActivity");
4256        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4257                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4258        // TODO: Switch to user app stacks here.
4259        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4260                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4261                profilerInfo, null, null, bOptions, false, userId, null, null);
4262    }
4263
4264    @Override
4265    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4268            int userId) {
4269
4270        // This is very dangerous -- it allows you to perform a start activity (including
4271        // permission grants) as any app that may launch one of your own activities.  So
4272        // we will only allow this to be done from activities that are part of the core framework,
4273        // and then only when they are running as the system.
4274        final ActivityRecord sourceRecord;
4275        final int targetUid;
4276        final String targetPackage;
4277        synchronized (this) {
4278            if (resultTo == null) {
4279                throw new SecurityException("Must be called from an activity");
4280            }
4281            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4282            if (sourceRecord == null) {
4283                throw new SecurityException("Called with bad activity token: " + resultTo);
4284            }
4285            if (!sourceRecord.info.packageName.equals("android")) {
4286                throw new SecurityException(
4287                        "Must be called from an activity that is declared in the android package");
4288            }
4289            if (sourceRecord.app == null) {
4290                throw new SecurityException("Called without a process attached to activity");
4291            }
4292            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4293                // This is still okay, as long as this activity is running under the
4294                // uid of the original calling activity.
4295                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4296                    throw new SecurityException(
4297                            "Calling activity in uid " + sourceRecord.app.uid
4298                                    + " must be system uid or original calling uid "
4299                                    + sourceRecord.launchedFromUid);
4300                }
4301            }
4302            if (ignoreTargetSecurity) {
4303                if (intent.getComponent() == null) {
4304                    throw new SecurityException(
4305                            "Component must be specified with ignoreTargetSecurity");
4306                }
4307                if (intent.getSelector() != null) {
4308                    throw new SecurityException(
4309                            "Selector not allowed with ignoreTargetSecurity");
4310                }
4311            }
4312            targetUid = sourceRecord.launchedFromUid;
4313            targetPackage = sourceRecord.launchedFromPackage;
4314        }
4315
4316        if (userId == UserHandle.USER_NULL) {
4317            userId = UserHandle.getUserId(sourceRecord.app.uid);
4318        }
4319
4320        // TODO: Switch to user app stacks here.
4321        try {
4322            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4323                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4324                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4325            return ret;
4326        } catch (SecurityException e) {
4327            // XXX need to figure out how to propagate to original app.
4328            // A SecurityException here is generally actually a fault of the original
4329            // calling activity (such as a fairly granting permissions), so propagate it
4330            // back to them.
4331            /*
4332            StringBuilder msg = new StringBuilder();
4333            msg.append("While launching");
4334            msg.append(intent.toString());
4335            msg.append(": ");
4336            msg.append(e.getMessage());
4337            */
4338            throw e;
4339        }
4340    }
4341
4342    @Override
4343    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4344            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4345            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4346        enforceNotIsolatedCaller("startActivityAndWait");
4347        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4349        WaitResult res = new WaitResult();
4350        // TODO: Switch to user app stacks here.
4351        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4352                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4353                bOptions, false, userId, null, null);
4354        return res;
4355    }
4356
4357    @Override
4358    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360            int startFlags, Configuration config, Bundle bOptions, int userId) {
4361        enforceNotIsolatedCaller("startActivityWithConfig");
4362        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4364        // TODO: Switch to user app stacks here.
4365        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4366                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4367                null, null, config, bOptions, false, userId, null, null);
4368        return ret;
4369    }
4370
4371    @Override
4372    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4373            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4374            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4375            throws TransactionTooLargeException {
4376        enforceNotIsolatedCaller("startActivityIntentSender");
4377        // Refuse possible leaked file descriptors
4378        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4379            throw new IllegalArgumentException("File descriptors passed in Intent");
4380        }
4381
4382        IIntentSender sender = intent.getTarget();
4383        if (!(sender instanceof PendingIntentRecord)) {
4384            throw new IllegalArgumentException("Bad PendingIntent object");
4385        }
4386
4387        PendingIntentRecord pir = (PendingIntentRecord)sender;
4388
4389        synchronized (this) {
4390            // If this is coming from the currently resumed activity, it is
4391            // effectively saying that app switches are allowed at this point.
4392            final ActivityStack stack = getFocusedStack();
4393            if (stack.mResumedActivity != null &&
4394                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4395                mAppSwitchesAllowedTime = 0;
4396            }
4397        }
4398        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4399                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4400        return ret;
4401    }
4402
4403    @Override
4404    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4405            Intent intent, String resolvedType, IVoiceInteractionSession session,
4406            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4407            Bundle bOptions, int userId) {
4408        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4409                != PackageManager.PERMISSION_GRANTED) {
4410            String msg = "Permission Denial: startVoiceActivity() from pid="
4411                    + Binder.getCallingPid()
4412                    + ", uid=" + Binder.getCallingUid()
4413                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4414            Slog.w(TAG, msg);
4415            throw new SecurityException(msg);
4416        }
4417        if (session == null || interactor == null) {
4418            throw new NullPointerException("null session or interactor");
4419        }
4420        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4421                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4422        // TODO: Switch to user app stacks here.
4423        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4424                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4425                null, bOptions, false, userId, null, null);
4426    }
4427
4428    @Override
4429    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4430            throws RemoteException {
4431        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4432        synchronized (this) {
4433            ActivityRecord activity = getFocusedStack().topActivity();
4434            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4435                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4436            }
4437            if (mRunningVoice != null || activity.task.voiceSession != null
4438                    || activity.voiceSession != null) {
4439                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4440                return;
4441            }
4442            if (activity.pendingVoiceInteractionStart) {
4443                Slog.w(TAG, "Pending start of voice interaction already.");
4444                return;
4445            }
4446            activity.pendingVoiceInteractionStart = true;
4447        }
4448        LocalServices.getService(VoiceInteractionManagerInternal.class)
4449                .startLocalVoiceInteraction(callingActivity, options);
4450    }
4451
4452    @Override
4453    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4454        LocalServices.getService(VoiceInteractionManagerInternal.class)
4455                .stopLocalVoiceInteraction(callingActivity);
4456    }
4457
4458    @Override
4459    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4460        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4461                .supportsLocalVoiceInteraction();
4462    }
4463
4464    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4465            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4466        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4467        if (activityToCallback == null) return;
4468        activityToCallback.setVoiceSessionLocked(voiceSession);
4469
4470        // Inform the activity
4471        try {
4472            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4473                    voiceInteractor);
4474            long token = Binder.clearCallingIdentity();
4475            try {
4476                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4477            } finally {
4478                Binder.restoreCallingIdentity(token);
4479            }
4480            // TODO: VI Should we cache the activity so that it's easier to find later
4481            // rather than scan through all the stacks and activities?
4482        } catch (RemoteException re) {
4483            activityToCallback.clearVoiceSessionLocked();
4484            // TODO: VI Should this terminate the voice session?
4485        }
4486    }
4487
4488    @Override
4489    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4490        synchronized (this) {
4491            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4492                if (keepAwake) {
4493                    mVoiceWakeLock.acquire();
4494                } else {
4495                    mVoiceWakeLock.release();
4496                }
4497            }
4498        }
4499    }
4500
4501    @Override
4502    public boolean startNextMatchingActivity(IBinder callingActivity,
4503            Intent intent, Bundle bOptions) {
4504        // Refuse possible leaked file descriptors
4505        if (intent != null && intent.hasFileDescriptors() == true) {
4506            throw new IllegalArgumentException("File descriptors passed in Intent");
4507        }
4508        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4509
4510        synchronized (this) {
4511            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4512            if (r == null) {
4513                ActivityOptions.abort(options);
4514                return false;
4515            }
4516            if (r.app == null || r.app.thread == null) {
4517                // The caller is not running...  d'oh!
4518                ActivityOptions.abort(options);
4519                return false;
4520            }
4521            intent = new Intent(intent);
4522            // The caller is not allowed to change the data.
4523            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4524            // And we are resetting to find the next component...
4525            intent.setComponent(null);
4526
4527            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4528
4529            ActivityInfo aInfo = null;
4530            try {
4531                List<ResolveInfo> resolves =
4532                    AppGlobals.getPackageManager().queryIntentActivities(
4533                            intent, r.resolvedType,
4534                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4535                            UserHandle.getCallingUserId()).getList();
4536
4537                // Look for the original activity in the list...
4538                final int N = resolves != null ? resolves.size() : 0;
4539                for (int i=0; i<N; i++) {
4540                    ResolveInfo rInfo = resolves.get(i);
4541                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4542                            && rInfo.activityInfo.name.equals(r.info.name)) {
4543                        // We found the current one...  the next matching is
4544                        // after it.
4545                        i++;
4546                        if (i<N) {
4547                            aInfo = resolves.get(i).activityInfo;
4548                        }
4549                        if (debug) {
4550                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4551                                    + "/" + r.info.name);
4552                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4553                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4554                        }
4555                        break;
4556                    }
4557                }
4558            } catch (RemoteException e) {
4559            }
4560
4561            if (aInfo == null) {
4562                // Nobody who is next!
4563                ActivityOptions.abort(options);
4564                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4565                return false;
4566            }
4567
4568            intent.setComponent(new ComponentName(
4569                    aInfo.applicationInfo.packageName, aInfo.name));
4570            intent.setFlags(intent.getFlags()&~(
4571                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4572                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4573                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4574                    Intent.FLAG_ACTIVITY_NEW_TASK));
4575
4576            // Okay now we need to start the new activity, replacing the
4577            // currently running activity.  This is a little tricky because
4578            // we want to start the new one as if the current one is finished,
4579            // but not finish the current one first so that there is no flicker.
4580            // And thus...
4581            final boolean wasFinishing = r.finishing;
4582            r.finishing = true;
4583
4584            // Propagate reply information over to the new activity.
4585            final ActivityRecord resultTo = r.resultTo;
4586            final String resultWho = r.resultWho;
4587            final int requestCode = r.requestCode;
4588            r.resultTo = null;
4589            if (resultTo != null) {
4590                resultTo.removeResultsLocked(r, resultWho, requestCode);
4591            }
4592
4593            final long origId = Binder.clearCallingIdentity();
4594            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4595                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4596                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4597                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4598                    false, false, null, null, null);
4599            Binder.restoreCallingIdentity(origId);
4600
4601            r.finishing = wasFinishing;
4602            if (res != ActivityManager.START_SUCCESS) {
4603                return false;
4604            }
4605            return true;
4606        }
4607    }
4608
4609    @Override
4610    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4611        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4612            String msg = "Permission Denial: startActivityFromRecents called without " +
4613                    START_TASKS_FROM_RECENTS;
4614            Slog.w(TAG, msg);
4615            throw new SecurityException(msg);
4616        }
4617        final long origId = Binder.clearCallingIdentity();
4618        try {
4619            synchronized (this) {
4620                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    final int startActivityInPackage(int uid, String callingPackage,
4628            Intent intent, String resolvedType, IBinder resultTo,
4629            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4630            IActivityContainer container, TaskRecord inTask) {
4631
4632        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4633                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4634
4635        // TODO: Switch to user app stacks here.
4636        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4637                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4638                null, null, null, bOptions, false, userId, container, inTask);
4639        return ret;
4640    }
4641
4642    @Override
4643    public final int startActivities(IApplicationThread caller, String callingPackage,
4644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4645            int userId) {
4646        enforceNotIsolatedCaller("startActivities");
4647        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4648                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4649        // TODO: Switch to user app stacks here.
4650        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4651                resolvedTypes, resultTo, bOptions, userId);
4652        return ret;
4653    }
4654
4655    final int startActivitiesInPackage(int uid, String callingPackage,
4656            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4657            Bundle bOptions, int userId) {
4658
4659        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4660                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4661        // TODO: Switch to user app stacks here.
4662        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4663                resultTo, bOptions, userId);
4664        return ret;
4665    }
4666
4667    @Override
4668    public void reportActivityFullyDrawn(IBinder token) {
4669        synchronized (this) {
4670            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671            if (r == null) {
4672                return;
4673            }
4674            r.reportFullyDrawnLocked();
4675        }
4676    }
4677
4678    @Override
4679    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4680        synchronized (this) {
4681            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682            if (r == null) {
4683                return;
4684            }
4685            TaskRecord task = r.task;
4686            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4687                // Fixed screen orientation isn't supported when activities aren't in full screen
4688                // mode.
4689                return;
4690            }
4691            final long origId = Binder.clearCallingIdentity();
4692            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4693            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4694                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4695            if (config != null) {
4696                r.frozenBeforeDestroy = true;
4697                if (!updateConfigurationLocked(config, r, false)) {
4698                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4699                }
4700            }
4701            Binder.restoreCallingIdentity(origId);
4702        }
4703    }
4704
4705    @Override
4706    public int getRequestedOrientation(IBinder token) {
4707        synchronized (this) {
4708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4709            if (r == null) {
4710                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4711            }
4712            return mWindowManager.getAppOrientation(r.appToken);
4713        }
4714    }
4715
4716    /**
4717     * This is the internal entry point for handling Activity.finish().
4718     *
4719     * @param token The Binder token referencing the Activity we want to finish.
4720     * @param resultCode Result code, if any, from this Activity.
4721     * @param resultData Result data (Intent), if any, from this Activity.
4722     * @param finishTask Whether to finish the task associated with this Activity.
4723     *
4724     * @return Returns true if the activity successfully finished, or false if it is still running.
4725     */
4726    @Override
4727    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4728            int finishTask) {
4729        // Refuse possible leaked file descriptors
4730        if (resultData != null && resultData.hasFileDescriptors() == true) {
4731            throw new IllegalArgumentException("File descriptors passed in Intent");
4732        }
4733
4734        synchronized(this) {
4735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736            if (r == null) {
4737                return true;
4738            }
4739            // Keep track of the root activity of the task before we finish it
4740            TaskRecord tr = r.task;
4741            ActivityRecord rootR = tr.getRootActivity();
4742            if (rootR == null) {
4743                Slog.w(TAG, "Finishing task with all activities already finished");
4744            }
4745            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4746            // finish.
4747            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4748                    mStackSupervisor.isLastLockedTask(tr)) {
4749                Slog.i(TAG, "Not finishing task in lock task mode");
4750                mStackSupervisor.showLockTaskToast();
4751                return false;
4752            }
4753            if (mController != null) {
4754                // Find the first activity that is not finishing.
4755                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4756                if (next != null) {
4757                    // ask watcher if this is allowed
4758                    boolean resumeOK = true;
4759                    try {
4760                        resumeOK = mController.activityResuming(next.packageName);
4761                    } catch (RemoteException e) {
4762                        mController = null;
4763                        Watchdog.getInstance().setActivityController(null);
4764                    }
4765
4766                    if (!resumeOK) {
4767                        Slog.i(TAG, "Not finishing activity because controller resumed");
4768                        return false;
4769                    }
4770                }
4771            }
4772            final long origId = Binder.clearCallingIdentity();
4773            try {
4774                boolean res;
4775                final boolean finishWithRootActivity =
4776                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4777                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4778                        || (finishWithRootActivity && r == rootR)) {
4779                    // If requested, remove the task that is associated to this activity only if it
4780                    // was the root activity in the task. The result code and data is ignored
4781                    // because we don't support returning them across task boundaries. Also, to
4782                    // keep backwards compatibility we remove the task from recents when finishing
4783                    // task with root activity.
4784                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4785                    if (!res) {
4786                        Slog.i(TAG, "Removing task failed to finish activity");
4787                    }
4788                } else {
4789                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4790                            resultData, "app-request", true);
4791                    if (!res) {
4792                        Slog.i(TAG, "Failed to finish by app-request");
4793                    }
4794                }
4795                return res;
4796            } finally {
4797                Binder.restoreCallingIdentity(origId);
4798            }
4799        }
4800    }
4801
4802    @Override
4803    public final void finishHeavyWeightApp() {
4804        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805                != PackageManager.PERMISSION_GRANTED) {
4806            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4807                    + Binder.getCallingPid()
4808                    + ", uid=" + Binder.getCallingUid()
4809                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4810            Slog.w(TAG, msg);
4811            throw new SecurityException(msg);
4812        }
4813
4814        synchronized(this) {
4815            if (mHeavyWeightProcess == null) {
4816                return;
4817            }
4818
4819            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4820            for (int i = 0; i < activities.size(); i++) {
4821                ActivityRecord r = activities.get(i);
4822                if (!r.finishing && r.isInStackLocked()) {
4823                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4824                            null, "finish-heavy", true);
4825                }
4826            }
4827
4828            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4829                    mHeavyWeightProcess.userId, 0));
4830            mHeavyWeightProcess = null;
4831        }
4832    }
4833
4834    @Override
4835    public void crashApplication(int uid, int initialPid, String packageName,
4836            String message) {
4837        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4838                != PackageManager.PERMISSION_GRANTED) {
4839            String msg = "Permission Denial: crashApplication() from pid="
4840                    + Binder.getCallingPid()
4841                    + ", uid=" + Binder.getCallingUid()
4842                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4843            Slog.w(TAG, msg);
4844            throw new SecurityException(msg);
4845        }
4846
4847        synchronized(this) {
4848            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4849        }
4850    }
4851
4852    @Override
4853    public final void finishSubActivity(IBinder token, String resultWho,
4854            int requestCode) {
4855        synchronized(this) {
4856            final long origId = Binder.clearCallingIdentity();
4857            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4858            if (r != null) {
4859                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4860            }
4861            Binder.restoreCallingIdentity(origId);
4862        }
4863    }
4864
4865    @Override
4866    public boolean finishActivityAffinity(IBinder token) {
4867        synchronized(this) {
4868            final long origId = Binder.clearCallingIdentity();
4869            try {
4870                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4871                if (r == null) {
4872                    return false;
4873                }
4874
4875                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4876                // can finish.
4877                final TaskRecord task = r.task;
4878                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4879                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4880                    mStackSupervisor.showLockTaskToast();
4881                    return false;
4882                }
4883                return task.stack.finishActivityAffinityLocked(r);
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void finishVoiceTask(IVoiceInteractionSession session) {
4892        synchronized (this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                // TODO: VI Consider treating local voice interactions and voice tasks
4896                // differently here
4897                mStackSupervisor.finishVoiceTask(session);
4898            } finally {
4899                Binder.restoreCallingIdentity(origId);
4900            }
4901        }
4902
4903    }
4904
4905    @Override
4906    public boolean releaseActivityInstance(IBinder token) {
4907        synchronized(this) {
4908            final long origId = Binder.clearCallingIdentity();
4909            try {
4910                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911                if (r == null) {
4912                    return false;
4913                }
4914                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4915            } finally {
4916                Binder.restoreCallingIdentity(origId);
4917            }
4918        }
4919    }
4920
4921    @Override
4922    public void releaseSomeActivities(IApplicationThread appInt) {
4923        synchronized(this) {
4924            final long origId = Binder.clearCallingIdentity();
4925            try {
4926                ProcessRecord app = getRecordForAppLocked(appInt);
4927                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4928            } finally {
4929                Binder.restoreCallingIdentity(origId);
4930            }
4931        }
4932    }
4933
4934    @Override
4935    public boolean willActivityBeVisible(IBinder token) {
4936        synchronized(this) {
4937            ActivityStack stack = ActivityRecord.getStackLocked(token);
4938            if (stack != null) {
4939                return stack.willActivityBeVisibleLocked(token);
4940            }
4941            return false;
4942        }
4943    }
4944
4945    @Override
4946    public void overridePendingTransition(IBinder token, String packageName,
4947            int enterAnim, int exitAnim) {
4948        synchronized(this) {
4949            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4950            if (self == null) {
4951                return;
4952            }
4953
4954            final long origId = Binder.clearCallingIdentity();
4955
4956            if (self.state == ActivityState.RESUMED
4957                    || self.state == ActivityState.PAUSING) {
4958                mWindowManager.overridePendingAppTransition(packageName,
4959                        enterAnim, exitAnim, null);
4960            }
4961
4962            Binder.restoreCallingIdentity(origId);
4963        }
4964    }
4965
4966    /**
4967     * Main function for removing an existing process from the activity manager
4968     * as a result of that process going away.  Clears out all connections
4969     * to the process.
4970     */
4971    private final void handleAppDiedLocked(ProcessRecord app,
4972            boolean restarting, boolean allowRestart) {
4973        int pid = app.pid;
4974        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4975        if (!kept && !restarting) {
4976            removeLruProcessLocked(app);
4977            if (pid > 0) {
4978                ProcessList.remove(pid);
4979            }
4980        }
4981
4982        if (mProfileProc == app) {
4983            clearProfilerLocked();
4984        }
4985
4986        // Remove this application's activities from active lists.
4987        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4988
4989        app.activities.clear();
4990
4991        if (app.instrumentationClass != null) {
4992            Slog.w(TAG, "Crash of app " + app.processName
4993                  + " running instrumentation " + app.instrumentationClass);
4994            Bundle info = new Bundle();
4995            info.putString("shortMsg", "Process crashed.");
4996            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4997        }
4998
4999        if (!restarting && hasVisibleActivities
5000                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5001            // If there was nothing to resume, and we are not already restarting this process, but
5002            // there is a visible activity that is hosted by the process...  then make sure all
5003            // visible activities are running, taking care of restarting this process.
5004            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5005        }
5006    }
5007
5008    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5009        IBinder threadBinder = thread.asBinder();
5010        // Find the application record.
5011        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012            ProcessRecord rec = mLruProcesses.get(i);
5013            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5014                return i;
5015            }
5016        }
5017        return -1;
5018    }
5019
5020    final ProcessRecord getRecordForAppLocked(
5021            IApplicationThread thread) {
5022        if (thread == null) {
5023            return null;
5024        }
5025
5026        int appIndex = getLRURecordIndexForAppLocked(thread);
5027        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5028    }
5029
5030    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5031        // If there are no longer any background processes running,
5032        // and the app that died was not running instrumentation,
5033        // then tell everyone we are now low on memory.
5034        boolean haveBg = false;
5035        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036            ProcessRecord rec = mLruProcesses.get(i);
5037            if (rec.thread != null
5038                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5039                haveBg = true;
5040                break;
5041            }
5042        }
5043
5044        if (!haveBg) {
5045            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5046            if (doReport) {
5047                long now = SystemClock.uptimeMillis();
5048                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5049                    doReport = false;
5050                } else {
5051                    mLastMemUsageReportTime = now;
5052                }
5053            }
5054            final ArrayList<ProcessMemInfo> memInfos
5055                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5056            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5057            long now = SystemClock.uptimeMillis();
5058            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059                ProcessRecord rec = mLruProcesses.get(i);
5060                if (rec == dyingProc || rec.thread == null) {
5061                    continue;
5062                }
5063                if (doReport) {
5064                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5065                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5066                }
5067                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5068                    // The low memory report is overriding any current
5069                    // state for a GC request.  Make sure to do
5070                    // heavy/important/visible/foreground processes first.
5071                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5072                        rec.lastRequestedGc = 0;
5073                    } else {
5074                        rec.lastRequestedGc = rec.lastLowMemory;
5075                    }
5076                    rec.reportLowMemory = true;
5077                    rec.lastLowMemory = now;
5078                    mProcessesToGc.remove(rec);
5079                    addProcessToGcListLocked(rec);
5080                }
5081            }
5082            if (doReport) {
5083                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5084                mHandler.sendMessage(msg);
5085            }
5086            scheduleAppGcsLocked();
5087        }
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app) {
5091       appDiedLocked(app, app.pid, app.thread, false);
5092    }
5093
5094    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5095            boolean fromBinderDied) {
5096        // First check if this ProcessRecord is actually active for the pid.
5097        synchronized (mPidsSelfLocked) {
5098            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5099            if (curProc != app) {
5100                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5101                return;
5102            }
5103        }
5104
5105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5106        synchronized (stats) {
5107            stats.noteProcessDiedLocked(app.info.uid, pid);
5108        }
5109
5110        if (!app.killed) {
5111            if (!fromBinderDied) {
5112                Process.killProcessQuiet(pid);
5113            }
5114            killProcessGroup(app.uid, pid);
5115            app.killed = true;
5116        }
5117
5118        // Clean up already done if the process has been re-started.
5119        if (app.pid == pid && app.thread != null &&
5120                app.thread.asBinder() == thread.asBinder()) {
5121            boolean doLowMem = app.instrumentationClass == null;
5122            boolean doOomAdj = doLowMem;
5123            if (!app.killedByAm) {
5124                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5125                        + ") has died");
5126                mAllowLowerMemLevel = true;
5127            } else {
5128                // Note that we always want to do oom adj to update our state with the
5129                // new number of procs.
5130                mAllowLowerMemLevel = false;
5131                doLowMem = false;
5132            }
5133            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5134            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5135                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5136            handleAppDiedLocked(app, false, true);
5137
5138            if (doOomAdj) {
5139                updateOomAdjLocked();
5140            }
5141            if (doLowMem) {
5142                doLowMemReportIfNeededLocked(app);
5143            }
5144        } else if (app.pid != pid) {
5145            // A new process has already been started.
5146            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5147                    + ") has died and restarted (pid " + app.pid + ").");
5148            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5149        } else if (DEBUG_PROCESSES) {
5150            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5151                    + thread.asBinder());
5152        }
5153    }
5154
5155    /**
5156     * If a stack trace dump file is configured, dump process stack traces.
5157     * @param clearTraces causes the dump file to be erased prior to the new
5158     *    traces being written, if true; when false, the new traces will be
5159     *    appended to any existing file content.
5160     * @param firstPids of dalvik VM processes to dump stack traces for first
5161     * @param lastPids of dalvik VM processes to dump stack traces for last
5162     * @param nativeProcs optional list of native process names to dump stack crawls
5163     * @return file containing stack traces, or null if no dump file is configured
5164     */
5165    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5166            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5167        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5168        if (tracesPath == null || tracesPath.length() == 0) {
5169            return null;
5170        }
5171
5172        File tracesFile = new File(tracesPath);
5173        try {
5174            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5175            tracesFile.createNewFile();
5176            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5177        } catch (IOException e) {
5178            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5179            return null;
5180        }
5181
5182        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5183        return tracesFile;
5184    }
5185
5186    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5188        // Use a FileObserver to detect when traces finish writing.
5189        // The order of traces is considered important to maintain for legibility.
5190        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5191            @Override
5192            public synchronized void onEvent(int event, String path) { notify(); }
5193        };
5194
5195        try {
5196            observer.startWatching();
5197
5198            // First collect all of the stacks of the most important pids.
5199            if (firstPids != null) {
5200                try {
5201                    int num = firstPids.size();
5202                    for (int i = 0; i < num; i++) {
5203                        synchronized (observer) {
5204                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5205                                    + firstPids.get(i));
5206                            final long sime = SystemClock.elapsedRealtime();
5207                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5208                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5209                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5210                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5211                        }
5212                    }
5213                } catch (InterruptedException e) {
5214                    Slog.wtf(TAG, e);
5215                }
5216            }
5217
5218            // Next collect the stacks of the native pids
5219            if (nativeProcs != null) {
5220                int[] pids = Process.getPidsForCommands(nativeProcs);
5221                if (pids != null) {
5222                    for (int pid : pids) {
5223                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5224                        final long sime = SystemClock.elapsedRealtime();
5225                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5226                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5227                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5228                    }
5229                }
5230            }
5231
5232            // Lastly, measure CPU usage.
5233            if (processCpuTracker != null) {
5234                processCpuTracker.init();
5235                System.gc();
5236                processCpuTracker.update();
5237                try {
5238                    synchronized (processCpuTracker) {
5239                        processCpuTracker.wait(500); // measure over 1/2 second.
5240                    }
5241                } catch (InterruptedException e) {
5242                }
5243                processCpuTracker.update();
5244
5245                // We'll take the stack crawls of just the top apps using CPU.
5246                final int N = processCpuTracker.countWorkingStats();
5247                int numProcs = 0;
5248                for (int i=0; i<N && numProcs<5; i++) {
5249                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5250                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5251                        numProcs++;
5252                        try {
5253                            synchronized (observer) {
5254                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5255                                        + stats.pid);
5256                                final long stime = SystemClock.elapsedRealtime();
5257                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5258                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5259                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5260                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5261                            }
5262                        } catch (InterruptedException e) {
5263                            Slog.wtf(TAG, e);
5264                        }
5265                    } else if (DEBUG_ANR) {
5266                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5267                                + stats.pid);
5268                    }
5269                }
5270            }
5271        } finally {
5272            observer.stopWatching();
5273        }
5274    }
5275
5276    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5277        if (true || IS_USER_BUILD) {
5278            return;
5279        }
5280        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5281        if (tracesPath == null || tracesPath.length() == 0) {
5282            return;
5283        }
5284
5285        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5286        StrictMode.allowThreadDiskWrites();
5287        try {
5288            final File tracesFile = new File(tracesPath);
5289            final File tracesDir = tracesFile.getParentFile();
5290            final File tracesTmp = new File(tracesDir, "__tmp__");
5291            try {
5292                if (tracesFile.exists()) {
5293                    tracesTmp.delete();
5294                    tracesFile.renameTo(tracesTmp);
5295                }
5296                StringBuilder sb = new StringBuilder();
5297                Time tobj = new Time();
5298                tobj.set(System.currentTimeMillis());
5299                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5300                sb.append(": ");
5301                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5302                sb.append(" since ");
5303                sb.append(msg);
5304                FileOutputStream fos = new FileOutputStream(tracesFile);
5305                fos.write(sb.toString().getBytes());
5306                if (app == null) {
5307                    fos.write("\n*** No application process!".getBytes());
5308                }
5309                fos.close();
5310                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311            } catch (IOException e) {
5312                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5313                return;
5314            }
5315
5316            if (app != null) {
5317                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5318                firstPids.add(app.pid);
5319                dumpStackTraces(tracesPath, firstPids, null, null, null);
5320            }
5321
5322            File lastTracesFile = null;
5323            File curTracesFile = null;
5324            for (int i=9; i>=0; i--) {
5325                String name = String.format(Locale.US, "slow%02d.txt", i);
5326                curTracesFile = new File(tracesDir, name);
5327                if (curTracesFile.exists()) {
5328                    if (lastTracesFile != null) {
5329                        curTracesFile.renameTo(lastTracesFile);
5330                    } else {
5331                        curTracesFile.delete();
5332                    }
5333                }
5334                lastTracesFile = curTracesFile;
5335            }
5336            tracesFile.renameTo(curTracesFile);
5337            if (tracesTmp.exists()) {
5338                tracesTmp.renameTo(tracesFile);
5339            }
5340        } finally {
5341            StrictMode.setThreadPolicy(oldPolicy);
5342        }
5343    }
5344
5345    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5346        if (!mLaunchWarningShown) {
5347            mLaunchWarningShown = true;
5348            mUiHandler.post(new Runnable() {
5349                @Override
5350                public void run() {
5351                    synchronized (ActivityManagerService.this) {
5352                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5353                        d.show();
5354                        mUiHandler.postDelayed(new Runnable() {
5355                            @Override
5356                            public void run() {
5357                                synchronized (ActivityManagerService.this) {
5358                                    d.dismiss();
5359                                    mLaunchWarningShown = false;
5360                                }
5361                            }
5362                        }, 4000);
5363                    }
5364                }
5365            });
5366        }
5367    }
5368
5369    @Override
5370    public boolean clearApplicationUserData(final String packageName,
5371            final IPackageDataObserver observer, int userId) {
5372        enforceNotIsolatedCaller("clearApplicationUserData");
5373        int uid = Binder.getCallingUid();
5374        int pid = Binder.getCallingPid();
5375        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5376                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5377
5378
5379        long callingId = Binder.clearCallingIdentity();
5380        try {
5381            IPackageManager pm = AppGlobals.getPackageManager();
5382            int pkgUid = -1;
5383            synchronized(this) {
5384                if (getPackageManagerInternalLocked().canPackageBeWiped(
5385                        userId, packageName)) {
5386                    throw new SecurityException(
5387                            "Cannot clear data for a device owner or a profile owner");
5388                }
5389
5390                try {
5391                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5392                } catch (RemoteException e) {
5393                }
5394                if (pkgUid == -1) {
5395                    Slog.w(TAG, "Invalid packageName: " + packageName);
5396                    if (observer != null) {
5397                        try {
5398                            observer.onRemoveCompleted(packageName, false);
5399                        } catch (RemoteException e) {
5400                            Slog.i(TAG, "Observer no longer exists.");
5401                        }
5402                    }
5403                    return false;
5404                }
5405                if (uid == pkgUid || checkComponentPermission(
5406                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5407                        pid, uid, -1, true)
5408                        == PackageManager.PERMISSION_GRANTED) {
5409                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5410                } else {
5411                    throw new SecurityException("PID " + pid + " does not have permission "
5412                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5413                                    + " of package " + packageName);
5414                }
5415
5416                // Remove all tasks match the cleared application package and user
5417                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5418                    final TaskRecord tr = mRecentTasks.get(i);
5419                    final String taskPackageName =
5420                            tr.getBaseIntent().getComponent().getPackageName();
5421                    if (tr.userId != userId) continue;
5422                    if (!taskPackageName.equals(packageName)) continue;
5423                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5424                }
5425            }
5426
5427            final int pkgUidF = pkgUid;
5428            final int userIdF = userId;
5429            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5430                @Override
5431                public void onRemoveCompleted(String packageName, boolean succeeded)
5432                        throws RemoteException {
5433                    synchronized (ActivityManagerService.this) {
5434                        finishForceStopPackageLocked(packageName, pkgUidF);
5435                    }
5436
5437                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5438                            Uri.fromParts("package", packageName, null));
5439                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5440                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5441                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5442                            null, null, 0, null, null, null, null, false, false, userIdF);
5443
5444                    if (observer != null) {
5445                        observer.onRemoveCompleted(packageName, succeeded);
5446                    }
5447                }
5448            };
5449
5450            try {
5451                // Clear application user data
5452                pm.clearApplicationUserData(packageName, localObserver, userId);
5453
5454                synchronized(this) {
5455                    // Remove all permissions granted from/to this package
5456                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5457                }
5458
5459                // Remove all zen rules created by this package; revoke it's zen access.
5460                INotificationManager inm = NotificationManager.getService();
5461                inm.removeAutomaticZenRules(packageName);
5462                inm.setNotificationPolicyAccessGranted(packageName, false);
5463
5464            } catch (RemoteException e) {
5465            }
5466        } finally {
5467            Binder.restoreCallingIdentity(callingId);
5468        }
5469        return true;
5470    }
5471
5472    @Override
5473    public void killBackgroundProcesses(final String packageName, int userId) {
5474        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5475                != PackageManager.PERMISSION_GRANTED &&
5476                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5477                        != PackageManager.PERMISSION_GRANTED) {
5478            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5479                    + Binder.getCallingPid()
5480                    + ", uid=" + Binder.getCallingUid()
5481                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5482            Slog.w(TAG, msg);
5483            throw new SecurityException(msg);
5484        }
5485
5486        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5487                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5488        long callingId = Binder.clearCallingIdentity();
5489        try {
5490            IPackageManager pm = AppGlobals.getPackageManager();
5491            synchronized(this) {
5492                int appId = -1;
5493                try {
5494                    appId = UserHandle.getAppId(
5495                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5496                } catch (RemoteException e) {
5497                }
5498                if (appId == -1) {
5499                    Slog.w(TAG, "Invalid packageName: " + packageName);
5500                    return;
5501                }
5502                killPackageProcessesLocked(packageName, appId, userId,
5503                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5504            }
5505        } finally {
5506            Binder.restoreCallingIdentity(callingId);
5507        }
5508    }
5509
5510    @Override
5511    public void killAllBackgroundProcesses() {
5512        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5513                != PackageManager.PERMISSION_GRANTED) {
5514            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5515                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5516                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5517            Slog.w(TAG, msg);
5518            throw new SecurityException(msg);
5519        }
5520
5521        final long callingId = Binder.clearCallingIdentity();
5522        try {
5523            synchronized (this) {
5524                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5525                final int NP = mProcessNames.getMap().size();
5526                for (int ip = 0; ip < NP; ip++) {
5527                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5528                    final int NA = apps.size();
5529                    for (int ia = 0; ia < NA; ia++) {
5530                        final ProcessRecord app = apps.valueAt(ia);
5531                        if (app.persistent) {
5532                            // We don't kill persistent processes.
5533                            continue;
5534                        }
5535                        if (app.removed) {
5536                            procs.add(app);
5537                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5538                            app.removed = true;
5539                            procs.add(app);
5540                        }
5541                    }
5542                }
5543
5544                final int N = procs.size();
5545                for (int i = 0; i < N; i++) {
5546                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5547                }
5548
5549                mAllowLowerMemLevel = true;
5550
5551                updateOomAdjLocked();
5552                doLowMemReportIfNeededLocked(null);
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(callingId);
5556        }
5557    }
5558
5559    /**
5560     * Kills all background processes, except those matching any of the
5561     * specified properties.
5562     *
5563     * @param minTargetSdk the target SDK version at or above which to preserve
5564     *                     processes, or {@code -1} to ignore the target SDK
5565     * @param maxProcState the process state at or below which to preserve
5566     *                     processes, or {@code -1} to ignore the process state
5567     */
5568    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5569        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5570                != PackageManager.PERMISSION_GRANTED) {
5571            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5572                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5573                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5574            Slog.w(TAG, msg);
5575            throw new SecurityException(msg);
5576        }
5577
5578        final long callingId = Binder.clearCallingIdentity();
5579        try {
5580            synchronized (this) {
5581                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5582                final int NP = mProcessNames.getMap().size();
5583                for (int ip = 0; ip < NP; ip++) {
5584                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5585                    final int NA = apps.size();
5586                    for (int ia = 0; ia < NA; ia++) {
5587                        final ProcessRecord app = apps.valueAt(ia);
5588                        if (app.removed) {
5589                            procs.add(app);
5590                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5591                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5592                            app.removed = true;
5593                            procs.add(app);
5594                        }
5595                    }
5596                }
5597
5598                final int N = procs.size();
5599                for (int i = 0; i < N; i++) {
5600                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5601                }
5602            }
5603        } finally {
5604            Binder.restoreCallingIdentity(callingId);
5605        }
5606    }
5607
5608    @Override
5609    public void forceStopPackage(final String packageName, int userId) {
5610        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5611                != PackageManager.PERMISSION_GRANTED) {
5612            String msg = "Permission Denial: forceStopPackage() from pid="
5613                    + Binder.getCallingPid()
5614                    + ", uid=" + Binder.getCallingUid()
5615                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5616            Slog.w(TAG, msg);
5617            throw new SecurityException(msg);
5618        }
5619        final int callingPid = Binder.getCallingPid();
5620        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5621                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5622        long callingId = Binder.clearCallingIdentity();
5623        try {
5624            IPackageManager pm = AppGlobals.getPackageManager();
5625            synchronized(this) {
5626                int[] users = userId == UserHandle.USER_ALL
5627                        ? mUserController.getUsers() : new int[] { userId };
5628                for (int user : users) {
5629                    int pkgUid = -1;
5630                    try {
5631                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5632                                user);
5633                    } catch (RemoteException e) {
5634                    }
5635                    if (pkgUid == -1) {
5636                        Slog.w(TAG, "Invalid packageName: " + packageName);
5637                        continue;
5638                    }
5639                    try {
5640                        pm.setPackageStoppedState(packageName, true, user);
5641                    } catch (RemoteException e) {
5642                    } catch (IllegalArgumentException e) {
5643                        Slog.w(TAG, "Failed trying to unstop package "
5644                                + packageName + ": " + e);
5645                    }
5646                    if (mUserController.isUserRunningLocked(user, 0)) {
5647                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5648                        finishForceStopPackageLocked(packageName, pkgUid);
5649                    }
5650                }
5651            }
5652        } finally {
5653            Binder.restoreCallingIdentity(callingId);
5654        }
5655    }
5656
5657    @Override
5658    public void addPackageDependency(String packageName) {
5659        synchronized (this) {
5660            int callingPid = Binder.getCallingPid();
5661            if (callingPid == Process.myPid()) {
5662                //  Yeah, um, no.
5663                return;
5664            }
5665            ProcessRecord proc;
5666            synchronized (mPidsSelfLocked) {
5667                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5668            }
5669            if (proc != null) {
5670                if (proc.pkgDeps == null) {
5671                    proc.pkgDeps = new ArraySet<String>(1);
5672                }
5673                proc.pkgDeps.add(packageName);
5674            }
5675        }
5676    }
5677
5678    /*
5679     * The pkg name and app id have to be specified.
5680     */
5681    @Override
5682    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5683        if (pkg == null) {
5684            return;
5685        }
5686        // Make sure the uid is valid.
5687        if (appid < 0) {
5688            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5689            return;
5690        }
5691        int callerUid = Binder.getCallingUid();
5692        // Only the system server can kill an application
5693        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5694            // Post an aysnc message to kill the application
5695            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5696            msg.arg1 = appid;
5697            msg.arg2 = 0;
5698            Bundle bundle = new Bundle();
5699            bundle.putString("pkg", pkg);
5700            bundle.putString("reason", reason);
5701            msg.obj = bundle;
5702            mHandler.sendMessage(msg);
5703        } else {
5704            throw new SecurityException(callerUid + " cannot kill pkg: " +
5705                    pkg);
5706        }
5707    }
5708
5709    @Override
5710    public void closeSystemDialogs(String reason) {
5711        enforceNotIsolatedCaller("closeSystemDialogs");
5712
5713        final int pid = Binder.getCallingPid();
5714        final int uid = Binder.getCallingUid();
5715        final long origId = Binder.clearCallingIdentity();
5716        try {
5717            synchronized (this) {
5718                // Only allow this from foreground processes, so that background
5719                // applications can't abuse it to prevent system UI from being shown.
5720                if (uid >= Process.FIRST_APPLICATION_UID) {
5721                    ProcessRecord proc;
5722                    synchronized (mPidsSelfLocked) {
5723                        proc = mPidsSelfLocked.get(pid);
5724                    }
5725                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5726                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5727                                + " from background process " + proc);
5728                        return;
5729                    }
5730                }
5731                closeSystemDialogsLocked(reason);
5732            }
5733        } finally {
5734            Binder.restoreCallingIdentity(origId);
5735        }
5736    }
5737
5738    void closeSystemDialogsLocked(String reason) {
5739        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5740        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5741                | Intent.FLAG_RECEIVER_FOREGROUND);
5742        if (reason != null) {
5743            intent.putExtra("reason", reason);
5744        }
5745        mWindowManager.closeSystemDialogs(reason);
5746
5747        mStackSupervisor.closeSystemDialogsLocked();
5748
5749        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5750                AppOpsManager.OP_NONE, null, false, false,
5751                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5752    }
5753
5754    @Override
5755    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5756        enforceNotIsolatedCaller("getProcessMemoryInfo");
5757        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5758        for (int i=pids.length-1; i>=0; i--) {
5759            ProcessRecord proc;
5760            int oomAdj;
5761            synchronized (this) {
5762                synchronized (mPidsSelfLocked) {
5763                    proc = mPidsSelfLocked.get(pids[i]);
5764                    oomAdj = proc != null ? proc.setAdj : 0;
5765                }
5766            }
5767            infos[i] = new Debug.MemoryInfo();
5768            Debug.getMemoryInfo(pids[i], infos[i]);
5769            if (proc != null) {
5770                synchronized (this) {
5771                    if (proc.thread != null && proc.setAdj == oomAdj) {
5772                        // Record this for posterity if the process has been stable.
5773                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5774                                infos[i].getTotalUss(), false, proc.pkgList);
5775                    }
5776                }
5777            }
5778        }
5779        return infos;
5780    }
5781
5782    @Override
5783    public long[] getProcessPss(int[] pids) {
5784        enforceNotIsolatedCaller("getProcessPss");
5785        long[] pss = new long[pids.length];
5786        for (int i=pids.length-1; i>=0; i--) {
5787            ProcessRecord proc;
5788            int oomAdj;
5789            synchronized (this) {
5790                synchronized (mPidsSelfLocked) {
5791                    proc = mPidsSelfLocked.get(pids[i]);
5792                    oomAdj = proc != null ? proc.setAdj : 0;
5793                }
5794            }
5795            long[] tmpUss = new long[1];
5796            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5797            if (proc != null) {
5798                synchronized (this) {
5799                    if (proc.thread != null && proc.setAdj == oomAdj) {
5800                        // Record this for posterity if the process has been stable.
5801                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5802                    }
5803                }
5804            }
5805        }
5806        return pss;
5807    }
5808
5809    @Override
5810    public void killApplicationProcess(String processName, int uid) {
5811        if (processName == null) {
5812            return;
5813        }
5814
5815        int callerUid = Binder.getCallingUid();
5816        // Only the system server can kill an application
5817        if (callerUid == Process.SYSTEM_UID) {
5818            synchronized (this) {
5819                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5820                if (app != null && app.thread != null) {
5821                    try {
5822                        app.thread.scheduleSuicide();
5823                    } catch (RemoteException e) {
5824                        // If the other end already died, then our work here is done.
5825                    }
5826                } else {
5827                    Slog.w(TAG, "Process/uid not found attempting kill of "
5828                            + processName + " / " + uid);
5829                }
5830            }
5831        } else {
5832            throw new SecurityException(callerUid + " cannot kill app process: " +
5833                    processName);
5834        }
5835    }
5836
5837    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5838        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5839                false, true, false, false, UserHandle.getUserId(uid), reason);
5840    }
5841
5842    private void finishForceStopPackageLocked(final String packageName, int uid) {
5843        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5844                Uri.fromParts("package", packageName, null));
5845        if (!mProcessesReady) {
5846            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5847                    | Intent.FLAG_RECEIVER_FOREGROUND);
5848        }
5849        intent.putExtra(Intent.EXTRA_UID, uid);
5850        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5851        broadcastIntentLocked(null, null, intent,
5852                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5853                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5854    }
5855
5856
5857    private final boolean killPackageProcessesLocked(String packageName, int appId,
5858            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5859            boolean doit, boolean evenPersistent, String reason) {
5860        ArrayList<ProcessRecord> procs = new ArrayList<>();
5861
5862        // Remove all processes this package may have touched: all with the
5863        // same UID (except for the system or root user), and all whose name
5864        // matches the package name.
5865        final int NP = mProcessNames.getMap().size();
5866        for (int ip=0; ip<NP; ip++) {
5867            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5868            final int NA = apps.size();
5869            for (int ia=0; ia<NA; ia++) {
5870                ProcessRecord app = apps.valueAt(ia);
5871                if (app.persistent && !evenPersistent) {
5872                    // we don't kill persistent processes
5873                    continue;
5874                }
5875                if (app.removed) {
5876                    if (doit) {
5877                        procs.add(app);
5878                    }
5879                    continue;
5880                }
5881
5882                // Skip process if it doesn't meet our oom adj requirement.
5883                if (app.setAdj < minOomAdj) {
5884                    continue;
5885                }
5886
5887                // If no package is specified, we call all processes under the
5888                // give user id.
5889                if (packageName == null) {
5890                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5891                        continue;
5892                    }
5893                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5894                        continue;
5895                    }
5896                // Package has been specified, we want to hit all processes
5897                // that match it.  We need to qualify this by the processes
5898                // that are running under the specified app and user ID.
5899                } else {
5900                    final boolean isDep = app.pkgDeps != null
5901                            && app.pkgDeps.contains(packageName);
5902                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5903                        continue;
5904                    }
5905                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5906                        continue;
5907                    }
5908                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5909                        continue;
5910                    }
5911                }
5912
5913                // Process has passed all conditions, kill it!
5914                if (!doit) {
5915                    return true;
5916                }
5917                app.removed = true;
5918                procs.add(app);
5919            }
5920        }
5921
5922        int N = procs.size();
5923        for (int i=0; i<N; i++) {
5924            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5925        }
5926        updateOomAdjLocked();
5927        return N > 0;
5928    }
5929
5930    private void cleanupDisabledPackageComponentsLocked(
5931            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5932
5933        Set<String> disabledClasses = null;
5934        boolean packageDisabled = false;
5935        IPackageManager pm = AppGlobals.getPackageManager();
5936
5937        if (changedClasses == null) {
5938            // Nothing changed...
5939            return;
5940        }
5941
5942        // Determine enable/disable state of the package and its components.
5943        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5944        for (int i = changedClasses.length - 1; i >= 0; i--) {
5945            final String changedClass = changedClasses[i];
5946
5947            if (changedClass.equals(packageName)) {
5948                try {
5949                    // Entire package setting changed
5950                    enabled = pm.getApplicationEnabledSetting(packageName,
5951                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5952                } catch (Exception e) {
5953                    // No such package/component; probably racing with uninstall.  In any
5954                    // event it means we have nothing further to do here.
5955                    return;
5956                }
5957                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5958                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5959                if (packageDisabled) {
5960                    // Entire package is disabled.
5961                    // No need to continue to check component states.
5962                    disabledClasses = null;
5963                    break;
5964                }
5965            } else {
5966                try {
5967                    enabled = pm.getComponentEnabledSetting(
5968                            new ComponentName(packageName, changedClass),
5969                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5970                } catch (Exception e) {
5971                    // As above, probably racing with uninstall.
5972                    return;
5973                }
5974                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5975                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5976                    if (disabledClasses == null) {
5977                        disabledClasses = new ArraySet<>(changedClasses.length);
5978                    }
5979                    disabledClasses.add(changedClass);
5980                }
5981            }
5982        }
5983
5984        if (!packageDisabled && disabledClasses == null) {
5985            // Nothing to do here...
5986            return;
5987        }
5988
5989        // Clean-up disabled activities.
5990        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5991                packageName, disabledClasses, true, false, userId) && mBooted) {
5992            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5993            mStackSupervisor.scheduleIdleLocked();
5994        }
5995
5996        // Clean-up disabled tasks
5997        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5998
5999        // Clean-up disabled services.
6000        mServices.bringDownDisabledPackageServicesLocked(
6001                packageName, disabledClasses, userId, false, killProcess, true);
6002
6003        // Clean-up disabled providers.
6004        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6005        mProviderMap.collectPackageProvidersLocked(
6006                packageName, disabledClasses, true, false, userId, providers);
6007        for (int i = providers.size() - 1; i >= 0; i--) {
6008            removeDyingProviderLocked(null, providers.get(i), true);
6009        }
6010
6011        // Clean-up disabled broadcast receivers.
6012        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6013            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6014                    packageName, disabledClasses, userId, true);
6015        }
6016
6017    }
6018
6019    final boolean clearBroadcastQueueForUserLocked(int userId) {
6020        boolean didSomething = false;
6021        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6022            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6023                    null, null, userId, true);
6024        }
6025        return didSomething;
6026    }
6027
6028    final boolean forceStopPackageLocked(String packageName, int appId,
6029            boolean callerWillRestart, boolean purgeCache, boolean doit,
6030            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6031        int i;
6032
6033        if (userId == UserHandle.USER_ALL && packageName == null) {
6034            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6035        }
6036
6037        if (appId < 0 && packageName != null) {
6038            try {
6039                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6040                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6041            } catch (RemoteException e) {
6042            }
6043        }
6044
6045        if (doit) {
6046            if (packageName != null) {
6047                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6048                        + " user=" + userId + ": " + reason);
6049            } else {
6050                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6051            }
6052
6053            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6054        }
6055
6056        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6057                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6058                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6059
6060        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6061                packageName, null, doit, evenPersistent, userId)) {
6062            if (!doit) {
6063                return true;
6064            }
6065            didSomething = true;
6066        }
6067
6068        if (mServices.bringDownDisabledPackageServicesLocked(
6069                packageName, null, userId, evenPersistent, true, doit)) {
6070            if (!doit) {
6071                return true;
6072            }
6073            didSomething = true;
6074        }
6075
6076        if (packageName == null) {
6077            // Remove all sticky broadcasts from this user.
6078            mStickyBroadcasts.remove(userId);
6079        }
6080
6081        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6082        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6083                userId, providers)) {
6084            if (!doit) {
6085                return true;
6086            }
6087            didSomething = true;
6088        }
6089        for (i = providers.size() - 1; i >= 0; i--) {
6090            removeDyingProviderLocked(null, providers.get(i), true);
6091        }
6092
6093        // Remove transient permissions granted from/to this package/user
6094        removeUriPermissionsForPackageLocked(packageName, userId, false);
6095
6096        if (doit) {
6097            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6098                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6099                        packageName, null, userId, doit);
6100            }
6101        }
6102
6103        if (packageName == null || uninstalling) {
6104            // Remove pending intents.  For now we only do this when force
6105            // stopping users, because we have some problems when doing this
6106            // for packages -- app widgets are not currently cleaned up for
6107            // such packages, so they can be left with bad pending intents.
6108            if (mIntentSenderRecords.size() > 0) {
6109                Iterator<WeakReference<PendingIntentRecord>> it
6110                        = mIntentSenderRecords.values().iterator();
6111                while (it.hasNext()) {
6112                    WeakReference<PendingIntentRecord> wpir = it.next();
6113                    if (wpir == null) {
6114                        it.remove();
6115                        continue;
6116                    }
6117                    PendingIntentRecord pir = wpir.get();
6118                    if (pir == null) {
6119                        it.remove();
6120                        continue;
6121                    }
6122                    if (packageName == null) {
6123                        // Stopping user, remove all objects for the user.
6124                        if (pir.key.userId != userId) {
6125                            // Not the same user, skip it.
6126                            continue;
6127                        }
6128                    } else {
6129                        if (UserHandle.getAppId(pir.uid) != appId) {
6130                            // Different app id, skip it.
6131                            continue;
6132                        }
6133                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6134                            // Different user, skip it.
6135                            continue;
6136                        }
6137                        if (!pir.key.packageName.equals(packageName)) {
6138                            // Different package, skip it.
6139                            continue;
6140                        }
6141                    }
6142                    if (!doit) {
6143                        return true;
6144                    }
6145                    didSomething = true;
6146                    it.remove();
6147                    pir.canceled = true;
6148                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6149                        pir.key.activity.pendingResults.remove(pir.ref);
6150                    }
6151                }
6152            }
6153        }
6154
6155        if (doit) {
6156            if (purgeCache && packageName != null) {
6157                AttributeCache ac = AttributeCache.instance();
6158                if (ac != null) {
6159                    ac.removePackage(packageName);
6160                }
6161            }
6162            if (mBooted) {
6163                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6164                mStackSupervisor.scheduleIdleLocked();
6165            }
6166        }
6167
6168        return didSomething;
6169    }
6170
6171    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6172        ProcessRecord old = mProcessNames.remove(name, uid);
6173        if (old != null) {
6174            old.uidRecord.numProcs--;
6175            if (old.uidRecord.numProcs == 0) {
6176                // No more processes using this uid, tell clients it is gone.
6177                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6178                        "No more processes in " + old.uidRecord);
6179                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6180                mActiveUids.remove(uid);
6181                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6182            }
6183            old.uidRecord = null;
6184        }
6185        mIsolatedProcesses.remove(uid);
6186        return old;
6187    }
6188
6189    private final void addProcessNameLocked(ProcessRecord proc) {
6190        // We shouldn't already have a process under this name, but just in case we
6191        // need to clean up whatever may be there now.
6192        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6193        if (old == proc && proc.persistent) {
6194            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6195            Slog.w(TAG, "Re-adding persistent process " + proc);
6196        } else if (old != null) {
6197            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6198        }
6199        UidRecord uidRec = mActiveUids.get(proc.uid);
6200        if (uidRec == null) {
6201            uidRec = new UidRecord(proc.uid);
6202            // This is the first appearance of the uid, report it now!
6203            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6204                    "Creating new process uid: " + uidRec);
6205            mActiveUids.put(proc.uid, uidRec);
6206            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6207            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6208        }
6209        proc.uidRecord = uidRec;
6210        uidRec.numProcs++;
6211        mProcessNames.put(proc.processName, proc.uid, proc);
6212        if (proc.isolated) {
6213            mIsolatedProcesses.put(proc.uid, proc);
6214        }
6215    }
6216
6217    boolean removeProcessLocked(ProcessRecord app,
6218            boolean callerWillRestart, boolean allowRestart, String reason) {
6219        final String name = app.processName;
6220        final int uid = app.uid;
6221        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6222            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6223
6224        ProcessRecord old = mProcessNames.get(name, uid);
6225        if (old != app) {
6226            // This process is no longer active, so nothing to do.
6227            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6228            return false;
6229        }
6230        removeProcessNameLocked(name, uid);
6231        if (mHeavyWeightProcess == app) {
6232            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6233                    mHeavyWeightProcess.userId, 0));
6234            mHeavyWeightProcess = null;
6235        }
6236        boolean needRestart = false;
6237        if (app.pid > 0 && app.pid != MY_PID) {
6238            int pid = app.pid;
6239            synchronized (mPidsSelfLocked) {
6240                mPidsSelfLocked.remove(pid);
6241                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6242            }
6243            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6244            if (app.isolated) {
6245                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6246            }
6247            boolean willRestart = false;
6248            if (app.persistent && !app.isolated) {
6249                if (!callerWillRestart) {
6250                    willRestart = true;
6251                } else {
6252                    needRestart = true;
6253                }
6254            }
6255            app.kill(reason, true);
6256            handleAppDiedLocked(app, willRestart, allowRestart);
6257            if (willRestart) {
6258                removeLruProcessLocked(app);
6259                addAppLocked(app.info, false, null /* ABI override */);
6260            }
6261        } else {
6262            mRemovedProcesses.add(app);
6263        }
6264
6265        return needRestart;
6266    }
6267
6268    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6269        cleanupAppInLaunchingProvidersLocked(app, true);
6270        removeProcessLocked(app, false, true, "timeout publishing content providers");
6271    }
6272
6273    private final void processStartTimedOutLocked(ProcessRecord app) {
6274        final int pid = app.pid;
6275        boolean gone = false;
6276        synchronized (mPidsSelfLocked) {
6277            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6278            if (knownApp != null && knownApp.thread == null) {
6279                mPidsSelfLocked.remove(pid);
6280                gone = true;
6281            }
6282        }
6283
6284        if (gone) {
6285            Slog.w(TAG, "Process " + app + " failed to attach");
6286            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6287                    pid, app.uid, app.processName);
6288            removeProcessNameLocked(app.processName, app.uid);
6289            if (mHeavyWeightProcess == app) {
6290                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6291                        mHeavyWeightProcess.userId, 0));
6292                mHeavyWeightProcess = null;
6293            }
6294            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6295            if (app.isolated) {
6296                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6297            }
6298            // Take care of any launching providers waiting for this process.
6299            cleanupAppInLaunchingProvidersLocked(app, true);
6300            // Take care of any services that are waiting for the process.
6301            mServices.processStartTimedOutLocked(app);
6302            app.kill("start timeout", true);
6303            removeLruProcessLocked(app);
6304            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6305                Slog.w(TAG, "Unattached app died before backup, skipping");
6306                try {
6307                    IBackupManager bm = IBackupManager.Stub.asInterface(
6308                            ServiceManager.getService(Context.BACKUP_SERVICE));
6309                    bm.agentDisconnected(app.info.packageName);
6310                } catch (RemoteException e) {
6311                    // Can't happen; the backup manager is local
6312                }
6313            }
6314            if (isPendingBroadcastProcessLocked(pid)) {
6315                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6316                skipPendingBroadcastLocked(pid);
6317            }
6318        } else {
6319            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6320        }
6321    }
6322
6323    private final boolean attachApplicationLocked(IApplicationThread thread,
6324            int pid) {
6325
6326        // Find the application record that is being attached...  either via
6327        // the pid if we are running in multiple processes, or just pull the
6328        // next app record if we are emulating process with anonymous threads.
6329        ProcessRecord app;
6330        if (pid != MY_PID && pid >= 0) {
6331            synchronized (mPidsSelfLocked) {
6332                app = mPidsSelfLocked.get(pid);
6333            }
6334        } else {
6335            app = null;
6336        }
6337
6338        if (app == null) {
6339            Slog.w(TAG, "No pending application record for pid " + pid
6340                    + " (IApplicationThread " + thread + "); dropping process");
6341            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6342            if (pid > 0 && pid != MY_PID) {
6343                Process.killProcessQuiet(pid);
6344                //TODO: killProcessGroup(app.info.uid, pid);
6345            } else {
6346                try {
6347                    thread.scheduleExit();
6348                } catch (Exception e) {
6349                    // Ignore exceptions.
6350                }
6351            }
6352            return false;
6353        }
6354
6355        // If this application record is still attached to a previous
6356        // process, clean it up now.
6357        if (app.thread != null) {
6358            handleAppDiedLocked(app, true, true);
6359        }
6360
6361        // Tell the process all about itself.
6362
6363        if (DEBUG_ALL) Slog.v(
6364                TAG, "Binding process pid " + pid + " to record " + app);
6365
6366        final String processName = app.processName;
6367        try {
6368            AppDeathRecipient adr = new AppDeathRecipient(
6369                    app, pid, thread);
6370            thread.asBinder().linkToDeath(adr, 0);
6371            app.deathRecipient = adr;
6372        } catch (RemoteException e) {
6373            app.resetPackageList(mProcessStats);
6374            startProcessLocked(app, "link fail", processName);
6375            return false;
6376        }
6377
6378        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6379
6380        app.makeActive(thread, mProcessStats);
6381        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6382        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6383        app.forcingToForeground = null;
6384        updateProcessForegroundLocked(app, false, false);
6385        app.hasShownUi = false;
6386        app.debugging = false;
6387        app.cached = false;
6388        app.killedByAm = false;
6389
6390        // We carefully use the same state that PackageManager uses for
6391        // filtering, since we use this flag to decide if we need to install
6392        // providers when user is unlocked later
6393        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6394
6395        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6396
6397        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6398        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6399
6400        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6401            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6402            msg.obj = app;
6403            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6404        }
6405
6406        if (!normalMode) {
6407            Slog.i(TAG, "Launching preboot mode app: " + app);
6408        }
6409
6410        if (DEBUG_ALL) Slog.v(
6411            TAG, "New app record " + app
6412            + " thread=" + thread.asBinder() + " pid=" + pid);
6413        try {
6414            int testMode = IApplicationThread.DEBUG_OFF;
6415            if (mDebugApp != null && mDebugApp.equals(processName)) {
6416                testMode = mWaitForDebugger
6417                    ? IApplicationThread.DEBUG_WAIT
6418                    : IApplicationThread.DEBUG_ON;
6419                app.debugging = true;
6420                if (mDebugTransient) {
6421                    mDebugApp = mOrigDebugApp;
6422                    mWaitForDebugger = mOrigWaitForDebugger;
6423                }
6424            }
6425            String profileFile = app.instrumentationProfileFile;
6426            ParcelFileDescriptor profileFd = null;
6427            int samplingInterval = 0;
6428            boolean profileAutoStop = false;
6429            if (mProfileApp != null && mProfileApp.equals(processName)) {
6430                mProfileProc = app;
6431                profileFile = mProfileFile;
6432                profileFd = mProfileFd;
6433                samplingInterval = mSamplingInterval;
6434                profileAutoStop = mAutoStopProfiler;
6435            }
6436            boolean enableTrackAllocation = false;
6437            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6438                enableTrackAllocation = true;
6439                mTrackAllocationApp = null;
6440            }
6441
6442            // If the app is being launched for restore or full backup, set it up specially
6443            boolean isRestrictedBackupMode = false;
6444            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6445                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6446                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6447                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6448                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6449            }
6450
6451            if (app.instrumentationClass != null) {
6452                notifyPackageUse(app.instrumentationClass.getPackageName(),
6453                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6454            }
6455            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6456                    + processName + " with config " + mConfiguration);
6457            ApplicationInfo appInfo = app.instrumentationInfo != null
6458                    ? app.instrumentationInfo : app.info;
6459            app.compat = compatibilityInfoForPackageLocked(appInfo);
6460            if (profileFd != null) {
6461                profileFd = profileFd.dup();
6462            }
6463            ProfilerInfo profilerInfo = profileFile == null ? null
6464                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6465            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6466                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6467                    app.instrumentationUiAutomationConnection, testMode,
6468                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6469                    isRestrictedBackupMode || !normalMode, app.persistent,
6470                    new Configuration(mConfiguration), app.compat,
6471                    getCommonServicesLocked(app.isolated),
6472                    mCoreSettingsObserver.getCoreSettingsLocked());
6473            updateLruProcessLocked(app, false, null);
6474            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6475        } catch (Exception e) {
6476            // todo: Yikes!  What should we do?  For now we will try to
6477            // start another process, but that could easily get us in
6478            // an infinite loop of restarting processes...
6479            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6480
6481            app.resetPackageList(mProcessStats);
6482            app.unlinkDeathRecipient();
6483            startProcessLocked(app, "bind fail", processName);
6484            return false;
6485        }
6486
6487        // Remove this record from the list of starting applications.
6488        mPersistentStartingProcesses.remove(app);
6489        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6490                "Attach application locked removing on hold: " + app);
6491        mProcessesOnHold.remove(app);
6492
6493        boolean badApp = false;
6494        boolean didSomething = false;
6495
6496        // See if the top visible activity is waiting to run in this process...
6497        if (normalMode) {
6498            try {
6499                if (mStackSupervisor.attachApplicationLocked(app)) {
6500                    didSomething = true;
6501                }
6502            } catch (Exception e) {
6503                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6504                badApp = true;
6505            }
6506        }
6507
6508        // Find any services that should be running in this process...
6509        if (!badApp) {
6510            try {
6511                didSomething |= mServices.attachApplicationLocked(app, processName);
6512            } catch (Exception e) {
6513                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6514                badApp = true;
6515            }
6516        }
6517
6518        // Check if a next-broadcast receiver is in this process...
6519        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6520            try {
6521                didSomething |= sendPendingBroadcastsLocked(app);
6522            } catch (Exception e) {
6523                // If the app died trying to launch the receiver we declare it 'bad'
6524                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6525                badApp = true;
6526            }
6527        }
6528
6529        // Check whether the next backup agent is in this process...
6530        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6531            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6532                    "New app is backup target, launching agent for " + app);
6533            notifyPackageUse(mBackupTarget.appInfo.packageName,
6534                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6535            try {
6536                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6537                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6538                        mBackupTarget.backupMode);
6539            } catch (Exception e) {
6540                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6541                badApp = true;
6542            }
6543        }
6544
6545        if (badApp) {
6546            app.kill("error during init", true);
6547            handleAppDiedLocked(app, false, true);
6548            return false;
6549        }
6550
6551        if (!didSomething) {
6552            updateOomAdjLocked();
6553        }
6554
6555        return true;
6556    }
6557
6558    @Override
6559    public final void attachApplication(IApplicationThread thread) {
6560        synchronized (this) {
6561            int callingPid = Binder.getCallingPid();
6562            final long origId = Binder.clearCallingIdentity();
6563            attachApplicationLocked(thread, callingPid);
6564            Binder.restoreCallingIdentity(origId);
6565        }
6566    }
6567
6568    @Override
6569    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6570        final long origId = Binder.clearCallingIdentity();
6571        synchronized (this) {
6572            ActivityStack stack = ActivityRecord.getStackLocked(token);
6573            if (stack != null) {
6574                ActivityRecord r =
6575                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6576                if (stopProfiling) {
6577                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6578                        try {
6579                            mProfileFd.close();
6580                        } catch (IOException e) {
6581                        }
6582                        clearProfilerLocked();
6583                    }
6584                }
6585            }
6586        }
6587        Binder.restoreCallingIdentity(origId);
6588    }
6589
6590    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6591        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6592                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6593    }
6594
6595    void enableScreenAfterBoot() {
6596        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6597                SystemClock.uptimeMillis());
6598        mWindowManager.enableScreenAfterBoot();
6599
6600        synchronized (this) {
6601            updateEventDispatchingLocked();
6602        }
6603    }
6604
6605    @Override
6606    public void showBootMessage(final CharSequence msg, final boolean always) {
6607        if (Binder.getCallingUid() != Process.myUid()) {
6608            // These days only the core system can call this, so apps can't get in
6609            // the way of what we show about running them.
6610        }
6611        mWindowManager.showBootMessage(msg, always);
6612    }
6613
6614    @Override
6615    public void keyguardWaitingForActivityDrawn() {
6616        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6617        final long token = Binder.clearCallingIdentity();
6618        try {
6619            synchronized (this) {
6620                if (DEBUG_LOCKSCREEN) logLockScreen("");
6621                mWindowManager.keyguardWaitingForActivityDrawn();
6622                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6623                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6624                    updateSleepIfNeededLocked();
6625                }
6626            }
6627        } finally {
6628            Binder.restoreCallingIdentity(token);
6629        }
6630    }
6631
6632    @Override
6633    public void keyguardGoingAway(int flags) {
6634        enforceNotIsolatedCaller("keyguardGoingAway");
6635        final long token = Binder.clearCallingIdentity();
6636        try {
6637            synchronized (this) {
6638                if (DEBUG_LOCKSCREEN) logLockScreen("");
6639                mWindowManager.keyguardGoingAway(flags);
6640                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6641                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6642                    updateSleepIfNeededLocked();
6643
6644                    // Some stack visibility might change (e.g. docked stack)
6645                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6646                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6647                }
6648            }
6649        } finally {
6650            Binder.restoreCallingIdentity(token);
6651        }
6652    }
6653
6654    final void finishBooting() {
6655        synchronized (this) {
6656            if (!mBootAnimationComplete) {
6657                mCallFinishBooting = true;
6658                return;
6659            }
6660            mCallFinishBooting = false;
6661        }
6662
6663        ArraySet<String> completedIsas = new ArraySet<String>();
6664        for (String abi : Build.SUPPORTED_ABIS) {
6665            Process.establishZygoteConnectionForAbi(abi);
6666            final String instructionSet = VMRuntime.getInstructionSet(abi);
6667            if (!completedIsas.contains(instructionSet)) {
6668                try {
6669                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6670                } catch (InstallerException e) {
6671                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6672                            e.getMessage() +")");
6673                }
6674                completedIsas.add(instructionSet);
6675            }
6676        }
6677
6678        IntentFilter pkgFilter = new IntentFilter();
6679        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6680        pkgFilter.addDataScheme("package");
6681        mContext.registerReceiver(new BroadcastReceiver() {
6682            @Override
6683            public void onReceive(Context context, Intent intent) {
6684                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6685                if (pkgs != null) {
6686                    for (String pkg : pkgs) {
6687                        synchronized (ActivityManagerService.this) {
6688                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6689                                    0, "query restart")) {
6690                                setResultCode(Activity.RESULT_OK);
6691                                return;
6692                            }
6693                        }
6694                    }
6695                }
6696            }
6697        }, pkgFilter);
6698
6699        IntentFilter dumpheapFilter = new IntentFilter();
6700        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6701        mContext.registerReceiver(new BroadcastReceiver() {
6702            @Override
6703            public void onReceive(Context context, Intent intent) {
6704                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6705                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6706                } else {
6707                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6708                }
6709            }
6710        }, dumpheapFilter);
6711
6712        // Let system services know.
6713        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6714
6715        synchronized (this) {
6716            // Ensure that any processes we had put on hold are now started
6717            // up.
6718            final int NP = mProcessesOnHold.size();
6719            if (NP > 0) {
6720                ArrayList<ProcessRecord> procs =
6721                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6722                for (int ip=0; ip<NP; ip++) {
6723                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6724                            + procs.get(ip));
6725                    startProcessLocked(procs.get(ip), "on-hold", null);
6726                }
6727            }
6728
6729            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6730                // Start looking for apps that are abusing wake locks.
6731                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6732                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6733                // Tell anyone interested that we are done booting!
6734                SystemProperties.set("sys.boot_completed", "1");
6735
6736                // And trigger dev.bootcomplete if we are not showing encryption progress
6737                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6738                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6739                    SystemProperties.set("dev.bootcomplete", "1");
6740                }
6741                mUserController.sendBootCompletedLocked(
6742                        new IIntentReceiver.Stub() {
6743                            @Override
6744                            public void performReceive(Intent intent, int resultCode,
6745                                    String data, Bundle extras, boolean ordered,
6746                                    boolean sticky, int sendingUser) {
6747                                synchronized (ActivityManagerService.this) {
6748                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6749                                            true, false);
6750                                }
6751                            }
6752                        });
6753                scheduleStartProfilesLocked();
6754            }
6755        }
6756    }
6757
6758    @Override
6759    public void bootAnimationComplete() {
6760        final boolean callFinishBooting;
6761        synchronized (this) {
6762            callFinishBooting = mCallFinishBooting;
6763            mBootAnimationComplete = true;
6764        }
6765        if (callFinishBooting) {
6766            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6767            finishBooting();
6768            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6769        }
6770    }
6771
6772    final void ensureBootCompleted() {
6773        boolean booting;
6774        boolean enableScreen;
6775        synchronized (this) {
6776            booting = mBooting;
6777            mBooting = false;
6778            enableScreen = !mBooted;
6779            mBooted = true;
6780        }
6781
6782        if (booting) {
6783            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6784            finishBooting();
6785            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6786        }
6787
6788        if (enableScreen) {
6789            enableScreenAfterBoot();
6790        }
6791    }
6792
6793    @Override
6794    public final void activityResumed(IBinder token) {
6795        final long origId = Binder.clearCallingIdentity();
6796        synchronized(this) {
6797            ActivityStack stack = ActivityRecord.getStackLocked(token);
6798            if (stack != null) {
6799                stack.activityResumedLocked(token);
6800            }
6801        }
6802        Binder.restoreCallingIdentity(origId);
6803    }
6804
6805    @Override
6806    public final void activityPaused(IBinder token) {
6807        final long origId = Binder.clearCallingIdentity();
6808        synchronized(this) {
6809            ActivityStack stack = ActivityRecord.getStackLocked(token);
6810            if (stack != null) {
6811                stack.activityPausedLocked(token, false);
6812            }
6813        }
6814        Binder.restoreCallingIdentity(origId);
6815    }
6816
6817    @Override
6818    public final void activityStopped(IBinder token, Bundle icicle,
6819            PersistableBundle persistentState, CharSequence description) {
6820        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6821
6822        // Refuse possible leaked file descriptors
6823        if (icicle != null && icicle.hasFileDescriptors()) {
6824            throw new IllegalArgumentException("File descriptors passed in Bundle");
6825        }
6826
6827        final long origId = Binder.clearCallingIdentity();
6828
6829        synchronized (this) {
6830            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6831            if (r != null) {
6832                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6833            }
6834        }
6835
6836        trimApplications();
6837
6838        Binder.restoreCallingIdentity(origId);
6839    }
6840
6841    @Override
6842    public final void activityDestroyed(IBinder token) {
6843        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6844        synchronized (this) {
6845            ActivityStack stack = ActivityRecord.getStackLocked(token);
6846            if (stack != null) {
6847                stack.activityDestroyedLocked(token, "activityDestroyed");
6848            }
6849        }
6850    }
6851
6852    @Override
6853    public final void activityRelaunched(IBinder token) {
6854        final long origId = Binder.clearCallingIdentity();
6855        synchronized (this) {
6856            mStackSupervisor.activityRelaunchedLocked(token);
6857        }
6858        Binder.restoreCallingIdentity(origId);
6859    }
6860
6861    @Override
6862    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6863            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6864        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6865                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6866        synchronized (this) {
6867            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6868            if (record == null) {
6869                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6870                        + "found for: " + token);
6871            }
6872            record.setSizeConfigurations(horizontalSizeConfiguration,
6873                    verticalSizeConfigurations, smallestSizeConfigurations);
6874        }
6875    }
6876
6877    @Override
6878    public final void backgroundResourcesReleased(IBinder token) {
6879        final long origId = Binder.clearCallingIdentity();
6880        try {
6881            synchronized (this) {
6882                ActivityStack stack = ActivityRecord.getStackLocked(token);
6883                if (stack != null) {
6884                    stack.backgroundResourcesReleased();
6885                }
6886            }
6887        } finally {
6888            Binder.restoreCallingIdentity(origId);
6889        }
6890    }
6891
6892    @Override
6893    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6894        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6895    }
6896
6897    @Override
6898    public final void notifyEnterAnimationComplete(IBinder token) {
6899        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6900    }
6901
6902    @Override
6903    public String getCallingPackage(IBinder token) {
6904        synchronized (this) {
6905            ActivityRecord r = getCallingRecordLocked(token);
6906            return r != null ? r.info.packageName : null;
6907        }
6908    }
6909
6910    @Override
6911    public ComponentName getCallingActivity(IBinder token) {
6912        synchronized (this) {
6913            ActivityRecord r = getCallingRecordLocked(token);
6914            return r != null ? r.intent.getComponent() : null;
6915        }
6916    }
6917
6918    private ActivityRecord getCallingRecordLocked(IBinder token) {
6919        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6920        if (r == null) {
6921            return null;
6922        }
6923        return r.resultTo;
6924    }
6925
6926    @Override
6927    public ComponentName getActivityClassForToken(IBinder token) {
6928        synchronized(this) {
6929            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6930            if (r == null) {
6931                return null;
6932            }
6933            return r.intent.getComponent();
6934        }
6935    }
6936
6937    @Override
6938    public String getPackageForToken(IBinder token) {
6939        synchronized(this) {
6940            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6941            if (r == null) {
6942                return null;
6943            }
6944            return r.packageName;
6945        }
6946    }
6947
6948    @Override
6949    public boolean isRootVoiceInteraction(IBinder token) {
6950        synchronized(this) {
6951            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6952            if (r == null) {
6953                return false;
6954            }
6955            return r.rootVoiceInteraction;
6956        }
6957    }
6958
6959    @Override
6960    public IIntentSender getIntentSender(int type,
6961            String packageName, IBinder token, String resultWho,
6962            int requestCode, Intent[] intents, String[] resolvedTypes,
6963            int flags, Bundle bOptions, int userId) {
6964        enforceNotIsolatedCaller("getIntentSender");
6965        // Refuse possible leaked file descriptors
6966        if (intents != null) {
6967            if (intents.length < 1) {
6968                throw new IllegalArgumentException("Intents array length must be >= 1");
6969            }
6970            for (int i=0; i<intents.length; i++) {
6971                Intent intent = intents[i];
6972                if (intent != null) {
6973                    if (intent.hasFileDescriptors()) {
6974                        throw new IllegalArgumentException("File descriptors passed in Intent");
6975                    }
6976                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6977                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6978                        throw new IllegalArgumentException(
6979                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6980                    }
6981                    intents[i] = new Intent(intent);
6982                }
6983            }
6984            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6985                throw new IllegalArgumentException(
6986                        "Intent array length does not match resolvedTypes length");
6987            }
6988        }
6989        if (bOptions != null) {
6990            if (bOptions.hasFileDescriptors()) {
6991                throw new IllegalArgumentException("File descriptors passed in options");
6992            }
6993        }
6994
6995        synchronized(this) {
6996            int callingUid = Binder.getCallingUid();
6997            int origUserId = userId;
6998            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6999                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7000                    ALLOW_NON_FULL, "getIntentSender", null);
7001            if (origUserId == UserHandle.USER_CURRENT) {
7002                // We don't want to evaluate this until the pending intent is
7003                // actually executed.  However, we do want to always do the
7004                // security checking for it above.
7005                userId = UserHandle.USER_CURRENT;
7006            }
7007            try {
7008                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7009                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7010                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7011                    if (!UserHandle.isSameApp(callingUid, uid)) {
7012                        String msg = "Permission Denial: getIntentSender() from pid="
7013                            + Binder.getCallingPid()
7014                            + ", uid=" + Binder.getCallingUid()
7015                            + ", (need uid=" + uid + ")"
7016                            + " is not allowed to send as package " + packageName;
7017                        Slog.w(TAG, msg);
7018                        throw new SecurityException(msg);
7019                    }
7020                }
7021
7022                return getIntentSenderLocked(type, packageName, callingUid, userId,
7023                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7024
7025            } catch (RemoteException e) {
7026                throw new SecurityException(e);
7027            }
7028        }
7029    }
7030
7031    IIntentSender getIntentSenderLocked(int type, String packageName,
7032            int callingUid, int userId, IBinder token, String resultWho,
7033            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7034            Bundle bOptions) {
7035        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7036        ActivityRecord activity = null;
7037        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7038            activity = ActivityRecord.isInStackLocked(token);
7039            if (activity == null) {
7040                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7041                return null;
7042            }
7043            if (activity.finishing) {
7044                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7045                return null;
7046            }
7047        }
7048
7049        // We're going to be splicing together extras before sending, so we're
7050        // okay poking into any contained extras.
7051        if (intents != null) {
7052            for (int i = 0; i < intents.length; i++) {
7053                intents[i].setDefusable(true);
7054            }
7055        }
7056        Bundle.setDefusable(bOptions, true);
7057
7058        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7059        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7060        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7061        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7062                |PendingIntent.FLAG_UPDATE_CURRENT);
7063
7064        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7065                type, packageName, activity, resultWho,
7066                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7067        WeakReference<PendingIntentRecord> ref;
7068        ref = mIntentSenderRecords.get(key);
7069        PendingIntentRecord rec = ref != null ? ref.get() : null;
7070        if (rec != null) {
7071            if (!cancelCurrent) {
7072                if (updateCurrent) {
7073                    if (rec.key.requestIntent != null) {
7074                        rec.key.requestIntent.replaceExtras(intents != null ?
7075                                intents[intents.length - 1] : null);
7076                    }
7077                    if (intents != null) {
7078                        intents[intents.length-1] = rec.key.requestIntent;
7079                        rec.key.allIntents = intents;
7080                        rec.key.allResolvedTypes = resolvedTypes;
7081                    } else {
7082                        rec.key.allIntents = null;
7083                        rec.key.allResolvedTypes = null;
7084                    }
7085                }
7086                return rec;
7087            }
7088            rec.canceled = true;
7089            mIntentSenderRecords.remove(key);
7090        }
7091        if (noCreate) {
7092            return rec;
7093        }
7094        rec = new PendingIntentRecord(this, key, callingUid);
7095        mIntentSenderRecords.put(key, rec.ref);
7096        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7097            if (activity.pendingResults == null) {
7098                activity.pendingResults
7099                        = new HashSet<WeakReference<PendingIntentRecord>>();
7100            }
7101            activity.pendingResults.add(rec.ref);
7102        }
7103        return rec;
7104    }
7105
7106    @Override
7107    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7108            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7109        if (target instanceof PendingIntentRecord) {
7110            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7111                    finishedReceiver, requiredPermission, options);
7112        } else {
7113            if (intent == null) {
7114                // Weird case: someone has given us their own custom IIntentSender, and now
7115                // they have someone else trying to send to it but of course this isn't
7116                // really a PendingIntent, so there is no base Intent, and the caller isn't
7117                // supplying an Intent... but we never want to dispatch a null Intent to
7118                // a receiver, so um...  let's make something up.
7119                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7120                intent = new Intent(Intent.ACTION_MAIN);
7121            }
7122            try {
7123                target.send(code, intent, resolvedType, null, requiredPermission, options);
7124            } catch (RemoteException e) {
7125            }
7126            // Platform code can rely on getting a result back when the send is done, but if
7127            // this intent sender is from outside of the system we can't rely on it doing that.
7128            // So instead we don't give it the result receiver, and instead just directly
7129            // report the finish immediately.
7130            if (finishedReceiver != null) {
7131                try {
7132                    finishedReceiver.performReceive(intent, 0,
7133                            null, null, false, false, UserHandle.getCallingUserId());
7134                } catch (RemoteException e) {
7135                }
7136            }
7137            return 0;
7138        }
7139    }
7140
7141    /**
7142     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7143     *
7144     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7145     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7146     */
7147    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7148        if (DEBUG_WHITELISTS) {
7149            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7150                    + targetUid + ", " + duration + ")");
7151        }
7152        synchronized (mPidsSelfLocked) {
7153            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7154            if (pr == null) {
7155                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7156                return;
7157            }
7158            if (!pr.whitelistManager) {
7159                if (DEBUG_WHITELISTS) {
7160                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7161                            + callerPid + " is not allowed");
7162                }
7163                return;
7164            }
7165        }
7166
7167        final long token = Binder.clearCallingIdentity();
7168        try {
7169            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7170                    true, "pe from uid:" + callerUid);
7171        } finally {
7172            Binder.restoreCallingIdentity(token);
7173        }
7174    }
7175
7176    @Override
7177    public void cancelIntentSender(IIntentSender sender) {
7178        if (!(sender instanceof PendingIntentRecord)) {
7179            return;
7180        }
7181        synchronized(this) {
7182            PendingIntentRecord rec = (PendingIntentRecord)sender;
7183            try {
7184                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7185                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7186                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7187                    String msg = "Permission Denial: cancelIntentSender() from pid="
7188                        + Binder.getCallingPid()
7189                        + ", uid=" + Binder.getCallingUid()
7190                        + " is not allowed to cancel packges "
7191                        + rec.key.packageName;
7192                    Slog.w(TAG, msg);
7193                    throw new SecurityException(msg);
7194                }
7195            } catch (RemoteException e) {
7196                throw new SecurityException(e);
7197            }
7198            cancelIntentSenderLocked(rec, true);
7199        }
7200    }
7201
7202    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7203        rec.canceled = true;
7204        mIntentSenderRecords.remove(rec.key);
7205        if (cleanActivity && rec.key.activity != null) {
7206            rec.key.activity.pendingResults.remove(rec.ref);
7207        }
7208    }
7209
7210    @Override
7211    public String getPackageForIntentSender(IIntentSender pendingResult) {
7212        if (!(pendingResult instanceof PendingIntentRecord)) {
7213            return null;
7214        }
7215        try {
7216            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7217            return res.key.packageName;
7218        } catch (ClassCastException e) {
7219        }
7220        return null;
7221    }
7222
7223    @Override
7224    public int getUidForIntentSender(IIntentSender sender) {
7225        if (sender instanceof PendingIntentRecord) {
7226            try {
7227                PendingIntentRecord res = (PendingIntentRecord)sender;
7228                return res.uid;
7229            } catch (ClassCastException e) {
7230            }
7231        }
7232        return -1;
7233    }
7234
7235    @Override
7236    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7237        if (!(pendingResult instanceof PendingIntentRecord)) {
7238            return false;
7239        }
7240        try {
7241            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7242            if (res.key.allIntents == null) {
7243                return false;
7244            }
7245            for (int i=0; i<res.key.allIntents.length; i++) {
7246                Intent intent = res.key.allIntents[i];
7247                if (intent.getPackage() != null && intent.getComponent() != null) {
7248                    return false;
7249                }
7250            }
7251            return true;
7252        } catch (ClassCastException e) {
7253        }
7254        return false;
7255    }
7256
7257    @Override
7258    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7259        if (!(pendingResult instanceof PendingIntentRecord)) {
7260            return false;
7261        }
7262        try {
7263            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7264            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7265                return true;
7266            }
7267            return false;
7268        } catch (ClassCastException e) {
7269        }
7270        return false;
7271    }
7272
7273    @Override
7274    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7275        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7276                "getIntentForIntentSender()");
7277        if (!(pendingResult instanceof PendingIntentRecord)) {
7278            return null;
7279        }
7280        try {
7281            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7282            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7283        } catch (ClassCastException e) {
7284        }
7285        return null;
7286    }
7287
7288    @Override
7289    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7290        if (!(pendingResult instanceof PendingIntentRecord)) {
7291            return null;
7292        }
7293        try {
7294            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7295            synchronized (this) {
7296                return getTagForIntentSenderLocked(res, prefix);
7297            }
7298        } catch (ClassCastException e) {
7299        }
7300        return null;
7301    }
7302
7303    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7304        final Intent intent = res.key.requestIntent;
7305        if (intent != null) {
7306            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7307                    || res.lastTagPrefix.equals(prefix))) {
7308                return res.lastTag;
7309            }
7310            res.lastTagPrefix = prefix;
7311            final StringBuilder sb = new StringBuilder(128);
7312            if (prefix != null) {
7313                sb.append(prefix);
7314            }
7315            if (intent.getAction() != null) {
7316                sb.append(intent.getAction());
7317            } else if (intent.getComponent() != null) {
7318                intent.getComponent().appendShortString(sb);
7319            } else {
7320                sb.append("?");
7321            }
7322            return res.lastTag = sb.toString();
7323        }
7324        return null;
7325    }
7326
7327    @Override
7328    public void setProcessLimit(int max) {
7329        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7330                "setProcessLimit()");
7331        synchronized (this) {
7332            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7333            mProcessLimitOverride = max;
7334        }
7335        trimApplications();
7336    }
7337
7338    @Override
7339    public int getProcessLimit() {
7340        synchronized (this) {
7341            return mProcessLimitOverride;
7342        }
7343    }
7344
7345    void foregroundTokenDied(ForegroundToken token) {
7346        synchronized (ActivityManagerService.this) {
7347            synchronized (mPidsSelfLocked) {
7348                ForegroundToken cur
7349                    = mForegroundProcesses.get(token.pid);
7350                if (cur != token) {
7351                    return;
7352                }
7353                mForegroundProcesses.remove(token.pid);
7354                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7355                if (pr == null) {
7356                    return;
7357                }
7358                pr.forcingToForeground = null;
7359                updateProcessForegroundLocked(pr, false, false);
7360            }
7361            updateOomAdjLocked();
7362        }
7363    }
7364
7365    @Override
7366    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7367        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7368                "setProcessForeground()");
7369        synchronized(this) {
7370            boolean changed = false;
7371
7372            synchronized (mPidsSelfLocked) {
7373                ProcessRecord pr = mPidsSelfLocked.get(pid);
7374                if (pr == null && isForeground) {
7375                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7376                    return;
7377                }
7378                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7379                if (oldToken != null) {
7380                    oldToken.token.unlinkToDeath(oldToken, 0);
7381                    mForegroundProcesses.remove(pid);
7382                    if (pr != null) {
7383                        pr.forcingToForeground = null;
7384                    }
7385                    changed = true;
7386                }
7387                if (isForeground && token != null) {
7388                    ForegroundToken newToken = new ForegroundToken() {
7389                        @Override
7390                        public void binderDied() {
7391                            foregroundTokenDied(this);
7392                        }
7393                    };
7394                    newToken.pid = pid;
7395                    newToken.token = token;
7396                    try {
7397                        token.linkToDeath(newToken, 0);
7398                        mForegroundProcesses.put(pid, newToken);
7399                        pr.forcingToForeground = token;
7400                        changed = true;
7401                    } catch (RemoteException e) {
7402                        // If the process died while doing this, we will later
7403                        // do the cleanup with the process death link.
7404                    }
7405                }
7406            }
7407
7408            if (changed) {
7409                updateOomAdjLocked();
7410            }
7411        }
7412    }
7413
7414    @Override
7415    public boolean isAppForeground(int uid) throws RemoteException {
7416        synchronized (this) {
7417            UidRecord uidRec = mActiveUids.get(uid);
7418            if (uidRec == null || uidRec.idle) {
7419                return false;
7420            }
7421            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7422        }
7423    }
7424
7425    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7426    // be guarded by permission checking.
7427    int getUidState(int uid) {
7428        synchronized (this) {
7429            UidRecord uidRec = mActiveUids.get(uid);
7430            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7431        }
7432    }
7433
7434    @Override
7435    public boolean isInMultiWindowMode(IBinder token) {
7436        final long origId = Binder.clearCallingIdentity();
7437        try {
7438            synchronized(this) {
7439                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7440                if (r == null) {
7441                    return false;
7442                }
7443                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7444                return !r.task.mFullscreen;
7445            }
7446        } finally {
7447            Binder.restoreCallingIdentity(origId);
7448        }
7449    }
7450
7451    @Override
7452    public boolean isInPictureInPictureMode(IBinder token) {
7453        final long origId = Binder.clearCallingIdentity();
7454        try {
7455            synchronized(this) {
7456                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7457                if (stack == null) {
7458                    return false;
7459                }
7460                return stack.mStackId == PINNED_STACK_ID;
7461            }
7462        } finally {
7463            Binder.restoreCallingIdentity(origId);
7464        }
7465    }
7466
7467    @Override
7468    public void enterPictureInPictureMode(IBinder token) {
7469        final long origId = Binder.clearCallingIdentity();
7470        try {
7471            synchronized(this) {
7472                if (!mSupportsPictureInPicture) {
7473                    throw new IllegalStateException("enterPictureInPictureMode: "
7474                            + "Device doesn't support picture-in-picture mode.");
7475                }
7476
7477                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7478
7479                if (r == null) {
7480                    throw new IllegalStateException("enterPictureInPictureMode: "
7481                            + "Can't find activity for token=" + token);
7482                }
7483
7484                if (!r.supportsPictureInPicture()) {
7485                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7486                            + "Picture-In-Picture not supported for r=" + r);
7487                }
7488
7489                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7490                // current bounds.
7491                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7492                final Rect bounds = (pinnedStack != null)
7493                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7494
7495                mStackSupervisor.moveActivityToPinnedStackLocked(
7496                        r, "enterPictureInPictureMode", bounds);
7497            }
7498        } finally {
7499            Binder.restoreCallingIdentity(origId);
7500        }
7501    }
7502
7503    // =========================================================
7504    // PROCESS INFO
7505    // =========================================================
7506
7507    static class ProcessInfoService extends IProcessInfoService.Stub {
7508        final ActivityManagerService mActivityManagerService;
7509        ProcessInfoService(ActivityManagerService activityManagerService) {
7510            mActivityManagerService = activityManagerService;
7511        }
7512
7513        @Override
7514        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7515            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7516                    /*in*/ pids, /*out*/ states, null);
7517        }
7518
7519        @Override
7520        public void getProcessStatesAndOomScoresFromPids(
7521                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7522            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7523                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7524        }
7525    }
7526
7527    /**
7528     * For each PID in the given input array, write the current process state
7529     * for that process into the states array, or -1 to indicate that no
7530     * process with the given PID exists. If scores array is provided, write
7531     * the oom score for the process into the scores array, with INVALID_ADJ
7532     * indicating the PID doesn't exist.
7533     */
7534    public void getProcessStatesAndOomScoresForPIDs(
7535            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7536        if (scores != null) {
7537            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7538                    "getProcessStatesAndOomScoresForPIDs()");
7539        }
7540
7541        if (pids == null) {
7542            throw new NullPointerException("pids");
7543        } else if (states == null) {
7544            throw new NullPointerException("states");
7545        } else if (pids.length != states.length) {
7546            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7547        } else if (scores != null && pids.length != scores.length) {
7548            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7549        }
7550
7551        synchronized (mPidsSelfLocked) {
7552            for (int i = 0; i < pids.length; i++) {
7553                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7554                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7555                        pr.curProcState;
7556                if (scores != null) {
7557                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7558                }
7559            }
7560        }
7561    }
7562
7563    // =========================================================
7564    // PERMISSIONS
7565    // =========================================================
7566
7567    static class PermissionController extends IPermissionController.Stub {
7568        ActivityManagerService mActivityManagerService;
7569        PermissionController(ActivityManagerService activityManagerService) {
7570            mActivityManagerService = activityManagerService;
7571        }
7572
7573        @Override
7574        public boolean checkPermission(String permission, int pid, int uid) {
7575            return mActivityManagerService.checkPermission(permission, pid,
7576                    uid) == PackageManager.PERMISSION_GRANTED;
7577        }
7578
7579        @Override
7580        public String[] getPackagesForUid(int uid) {
7581            return mActivityManagerService.mContext.getPackageManager()
7582                    .getPackagesForUid(uid);
7583        }
7584
7585        @Override
7586        public boolean isRuntimePermission(String permission) {
7587            try {
7588                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7589                        .getPermissionInfo(permission, 0);
7590                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7591            } catch (NameNotFoundException nnfe) {
7592                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7593            }
7594            return false;
7595        }
7596    }
7597
7598    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7599        @Override
7600        public int checkComponentPermission(String permission, int pid, int uid,
7601                int owningUid, boolean exported) {
7602            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7603                    owningUid, exported);
7604        }
7605
7606        @Override
7607        public Object getAMSLock() {
7608            return ActivityManagerService.this;
7609        }
7610    }
7611
7612    /**
7613     * This can be called with or without the global lock held.
7614     */
7615    int checkComponentPermission(String permission, int pid, int uid,
7616            int owningUid, boolean exported) {
7617        if (pid == MY_PID) {
7618            return PackageManager.PERMISSION_GRANTED;
7619        }
7620        return ActivityManager.checkComponentPermission(permission, uid,
7621                owningUid, exported);
7622    }
7623
7624    /**
7625     * As the only public entry point for permissions checking, this method
7626     * can enforce the semantic that requesting a check on a null global
7627     * permission is automatically denied.  (Internally a null permission
7628     * string is used when calling {@link #checkComponentPermission} in cases
7629     * when only uid-based security is needed.)
7630     *
7631     * This can be called with or without the global lock held.
7632     */
7633    @Override
7634    public int checkPermission(String permission, int pid, int uid) {
7635        if (permission == null) {
7636            return PackageManager.PERMISSION_DENIED;
7637        }
7638        return checkComponentPermission(permission, pid, uid, -1, true);
7639    }
7640
7641    @Override
7642    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7643        if (permission == null) {
7644            return PackageManager.PERMISSION_DENIED;
7645        }
7646
7647        // We might be performing an operation on behalf of an indirect binder
7648        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7649        // client identity accordingly before proceeding.
7650        Identity tlsIdentity = sCallerIdentity.get();
7651        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7652            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7653                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7654            uid = tlsIdentity.uid;
7655            pid = tlsIdentity.pid;
7656        }
7657
7658        return checkComponentPermission(permission, pid, uid, -1, true);
7659    }
7660
7661    /**
7662     * Binder IPC calls go through the public entry point.
7663     * This can be called with or without the global lock held.
7664     */
7665    int checkCallingPermission(String permission) {
7666        return checkPermission(permission,
7667                Binder.getCallingPid(),
7668                UserHandle.getAppId(Binder.getCallingUid()));
7669    }
7670
7671    /**
7672     * This can be called with or without the global lock held.
7673     */
7674    void enforceCallingPermission(String permission, String func) {
7675        if (checkCallingPermission(permission)
7676                == PackageManager.PERMISSION_GRANTED) {
7677            return;
7678        }
7679
7680        String msg = "Permission Denial: " + func + " from pid="
7681                + Binder.getCallingPid()
7682                + ", uid=" + Binder.getCallingUid()
7683                + " requires " + permission;
7684        Slog.w(TAG, msg);
7685        throw new SecurityException(msg);
7686    }
7687
7688    /**
7689     * Determine if UID is holding permissions required to access {@link Uri} in
7690     * the given {@link ProviderInfo}. Final permission checking is always done
7691     * in {@link ContentProvider}.
7692     */
7693    private final boolean checkHoldingPermissionsLocked(
7694            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7695        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7696                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7697        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7698            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7699                    != PERMISSION_GRANTED) {
7700                return false;
7701            }
7702        }
7703        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7704    }
7705
7706    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7707            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7708        if (pi.applicationInfo.uid == uid) {
7709            return true;
7710        } else if (!pi.exported) {
7711            return false;
7712        }
7713
7714        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7715        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7716        try {
7717            // check if target holds top-level <provider> permissions
7718            if (!readMet && pi.readPermission != null && considerUidPermissions
7719                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7720                readMet = true;
7721            }
7722            if (!writeMet && pi.writePermission != null && considerUidPermissions
7723                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7724                writeMet = true;
7725            }
7726
7727            // track if unprotected read/write is allowed; any denied
7728            // <path-permission> below removes this ability
7729            boolean allowDefaultRead = pi.readPermission == null;
7730            boolean allowDefaultWrite = pi.writePermission == null;
7731
7732            // check if target holds any <path-permission> that match uri
7733            final PathPermission[] pps = pi.pathPermissions;
7734            if (pps != null) {
7735                final String path = grantUri.uri.getPath();
7736                int i = pps.length;
7737                while (i > 0 && (!readMet || !writeMet)) {
7738                    i--;
7739                    PathPermission pp = pps[i];
7740                    if (pp.match(path)) {
7741                        if (!readMet) {
7742                            final String pprperm = pp.getReadPermission();
7743                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7744                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7745                                    + ": match=" + pp.match(path)
7746                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7747                            if (pprperm != null) {
7748                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7749                                        == PERMISSION_GRANTED) {
7750                                    readMet = true;
7751                                } else {
7752                                    allowDefaultRead = false;
7753                                }
7754                            }
7755                        }
7756                        if (!writeMet) {
7757                            final String ppwperm = pp.getWritePermission();
7758                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7759                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7760                                    + ": match=" + pp.match(path)
7761                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7762                            if (ppwperm != null) {
7763                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7764                                        == PERMISSION_GRANTED) {
7765                                    writeMet = true;
7766                                } else {
7767                                    allowDefaultWrite = false;
7768                                }
7769                            }
7770                        }
7771                    }
7772                }
7773            }
7774
7775            // grant unprotected <provider> read/write, if not blocked by
7776            // <path-permission> above
7777            if (allowDefaultRead) readMet = true;
7778            if (allowDefaultWrite) writeMet = true;
7779
7780        } catch (RemoteException e) {
7781            return false;
7782        }
7783
7784        return readMet && writeMet;
7785    }
7786
7787    public int getAppStartMode(int uid, String packageName) {
7788        synchronized (this) {
7789            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7790        }
7791    }
7792
7793    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7794            boolean allowWhenForeground) {
7795        UidRecord uidRec = mActiveUids.get(uid);
7796        if (!mLenientBackgroundCheck) {
7797            if (!allowWhenForeground || uidRec == null
7798                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7799                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7800                        packageName) != AppOpsManager.MODE_ALLOWED) {
7801                    return ActivityManager.APP_START_MODE_DELAYED;
7802                }
7803            }
7804
7805        } else if (uidRec == null || uidRec.idle) {
7806            if (callingPid >= 0) {
7807                ProcessRecord proc;
7808                synchronized (mPidsSelfLocked) {
7809                    proc = mPidsSelfLocked.get(callingPid);
7810                }
7811                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7812                    // Whoever is instigating this is in the foreground, so we will allow it
7813                    // to go through.
7814                    return ActivityManager.APP_START_MODE_NORMAL;
7815                }
7816            }
7817            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7818                    != AppOpsManager.MODE_ALLOWED) {
7819                return ActivityManager.APP_START_MODE_DELAYED;
7820            }
7821        }
7822        return ActivityManager.APP_START_MODE_NORMAL;
7823    }
7824
7825    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7826        ProviderInfo pi = null;
7827        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7828        if (cpr != null) {
7829            pi = cpr.info;
7830        } else {
7831            try {
7832                pi = AppGlobals.getPackageManager().resolveContentProvider(
7833                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7834                        userHandle);
7835            } catch (RemoteException ex) {
7836            }
7837        }
7838        return pi;
7839    }
7840
7841    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7842        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7843        if (targetUris != null) {
7844            return targetUris.get(grantUri);
7845        }
7846        return null;
7847    }
7848
7849    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7850            String targetPkg, int targetUid, GrantUri grantUri) {
7851        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7852        if (targetUris == null) {
7853            targetUris = Maps.newArrayMap();
7854            mGrantedUriPermissions.put(targetUid, targetUris);
7855        }
7856
7857        UriPermission perm = targetUris.get(grantUri);
7858        if (perm == null) {
7859            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7860            targetUris.put(grantUri, perm);
7861        }
7862
7863        return perm;
7864    }
7865
7866    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7867            final int modeFlags) {
7868        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7869        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7870                : UriPermission.STRENGTH_OWNED;
7871
7872        // Root gets to do everything.
7873        if (uid == 0) {
7874            return true;
7875        }
7876
7877        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7878        if (perms == null) return false;
7879
7880        // First look for exact match
7881        final UriPermission exactPerm = perms.get(grantUri);
7882        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7883            return true;
7884        }
7885
7886        // No exact match, look for prefixes
7887        final int N = perms.size();
7888        for (int i = 0; i < N; i++) {
7889            final UriPermission perm = perms.valueAt(i);
7890            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7891                    && perm.getStrength(modeFlags) >= minStrength) {
7892                return true;
7893            }
7894        }
7895
7896        return false;
7897    }
7898
7899    /**
7900     * @param uri This uri must NOT contain an embedded userId.
7901     * @param userId The userId in which the uri is to be resolved.
7902     */
7903    @Override
7904    public int checkUriPermission(Uri uri, int pid, int uid,
7905            final int modeFlags, int userId, IBinder callerToken) {
7906        enforceNotIsolatedCaller("checkUriPermission");
7907
7908        // Another redirected-binder-call permissions check as in
7909        // {@link checkPermissionWithToken}.
7910        Identity tlsIdentity = sCallerIdentity.get();
7911        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7912            uid = tlsIdentity.uid;
7913            pid = tlsIdentity.pid;
7914        }
7915
7916        // Our own process gets to do everything.
7917        if (pid == MY_PID) {
7918            return PackageManager.PERMISSION_GRANTED;
7919        }
7920        synchronized (this) {
7921            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7922                    ? PackageManager.PERMISSION_GRANTED
7923                    : PackageManager.PERMISSION_DENIED;
7924        }
7925    }
7926
7927    /**
7928     * Check if the targetPkg can be granted permission to access uri by
7929     * the callingUid using the given modeFlags.  Throws a security exception
7930     * if callingUid is not allowed to do this.  Returns the uid of the target
7931     * if the URI permission grant should be performed; returns -1 if it is not
7932     * needed (for example targetPkg already has permission to access the URI).
7933     * If you already know the uid of the target, you can supply it in
7934     * lastTargetUid else set that to -1.
7935     */
7936    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7937            final int modeFlags, int lastTargetUid) {
7938        if (!Intent.isAccessUriMode(modeFlags)) {
7939            return -1;
7940        }
7941
7942        if (targetPkg != null) {
7943            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7944                    "Checking grant " + targetPkg + " permission to " + grantUri);
7945        }
7946
7947        final IPackageManager pm = AppGlobals.getPackageManager();
7948
7949        // If this is not a content: uri, we can't do anything with it.
7950        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7951            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7952                    "Can't grant URI permission for non-content URI: " + grantUri);
7953            return -1;
7954        }
7955
7956        final String authority = grantUri.uri.getAuthority();
7957        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7958                MATCH_DEBUG_TRIAGED_MISSING);
7959        if (pi == null) {
7960            Slog.w(TAG, "No content provider found for permission check: " +
7961                    grantUri.uri.toSafeString());
7962            return -1;
7963        }
7964
7965        int targetUid = lastTargetUid;
7966        if (targetUid < 0 && targetPkg != null) {
7967            try {
7968                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7969                        UserHandle.getUserId(callingUid));
7970                if (targetUid < 0) {
7971                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7972                            "Can't grant URI permission no uid for: " + targetPkg);
7973                    return -1;
7974                }
7975            } catch (RemoteException ex) {
7976                return -1;
7977            }
7978        }
7979
7980        if (targetUid >= 0) {
7981            // First...  does the target actually need this permission?
7982            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7983                // No need to grant the target this permission.
7984                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7985                        "Target " + targetPkg + " already has full permission to " + grantUri);
7986                return -1;
7987            }
7988        } else {
7989            // First...  there is no target package, so can anyone access it?
7990            boolean allowed = pi.exported;
7991            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7992                if (pi.readPermission != null) {
7993                    allowed = false;
7994                }
7995            }
7996            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7997                if (pi.writePermission != null) {
7998                    allowed = false;
7999                }
8000            }
8001            if (allowed) {
8002                return -1;
8003            }
8004        }
8005
8006        /* There is a special cross user grant if:
8007         * - The target is on another user.
8008         * - Apps on the current user can access the uri without any uid permissions.
8009         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8010         * grant uri permissions.
8011         */
8012        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8013                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8014                modeFlags, false /*without considering the uid permissions*/);
8015
8016        // Second...  is the provider allowing granting of URI permissions?
8017        if (!specialCrossUserGrant) {
8018            if (!pi.grantUriPermissions) {
8019                throw new SecurityException("Provider " + pi.packageName
8020                        + "/" + pi.name
8021                        + " does not allow granting of Uri permissions (uri "
8022                        + grantUri + ")");
8023            }
8024            if (pi.uriPermissionPatterns != null) {
8025                final int N = pi.uriPermissionPatterns.length;
8026                boolean allowed = false;
8027                for (int i=0; i<N; i++) {
8028                    if (pi.uriPermissionPatterns[i] != null
8029                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8030                        allowed = true;
8031                        break;
8032                    }
8033                }
8034                if (!allowed) {
8035                    throw new SecurityException("Provider " + pi.packageName
8036                            + "/" + pi.name
8037                            + " does not allow granting of permission to path of Uri "
8038                            + grantUri);
8039                }
8040            }
8041        }
8042
8043        // Third...  does the caller itself have permission to access
8044        // this uri?
8045        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8046            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8047                // Require they hold a strong enough Uri permission
8048                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8049                    throw new SecurityException("Uid " + callingUid
8050                            + " does not have permission to uri " + grantUri);
8051                }
8052            }
8053        }
8054        return targetUid;
8055    }
8056
8057    /**
8058     * @param uri This uri must NOT contain an embedded userId.
8059     * @param userId The userId in which the uri is to be resolved.
8060     */
8061    @Override
8062    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8063            final int modeFlags, int userId) {
8064        enforceNotIsolatedCaller("checkGrantUriPermission");
8065        synchronized(this) {
8066            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8067                    new GrantUri(userId, uri, false), modeFlags, -1);
8068        }
8069    }
8070
8071    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8072            final int modeFlags, UriPermissionOwner owner) {
8073        if (!Intent.isAccessUriMode(modeFlags)) {
8074            return;
8075        }
8076
8077        // So here we are: the caller has the assumed permission
8078        // to the uri, and the target doesn't.  Let's now give this to
8079        // the target.
8080
8081        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8082                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8083
8084        final String authority = grantUri.uri.getAuthority();
8085        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8086                MATCH_DEBUG_TRIAGED_MISSING);
8087        if (pi == null) {
8088            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8089            return;
8090        }
8091
8092        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8093            grantUri.prefix = true;
8094        }
8095        final UriPermission perm = findOrCreateUriPermissionLocked(
8096                pi.packageName, targetPkg, targetUid, grantUri);
8097        perm.grantModes(modeFlags, owner);
8098    }
8099
8100    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8101            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8102        if (targetPkg == null) {
8103            throw new NullPointerException("targetPkg");
8104        }
8105        int targetUid;
8106        final IPackageManager pm = AppGlobals.getPackageManager();
8107        try {
8108            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8109        } catch (RemoteException ex) {
8110            return;
8111        }
8112
8113        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8114                targetUid);
8115        if (targetUid < 0) {
8116            return;
8117        }
8118
8119        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8120                owner);
8121    }
8122
8123    static class NeededUriGrants extends ArrayList<GrantUri> {
8124        final String targetPkg;
8125        final int targetUid;
8126        final int flags;
8127
8128        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8129            this.targetPkg = targetPkg;
8130            this.targetUid = targetUid;
8131            this.flags = flags;
8132        }
8133    }
8134
8135    /**
8136     * Like checkGrantUriPermissionLocked, but takes an Intent.
8137     */
8138    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8139            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8140        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8141                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8142                + " clip=" + (intent != null ? intent.getClipData() : null)
8143                + " from " + intent + "; flags=0x"
8144                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8145
8146        if (targetPkg == null) {
8147            throw new NullPointerException("targetPkg");
8148        }
8149
8150        if (intent == null) {
8151            return null;
8152        }
8153        Uri data = intent.getData();
8154        ClipData clip = intent.getClipData();
8155        if (data == null && clip == null) {
8156            return null;
8157        }
8158        // Default userId for uris in the intent (if they don't specify it themselves)
8159        int contentUserHint = intent.getContentUserHint();
8160        if (contentUserHint == UserHandle.USER_CURRENT) {
8161            contentUserHint = UserHandle.getUserId(callingUid);
8162        }
8163        final IPackageManager pm = AppGlobals.getPackageManager();
8164        int targetUid;
8165        if (needed != null) {
8166            targetUid = needed.targetUid;
8167        } else {
8168            try {
8169                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8170                        targetUserId);
8171            } catch (RemoteException ex) {
8172                return null;
8173            }
8174            if (targetUid < 0) {
8175                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8176                        "Can't grant URI permission no uid for: " + targetPkg
8177                        + " on user " + targetUserId);
8178                return null;
8179            }
8180        }
8181        if (data != null) {
8182            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8183            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8184                    targetUid);
8185            if (targetUid > 0) {
8186                if (needed == null) {
8187                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8188                }
8189                needed.add(grantUri);
8190            }
8191        }
8192        if (clip != null) {
8193            for (int i=0; i<clip.getItemCount(); i++) {
8194                Uri uri = clip.getItemAt(i).getUri();
8195                if (uri != null) {
8196                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8197                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8198                            targetUid);
8199                    if (targetUid > 0) {
8200                        if (needed == null) {
8201                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8202                        }
8203                        needed.add(grantUri);
8204                    }
8205                } else {
8206                    Intent clipIntent = clip.getItemAt(i).getIntent();
8207                    if (clipIntent != null) {
8208                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8209                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8210                        if (newNeeded != null) {
8211                            needed = newNeeded;
8212                        }
8213                    }
8214                }
8215            }
8216        }
8217
8218        return needed;
8219    }
8220
8221    /**
8222     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8223     */
8224    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8225            UriPermissionOwner owner) {
8226        if (needed != null) {
8227            for (int i=0; i<needed.size(); i++) {
8228                GrantUri grantUri = needed.get(i);
8229                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8230                        grantUri, needed.flags, owner);
8231            }
8232        }
8233    }
8234
8235    void grantUriPermissionFromIntentLocked(int callingUid,
8236            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8237        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8238                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8239        if (needed == null) {
8240            return;
8241        }
8242
8243        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8244    }
8245
8246    /**
8247     * @param uri This uri must NOT contain an embedded userId.
8248     * @param userId The userId in which the uri is to be resolved.
8249     */
8250    @Override
8251    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8252            final int modeFlags, int userId) {
8253        enforceNotIsolatedCaller("grantUriPermission");
8254        GrantUri grantUri = new GrantUri(userId, uri, false);
8255        synchronized(this) {
8256            final ProcessRecord r = getRecordForAppLocked(caller);
8257            if (r == null) {
8258                throw new SecurityException("Unable to find app for caller "
8259                        + caller
8260                        + " when granting permission to uri " + grantUri);
8261            }
8262            if (targetPkg == null) {
8263                throw new IllegalArgumentException("null target");
8264            }
8265            if (grantUri == null) {
8266                throw new IllegalArgumentException("null uri");
8267            }
8268
8269            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8270                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8271                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8272                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8273
8274            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8275                    UserHandle.getUserId(r.uid));
8276        }
8277    }
8278
8279    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8280        if (perm.modeFlags == 0) {
8281            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8282                    perm.targetUid);
8283            if (perms != null) {
8284                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8285                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8286
8287                perms.remove(perm.uri);
8288                if (perms.isEmpty()) {
8289                    mGrantedUriPermissions.remove(perm.targetUid);
8290                }
8291            }
8292        }
8293    }
8294
8295    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8296        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8297                "Revoking all granted permissions to " + grantUri);
8298
8299        final IPackageManager pm = AppGlobals.getPackageManager();
8300        final String authority = grantUri.uri.getAuthority();
8301        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8302                MATCH_DEBUG_TRIAGED_MISSING);
8303        if (pi == null) {
8304            Slog.w(TAG, "No content provider found for permission revoke: "
8305                    + grantUri.toSafeString());
8306            return;
8307        }
8308
8309        // Does the caller have this permission on the URI?
8310        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8311            // If they don't have direct access to the URI, then revoke any
8312            // ownerless URI permissions that have been granted to them.
8313            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8314            if (perms != null) {
8315                boolean persistChanged = false;
8316                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8317                    final UriPermission perm = it.next();
8318                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8319                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8320                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8321                                "Revoking non-owned " + perm.targetUid
8322                                + " permission to " + perm.uri);
8323                        persistChanged |= perm.revokeModes(
8324                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8325                        if (perm.modeFlags == 0) {
8326                            it.remove();
8327                        }
8328                    }
8329                }
8330                if (perms.isEmpty()) {
8331                    mGrantedUriPermissions.remove(callingUid);
8332                }
8333                if (persistChanged) {
8334                    schedulePersistUriGrants();
8335                }
8336            }
8337            return;
8338        }
8339
8340        boolean persistChanged = false;
8341
8342        // Go through all of the permissions and remove any that match.
8343        int N = mGrantedUriPermissions.size();
8344        for (int i = 0; i < N; i++) {
8345            final int targetUid = mGrantedUriPermissions.keyAt(i);
8346            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8347
8348            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8349                final UriPermission perm = it.next();
8350                if (perm.uri.sourceUserId == grantUri.sourceUserId
8351                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8352                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8353                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8354                    persistChanged |= perm.revokeModes(
8355                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8356                    if (perm.modeFlags == 0) {
8357                        it.remove();
8358                    }
8359                }
8360            }
8361
8362            if (perms.isEmpty()) {
8363                mGrantedUriPermissions.remove(targetUid);
8364                N--;
8365                i--;
8366            }
8367        }
8368
8369        if (persistChanged) {
8370            schedulePersistUriGrants();
8371        }
8372    }
8373
8374    /**
8375     * @param uri This uri must NOT contain an embedded userId.
8376     * @param userId The userId in which the uri is to be resolved.
8377     */
8378    @Override
8379    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8380            int userId) {
8381        enforceNotIsolatedCaller("revokeUriPermission");
8382        synchronized(this) {
8383            final ProcessRecord r = getRecordForAppLocked(caller);
8384            if (r == null) {
8385                throw new SecurityException("Unable to find app for caller "
8386                        + caller
8387                        + " when revoking permission to uri " + uri);
8388            }
8389            if (uri == null) {
8390                Slog.w(TAG, "revokeUriPermission: null uri");
8391                return;
8392            }
8393
8394            if (!Intent.isAccessUriMode(modeFlags)) {
8395                return;
8396            }
8397
8398            final String authority = uri.getAuthority();
8399            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8400                    MATCH_DEBUG_TRIAGED_MISSING);
8401            if (pi == null) {
8402                Slog.w(TAG, "No content provider found for permission revoke: "
8403                        + uri.toSafeString());
8404                return;
8405            }
8406
8407            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8408        }
8409    }
8410
8411    /**
8412     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8413     * given package.
8414     *
8415     * @param packageName Package name to match, or {@code null} to apply to all
8416     *            packages.
8417     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8418     *            to all users.
8419     * @param persistable If persistable grants should be removed.
8420     */
8421    private void removeUriPermissionsForPackageLocked(
8422            String packageName, int userHandle, boolean persistable) {
8423        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8424            throw new IllegalArgumentException("Must narrow by either package or user");
8425        }
8426
8427        boolean persistChanged = false;
8428
8429        int N = mGrantedUriPermissions.size();
8430        for (int i = 0; i < N; i++) {
8431            final int targetUid = mGrantedUriPermissions.keyAt(i);
8432            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8433
8434            // Only inspect grants matching user
8435            if (userHandle == UserHandle.USER_ALL
8436                    || userHandle == UserHandle.getUserId(targetUid)) {
8437                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8438                    final UriPermission perm = it.next();
8439
8440                    // Only inspect grants matching package
8441                    if (packageName == null || perm.sourcePkg.equals(packageName)
8442                            || perm.targetPkg.equals(packageName)) {
8443                        persistChanged |= perm.revokeModes(persistable
8444                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8445
8446                        // Only remove when no modes remain; any persisted grants
8447                        // will keep this alive.
8448                        if (perm.modeFlags == 0) {
8449                            it.remove();
8450                        }
8451                    }
8452                }
8453
8454                if (perms.isEmpty()) {
8455                    mGrantedUriPermissions.remove(targetUid);
8456                    N--;
8457                    i--;
8458                }
8459            }
8460        }
8461
8462        if (persistChanged) {
8463            schedulePersistUriGrants();
8464        }
8465    }
8466
8467    @Override
8468    public IBinder newUriPermissionOwner(String name) {
8469        enforceNotIsolatedCaller("newUriPermissionOwner");
8470        synchronized(this) {
8471            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8472            return owner.getExternalTokenLocked();
8473        }
8474    }
8475
8476    @Override
8477    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8478        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8479        synchronized(this) {
8480            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8481            if (r == null) {
8482                throw new IllegalArgumentException("Activity does not exist; token="
8483                        + activityToken);
8484            }
8485            return r.getUriPermissionsLocked().getExternalTokenLocked();
8486        }
8487    }
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param sourceUserId The userId in which the uri is to be resolved.
8491     * @param targetUserId The userId of the app that receives the grant.
8492     */
8493    @Override
8494    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8495            final int modeFlags, int sourceUserId, int targetUserId) {
8496        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8497                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8498                "grantUriPermissionFromOwner", null);
8499        synchronized(this) {
8500            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8501            if (owner == null) {
8502                throw new IllegalArgumentException("Unknown owner: " + token);
8503            }
8504            if (fromUid != Binder.getCallingUid()) {
8505                if (Binder.getCallingUid() != Process.myUid()) {
8506                    // Only system code can grant URI permissions on behalf
8507                    // of other users.
8508                    throw new SecurityException("nice try");
8509                }
8510            }
8511            if (targetPkg == null) {
8512                throw new IllegalArgumentException("null target");
8513            }
8514            if (uri == null) {
8515                throw new IllegalArgumentException("null uri");
8516            }
8517
8518            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8519                    modeFlags, owner, targetUserId);
8520        }
8521    }
8522
8523    /**
8524     * @param uri This uri must NOT contain an embedded userId.
8525     * @param userId The userId in which the uri is to be resolved.
8526     */
8527    @Override
8528    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8529        synchronized(this) {
8530            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8531            if (owner == null) {
8532                throw new IllegalArgumentException("Unknown owner: " + token);
8533            }
8534
8535            if (uri == null) {
8536                owner.removeUriPermissionsLocked(mode);
8537            } else {
8538                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8539            }
8540        }
8541    }
8542
8543    private void schedulePersistUriGrants() {
8544        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8545            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8546                    10 * DateUtils.SECOND_IN_MILLIS);
8547        }
8548    }
8549
8550    private void writeGrantedUriPermissions() {
8551        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8552
8553        // Snapshot permissions so we can persist without lock
8554        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8555        synchronized (this) {
8556            final int size = mGrantedUriPermissions.size();
8557            for (int i = 0; i < size; i++) {
8558                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8559                for (UriPermission perm : perms.values()) {
8560                    if (perm.persistedModeFlags != 0) {
8561                        persist.add(perm.snapshot());
8562                    }
8563                }
8564            }
8565        }
8566
8567        FileOutputStream fos = null;
8568        try {
8569            fos = mGrantFile.startWrite();
8570
8571            XmlSerializer out = new FastXmlSerializer();
8572            out.setOutput(fos, StandardCharsets.UTF_8.name());
8573            out.startDocument(null, true);
8574            out.startTag(null, TAG_URI_GRANTS);
8575            for (UriPermission.Snapshot perm : persist) {
8576                out.startTag(null, TAG_URI_GRANT);
8577                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8578                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8579                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8580                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8581                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8582                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8583                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8584                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8585                out.endTag(null, TAG_URI_GRANT);
8586            }
8587            out.endTag(null, TAG_URI_GRANTS);
8588            out.endDocument();
8589
8590            mGrantFile.finishWrite(fos);
8591        } catch (IOException e) {
8592            if (fos != null) {
8593                mGrantFile.failWrite(fos);
8594            }
8595        }
8596    }
8597
8598    private void readGrantedUriPermissionsLocked() {
8599        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8600
8601        final long now = System.currentTimeMillis();
8602
8603        FileInputStream fis = null;
8604        try {
8605            fis = mGrantFile.openRead();
8606            final XmlPullParser in = Xml.newPullParser();
8607            in.setInput(fis, StandardCharsets.UTF_8.name());
8608
8609            int type;
8610            while ((type = in.next()) != END_DOCUMENT) {
8611                final String tag = in.getName();
8612                if (type == START_TAG) {
8613                    if (TAG_URI_GRANT.equals(tag)) {
8614                        final int sourceUserId;
8615                        final int targetUserId;
8616                        final int userHandle = readIntAttribute(in,
8617                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8618                        if (userHandle != UserHandle.USER_NULL) {
8619                            // For backwards compatibility.
8620                            sourceUserId = userHandle;
8621                            targetUserId = userHandle;
8622                        } else {
8623                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8624                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8625                        }
8626                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8627                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8628                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8629                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8630                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8631                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8632
8633                        // Sanity check that provider still belongs to source package
8634                        // Both direct boot aware and unaware packages are fine as we
8635                        // will do filtering at query time to avoid multiple parsing.
8636                        final ProviderInfo pi = getProviderInfoLocked(
8637                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8638                                        | MATCH_DIRECT_BOOT_UNAWARE);
8639                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8640                            int targetUid = -1;
8641                            try {
8642                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8643                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8644                            } catch (RemoteException e) {
8645                            }
8646                            if (targetUid != -1) {
8647                                final UriPermission perm = findOrCreateUriPermissionLocked(
8648                                        sourcePkg, targetPkg, targetUid,
8649                                        new GrantUri(sourceUserId, uri, prefix));
8650                                perm.initPersistedModes(modeFlags, createdTime);
8651                            }
8652                        } else {
8653                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8654                                    + " but instead found " + pi);
8655                        }
8656                    }
8657                }
8658            }
8659        } catch (FileNotFoundException e) {
8660            // Missing grants is okay
8661        } catch (IOException e) {
8662            Slog.wtf(TAG, "Failed reading Uri grants", e);
8663        } catch (XmlPullParserException e) {
8664            Slog.wtf(TAG, "Failed reading Uri grants", e);
8665        } finally {
8666            IoUtils.closeQuietly(fis);
8667        }
8668    }
8669
8670    /**
8671     * @param uri This uri must NOT contain an embedded userId.
8672     * @param userId The userId in which the uri is to be resolved.
8673     */
8674    @Override
8675    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8676        enforceNotIsolatedCaller("takePersistableUriPermission");
8677
8678        Preconditions.checkFlagsArgument(modeFlags,
8679                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8680
8681        synchronized (this) {
8682            final int callingUid = Binder.getCallingUid();
8683            boolean persistChanged = false;
8684            GrantUri grantUri = new GrantUri(userId, uri, false);
8685
8686            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8687                    new GrantUri(userId, uri, false));
8688            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8689                    new GrantUri(userId, uri, true));
8690
8691            final boolean exactValid = (exactPerm != null)
8692                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8693            final boolean prefixValid = (prefixPerm != null)
8694                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8695
8696            if (!(exactValid || prefixValid)) {
8697                throw new SecurityException("No persistable permission grants found for UID "
8698                        + callingUid + " and Uri " + grantUri.toSafeString());
8699            }
8700
8701            if (exactValid) {
8702                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8703            }
8704            if (prefixValid) {
8705                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8706            }
8707
8708            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8709
8710            if (persistChanged) {
8711                schedulePersistUriGrants();
8712            }
8713        }
8714    }
8715
8716    /**
8717     * @param uri This uri must NOT contain an embedded userId.
8718     * @param userId The userId in which the uri is to be resolved.
8719     */
8720    @Override
8721    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8722        enforceNotIsolatedCaller("releasePersistableUriPermission");
8723
8724        Preconditions.checkFlagsArgument(modeFlags,
8725                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8726
8727        synchronized (this) {
8728            final int callingUid = Binder.getCallingUid();
8729            boolean persistChanged = false;
8730
8731            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8732                    new GrantUri(userId, uri, false));
8733            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8734                    new GrantUri(userId, uri, true));
8735            if (exactPerm == null && prefixPerm == null) {
8736                throw new SecurityException("No permission grants found for UID " + callingUid
8737                        + " and Uri " + uri.toSafeString());
8738            }
8739
8740            if (exactPerm != null) {
8741                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8742                removeUriPermissionIfNeededLocked(exactPerm);
8743            }
8744            if (prefixPerm != null) {
8745                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8746                removeUriPermissionIfNeededLocked(prefixPerm);
8747            }
8748
8749            if (persistChanged) {
8750                schedulePersistUriGrants();
8751            }
8752        }
8753    }
8754
8755    /**
8756     * Prune any older {@link UriPermission} for the given UID until outstanding
8757     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8758     *
8759     * @return if any mutations occured that require persisting.
8760     */
8761    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8762        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8763        if (perms == null) return false;
8764        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8765
8766        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8767        for (UriPermission perm : perms.values()) {
8768            if (perm.persistedModeFlags != 0) {
8769                persisted.add(perm);
8770            }
8771        }
8772
8773        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8774        if (trimCount <= 0) return false;
8775
8776        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8777        for (int i = 0; i < trimCount; i++) {
8778            final UriPermission perm = persisted.get(i);
8779
8780            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8781                    "Trimming grant created at " + perm.persistedCreateTime);
8782
8783            perm.releasePersistableModes(~0);
8784            removeUriPermissionIfNeededLocked(perm);
8785        }
8786
8787        return true;
8788    }
8789
8790    @Override
8791    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8792            String packageName, boolean incoming) {
8793        enforceNotIsolatedCaller("getPersistedUriPermissions");
8794        Preconditions.checkNotNull(packageName, "packageName");
8795
8796        final int callingUid = Binder.getCallingUid();
8797        final IPackageManager pm = AppGlobals.getPackageManager();
8798        try {
8799            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8800                    UserHandle.getUserId(callingUid));
8801            if (packageUid != callingUid) {
8802                throw new SecurityException(
8803                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8804            }
8805        } catch (RemoteException e) {
8806            throw new SecurityException("Failed to verify package name ownership");
8807        }
8808
8809        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8810        synchronized (this) {
8811            if (incoming) {
8812                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8813                        callingUid);
8814                if (perms == null) {
8815                    Slog.w(TAG, "No permission grants found for " + packageName);
8816                } else {
8817                    final int userId = UserHandle.getUserId(callingUid);
8818                    Set<String> existingAuthorities = null;
8819
8820                    for (UriPermission perm : perms.values()) {
8821                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8822                            // Is this provider available in the current boot state? If the user
8823                            // is not running and unlocked we check if the provider package exists.
8824                            if (!mUserController.isUserRunningLocked(userId,
8825                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8826                                String authority = perm.uri.uri.getAuthority();
8827                                if (existingAuthorities == null
8828                                        || !existingAuthorities.contains(authority)) {
8829                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8830                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8831                                    if (providerInfo != null) {
8832                                        if (existingAuthorities == null) {
8833                                            existingAuthorities = new ArraySet<>();
8834                                        }
8835                                        existingAuthorities.add(authority);
8836                                    } else {
8837                                        continue;
8838                                    }
8839                                }
8840                            }
8841                            result.add(perm.buildPersistedPublicApiObject());
8842                        }
8843                    }
8844                }
8845            } else {
8846                final int size = mGrantedUriPermissions.size();
8847                for (int i = 0; i < size; i++) {
8848                    final ArrayMap<GrantUri, UriPermission> perms =
8849                            mGrantedUriPermissions.valueAt(i);
8850                    for (UriPermission perm : perms.values()) {
8851                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8852                            result.add(perm.buildPersistedPublicApiObject());
8853                        }
8854                    }
8855                }
8856            }
8857        }
8858        return new ParceledListSlice<android.content.UriPermission>(result);
8859    }
8860
8861    @Override
8862    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8863            String packageName, int userId) {
8864        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8865                "getGrantedUriPermissions");
8866
8867        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8868        synchronized (this) {
8869            final int size = mGrantedUriPermissions.size();
8870            for (int i = 0; i < size; i++) {
8871                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8872                for (UriPermission perm : perms.values()) {
8873                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8874                            && perm.persistedModeFlags != 0) {
8875                        result.add(perm.buildPersistedPublicApiObject());
8876                    }
8877                }
8878            }
8879        }
8880        return new ParceledListSlice<android.content.UriPermission>(result);
8881    }
8882
8883    @Override
8884    public void clearGrantedUriPermissions(String packageName, int userId) {
8885        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8886                "clearGrantedUriPermissions");
8887        removeUriPermissionsForPackageLocked(packageName, userId, true);
8888    }
8889
8890    @Override
8891    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8892        synchronized (this) {
8893            ProcessRecord app =
8894                who != null ? getRecordForAppLocked(who) : null;
8895            if (app == null) return;
8896
8897            Message msg = Message.obtain();
8898            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8899            msg.obj = app;
8900            msg.arg1 = waiting ? 1 : 0;
8901            mUiHandler.sendMessage(msg);
8902        }
8903    }
8904
8905    @Override
8906    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8907        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8908        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8909        outInfo.availMem = Process.getFreeMemory();
8910        outInfo.totalMem = Process.getTotalMemory();
8911        outInfo.threshold = homeAppMem;
8912        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8913        outInfo.hiddenAppThreshold = cachedAppMem;
8914        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8915                ProcessList.SERVICE_ADJ);
8916        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8917                ProcessList.VISIBLE_APP_ADJ);
8918        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8919                ProcessList.FOREGROUND_APP_ADJ);
8920    }
8921
8922    // =========================================================
8923    // TASK MANAGEMENT
8924    // =========================================================
8925
8926    @Override
8927    public List<IAppTask> getAppTasks(String callingPackage) {
8928        int callingUid = Binder.getCallingUid();
8929        long ident = Binder.clearCallingIdentity();
8930
8931        synchronized(this) {
8932            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8933            try {
8934                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8935
8936                final int N = mRecentTasks.size();
8937                for (int i = 0; i < N; i++) {
8938                    TaskRecord tr = mRecentTasks.get(i);
8939                    // Skip tasks that do not match the caller.  We don't need to verify
8940                    // callingPackage, because we are also limiting to callingUid and know
8941                    // that will limit to the correct security sandbox.
8942                    if (tr.effectiveUid != callingUid) {
8943                        continue;
8944                    }
8945                    Intent intent = tr.getBaseIntent();
8946                    if (intent == null ||
8947                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8948                        continue;
8949                    }
8950                    ActivityManager.RecentTaskInfo taskInfo =
8951                            createRecentTaskInfoFromTaskRecord(tr);
8952                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8953                    list.add(taskImpl);
8954                }
8955            } finally {
8956                Binder.restoreCallingIdentity(ident);
8957            }
8958            return list;
8959        }
8960    }
8961
8962    @Override
8963    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8964        final int callingUid = Binder.getCallingUid();
8965        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8966
8967        synchronized(this) {
8968            if (DEBUG_ALL) Slog.v(
8969                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8970
8971            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8972                    callingUid);
8973
8974            // TODO: Improve with MRU list from all ActivityStacks.
8975            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8976        }
8977
8978        return list;
8979    }
8980
8981    /**
8982     * Creates a new RecentTaskInfo from a TaskRecord.
8983     */
8984    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8985        // Update the task description to reflect any changes in the task stack
8986        tr.updateTaskDescription();
8987
8988        // Compose the recent task info
8989        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8990        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8991        rti.persistentId = tr.taskId;
8992        rti.baseIntent = new Intent(tr.getBaseIntent());
8993        rti.origActivity = tr.origActivity;
8994        rti.realActivity = tr.realActivity;
8995        rti.description = tr.lastDescription;
8996        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8997        rti.userId = tr.userId;
8998        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8999        rti.firstActiveTime = tr.firstActiveTime;
9000        rti.lastActiveTime = tr.lastActiveTime;
9001        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9002        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9003        rti.numActivities = 0;
9004        if (tr.mBounds != null) {
9005            rti.bounds = new Rect(tr.mBounds);
9006        }
9007        rti.isDockable = tr.canGoInDockedStack();
9008        rti.resizeMode = tr.mResizeMode;
9009
9010        ActivityRecord base = null;
9011        ActivityRecord top = null;
9012        ActivityRecord tmp;
9013
9014        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9015            tmp = tr.mActivities.get(i);
9016            if (tmp.finishing) {
9017                continue;
9018            }
9019            base = tmp;
9020            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9021                top = base;
9022            }
9023            rti.numActivities++;
9024        }
9025
9026        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9027        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9028
9029        return rti;
9030    }
9031
9032    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9033        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9034                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9035        if (!allowed) {
9036            if (checkPermission(android.Manifest.permission.GET_TASKS,
9037                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9038                // Temporary compatibility: some existing apps on the system image may
9039                // still be requesting the old permission and not switched to the new
9040                // one; if so, we'll still allow them full access.  This means we need
9041                // to see if they are holding the old permission and are a system app.
9042                try {
9043                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9044                        allowed = true;
9045                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9046                                + " is using old GET_TASKS but privileged; allowing");
9047                    }
9048                } catch (RemoteException e) {
9049                }
9050            }
9051        }
9052        if (!allowed) {
9053            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9054                    + " does not hold REAL_GET_TASKS; limiting output");
9055        }
9056        return allowed;
9057    }
9058
9059    @Override
9060    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9061        final int callingUid = Binder.getCallingUid();
9062        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9063                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9064
9065        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9066        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9067        synchronized (this) {
9068            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9069                    callingUid);
9070            final boolean detailed = checkCallingPermission(
9071                    android.Manifest.permission.GET_DETAILED_TASKS)
9072                    == PackageManager.PERMISSION_GRANTED;
9073
9074            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9075                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9076                return Collections.emptyList();
9077            }
9078            mRecentTasks.loadUserRecentsLocked(userId);
9079
9080            final int recentsCount = mRecentTasks.size();
9081            ArrayList<ActivityManager.RecentTaskInfo> res =
9082                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9083
9084            final Set<Integer> includedUsers;
9085            if (includeProfiles) {
9086                includedUsers = mUserController.getProfileIds(userId);
9087            } else {
9088                includedUsers = new HashSet<>();
9089            }
9090            includedUsers.add(Integer.valueOf(userId));
9091
9092            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9093                TaskRecord tr = mRecentTasks.get(i);
9094                // Only add calling user or related users recent tasks
9095                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9096                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9097                    continue;
9098                }
9099
9100                if (tr.realActivitySuspended) {
9101                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9102                    continue;
9103                }
9104
9105                // Return the entry if desired by the caller.  We always return
9106                // the first entry, because callers always expect this to be the
9107                // foreground app.  We may filter others if the caller has
9108                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9109                // we should exclude the entry.
9110
9111                if (i == 0
9112                        || withExcluded
9113                        || (tr.intent == null)
9114                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9115                                == 0)) {
9116                    if (!allowed) {
9117                        // If the caller doesn't have the GET_TASKS permission, then only
9118                        // allow them to see a small subset of tasks -- their own and home.
9119                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9120                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9121                            continue;
9122                        }
9123                    }
9124                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9125                        if (tr.stack != null && tr.stack.isHomeStack()) {
9126                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9127                                    "Skipping, home stack task: " + tr);
9128                            continue;
9129                        }
9130                    }
9131                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9132                        final ActivityStack stack = tr.stack;
9133                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9134                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9135                                    "Skipping, top task in docked stack: " + tr);
9136                            continue;
9137                        }
9138                    }
9139                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9140                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9141                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9142                                    "Skipping, pinned stack task: " + tr);
9143                            continue;
9144                        }
9145                    }
9146                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9147                        // Don't include auto remove tasks that are finished or finishing.
9148                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9149                                "Skipping, auto-remove without activity: " + tr);
9150                        continue;
9151                    }
9152                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9153                            && !tr.isAvailable) {
9154                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9155                                "Skipping, unavail real act: " + tr);
9156                        continue;
9157                    }
9158
9159                    if (!tr.mUserSetupComplete) {
9160                        // Don't include task launched while user is not done setting-up.
9161                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9162                                "Skipping, user setup not complete: " + tr);
9163                        continue;
9164                    }
9165
9166                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9167                    if (!detailed) {
9168                        rti.baseIntent.replaceExtras((Bundle)null);
9169                    }
9170
9171                    res.add(rti);
9172                    maxNum--;
9173                }
9174            }
9175            return res;
9176        }
9177    }
9178
9179    @Override
9180    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9181        synchronized (this) {
9182            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9183                    "getTaskThumbnail()");
9184            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9185                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9186            if (tr != null) {
9187                return tr.getTaskThumbnailLocked();
9188            }
9189        }
9190        return null;
9191    }
9192
9193    @Override
9194    public int addAppTask(IBinder activityToken, Intent intent,
9195            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9196        final int callingUid = Binder.getCallingUid();
9197        final long callingIdent = Binder.clearCallingIdentity();
9198
9199        try {
9200            synchronized (this) {
9201                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9202                if (r == null) {
9203                    throw new IllegalArgumentException("Activity does not exist; token="
9204                            + activityToken);
9205                }
9206                ComponentName comp = intent.getComponent();
9207                if (comp == null) {
9208                    throw new IllegalArgumentException("Intent " + intent
9209                            + " must specify explicit component");
9210                }
9211                if (thumbnail.getWidth() != mThumbnailWidth
9212                        || thumbnail.getHeight() != mThumbnailHeight) {
9213                    throw new IllegalArgumentException("Bad thumbnail size: got "
9214                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9215                            + mThumbnailWidth + "x" + mThumbnailHeight);
9216                }
9217                if (intent.getSelector() != null) {
9218                    intent.setSelector(null);
9219                }
9220                if (intent.getSourceBounds() != null) {
9221                    intent.setSourceBounds(null);
9222                }
9223                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9224                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9225                        // The caller has added this as an auto-remove task...  that makes no
9226                        // sense, so turn off auto-remove.
9227                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9228                    }
9229                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9230                    // Must be a new task.
9231                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9232                }
9233                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9234                    mLastAddedTaskActivity = null;
9235                }
9236                ActivityInfo ainfo = mLastAddedTaskActivity;
9237                if (ainfo == null) {
9238                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9239                            comp, 0, UserHandle.getUserId(callingUid));
9240                    if (ainfo.applicationInfo.uid != callingUid) {
9241                        throw new SecurityException(
9242                                "Can't add task for another application: target uid="
9243                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9244                    }
9245                }
9246
9247                // Use the full screen as the context for the task thumbnail
9248                final Point displaySize = new Point();
9249                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9250                r.task.stack.getDisplaySize(displaySize);
9251                thumbnailInfo.taskWidth = displaySize.x;
9252                thumbnailInfo.taskHeight = displaySize.y;
9253                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9254
9255                TaskRecord task = new TaskRecord(this,
9256                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9257                        ainfo, intent, description, thumbnailInfo);
9258
9259                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9260                if (trimIdx >= 0) {
9261                    // If this would have caused a trim, then we'll abort because that
9262                    // means it would be added at the end of the list but then just removed.
9263                    return INVALID_TASK_ID;
9264                }
9265
9266                final int N = mRecentTasks.size();
9267                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9268                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9269                    tr.removedFromRecents();
9270                }
9271
9272                task.inRecents = true;
9273                mRecentTasks.add(task);
9274                r.task.stack.addTask(task, false, "addAppTask");
9275
9276                task.setLastThumbnailLocked(thumbnail);
9277                task.freeLastThumbnail();
9278
9279                return task.taskId;
9280            }
9281        } finally {
9282            Binder.restoreCallingIdentity(callingIdent);
9283        }
9284    }
9285
9286    @Override
9287    public Point getAppTaskThumbnailSize() {
9288        synchronized (this) {
9289            return new Point(mThumbnailWidth,  mThumbnailHeight);
9290        }
9291    }
9292
9293    @Override
9294    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9295        synchronized (this) {
9296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9297            if (r != null) {
9298                r.setTaskDescription(td);
9299                r.task.updateTaskDescription();
9300            }
9301        }
9302    }
9303
9304    @Override
9305    public void setTaskResizeable(int taskId, int resizeableMode) {
9306        synchronized (this) {
9307            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9308                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9309            if (task == null) {
9310                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9311                return;
9312            }
9313            if (task.mResizeMode != resizeableMode) {
9314                task.mResizeMode = resizeableMode;
9315                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9316                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9317                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9318            }
9319        }
9320    }
9321
9322    @Override
9323    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9324        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9325        long ident = Binder.clearCallingIdentity();
9326        try {
9327            synchronized (this) {
9328                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9329                if (task == null) {
9330                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9331                    return;
9332                }
9333                int stackId = task.stack.mStackId;
9334                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9335                // in crop windows resize mode or if the task size is affected by the docked stack
9336                // changing size. No need to update configuration.
9337                if (bounds != null && task.inCropWindowsResizeMode()
9338                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9339                    mWindowManager.scrollTask(task.taskId, bounds);
9340                    return;
9341                }
9342
9343                // Place the task in the right stack if it isn't there already based on
9344                // the requested bounds.
9345                // The stack transition logic is:
9346                // - a null bounds on a freeform task moves that task to fullscreen
9347                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9348                //   that task to freeform
9349                // - otherwise the task is not moved
9350                if (!StackId.isTaskResizeAllowed(stackId)) {
9351                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9352                }
9353                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9354                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9355                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9356                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9357                }
9358                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9359                if (stackId != task.stack.mStackId) {
9360                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9361                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9362                    preserveWindow = false;
9363                }
9364
9365                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9366                        false /* deferResume */);
9367            }
9368        } finally {
9369            Binder.restoreCallingIdentity(ident);
9370        }
9371    }
9372
9373    @Override
9374    public Rect getTaskBounds(int taskId) {
9375        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9376        long ident = Binder.clearCallingIdentity();
9377        Rect rect = new Rect();
9378        try {
9379            synchronized (this) {
9380                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9381                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9382                if (task == null) {
9383                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9384                    return rect;
9385                }
9386                if (task.stack != null) {
9387                    // Return the bounds from window manager since it will be adjusted for various
9388                    // things like the presense of a docked stack for tasks that aren't resizeable.
9389                    mWindowManager.getTaskBounds(task.taskId, rect);
9390                } else {
9391                    // Task isn't in window manager yet since it isn't associated with a stack.
9392                    // Return the persist value from activity manager
9393                    if (task.mBounds != null) {
9394                        rect.set(task.mBounds);
9395                    } else if (task.mLastNonFullscreenBounds != null) {
9396                        rect.set(task.mLastNonFullscreenBounds);
9397                    }
9398                }
9399            }
9400        } finally {
9401            Binder.restoreCallingIdentity(ident);
9402        }
9403        return rect;
9404    }
9405
9406    @Override
9407    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9408        if (userId != UserHandle.getCallingUserId()) {
9409            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9410                    "getTaskDescriptionIcon");
9411        }
9412        final File passedIconFile = new File(filePath);
9413        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9414                passedIconFile.getName());
9415        if (!legitIconFile.getPath().equals(filePath)
9416                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9417            throw new IllegalArgumentException("Bad file path: " + filePath
9418                    + " passed for userId " + userId);
9419        }
9420        return mRecentTasks.getTaskDescriptionIcon(filePath);
9421    }
9422
9423    @Override
9424    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9425            throws RemoteException {
9426        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9427                opts.getCustomInPlaceResId() == 0) {
9428            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9429                    "with valid animation");
9430        }
9431        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9432        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9433                opts.getCustomInPlaceResId());
9434        mWindowManager.executeAppTransition();
9435    }
9436
9437    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9438            boolean removeFromRecents) {
9439        if (removeFromRecents) {
9440            mRecentTasks.remove(tr);
9441            tr.removedFromRecents();
9442        }
9443        ComponentName component = tr.getBaseIntent().getComponent();
9444        if (component == null) {
9445            Slog.w(TAG, "No component for base intent of task: " + tr);
9446            return;
9447        }
9448
9449        // Find any running services associated with this app and stop if needed.
9450        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9451
9452        if (!killProcess) {
9453            return;
9454        }
9455
9456        // Determine if the process(es) for this task should be killed.
9457        final String pkg = component.getPackageName();
9458        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9459        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9460        for (int i = 0; i < pmap.size(); i++) {
9461
9462            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9463            for (int j = 0; j < uids.size(); j++) {
9464                ProcessRecord proc = uids.valueAt(j);
9465                if (proc.userId != tr.userId) {
9466                    // Don't kill process for a different user.
9467                    continue;
9468                }
9469                if (proc == mHomeProcess) {
9470                    // Don't kill the home process along with tasks from the same package.
9471                    continue;
9472                }
9473                if (!proc.pkgList.containsKey(pkg)) {
9474                    // Don't kill process that is not associated with this task.
9475                    continue;
9476                }
9477
9478                for (int k = 0; k < proc.activities.size(); k++) {
9479                    TaskRecord otherTask = proc.activities.get(k).task;
9480                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9481                        // Don't kill process(es) that has an activity in a different task that is
9482                        // also in recents.
9483                        return;
9484                    }
9485                }
9486
9487                if (proc.foregroundServices) {
9488                    // Don't kill process(es) with foreground service.
9489                    return;
9490                }
9491
9492                // Add process to kill list.
9493                procsToKill.add(proc);
9494            }
9495        }
9496
9497        // Kill the running processes.
9498        for (int i = 0; i < procsToKill.size(); i++) {
9499            ProcessRecord pr = procsToKill.get(i);
9500            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9501                    && pr.curReceiver == null) {
9502                pr.kill("remove task", true);
9503            } else {
9504                // We delay killing processes that are not in the background or running a receiver.
9505                pr.waitingToKill = "remove task";
9506            }
9507        }
9508    }
9509
9510    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9511        // Remove all tasks with activities in the specified package from the list of recent tasks
9512        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9513            TaskRecord tr = mRecentTasks.get(i);
9514            if (tr.userId != userId) continue;
9515
9516            ComponentName cn = tr.intent.getComponent();
9517            if (cn != null && cn.getPackageName().equals(packageName)) {
9518                // If the package name matches, remove the task.
9519                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9520            }
9521        }
9522    }
9523
9524    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9525            int userId) {
9526
9527        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9528            TaskRecord tr = mRecentTasks.get(i);
9529            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9530                continue;
9531            }
9532
9533            ComponentName cn = tr.intent.getComponent();
9534            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9535                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9536            if (sameComponent) {
9537                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9538            }
9539        }
9540    }
9541
9542    /**
9543     * Removes the task with the specified task id.
9544     *
9545     * @param taskId Identifier of the task to be removed.
9546     * @param killProcess Kill any process associated with the task if possible.
9547     * @param removeFromRecents Whether to also remove the task from recents.
9548     * @return Returns true if the given task was found and removed.
9549     */
9550    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9551            boolean removeFromRecents) {
9552        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9553                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9554        if (tr != null) {
9555            tr.removeTaskActivitiesLocked();
9556            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9557            if (tr.isPersistable) {
9558                notifyTaskPersisterLocked(null, true);
9559            }
9560            return true;
9561        }
9562        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9563        return false;
9564    }
9565
9566    @Override
9567    public void removeStack(int stackId) {
9568        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9569        if (stackId == HOME_STACK_ID) {
9570            throw new IllegalArgumentException("Removing home stack is not allowed.");
9571        }
9572
9573        synchronized (this) {
9574            final long ident = Binder.clearCallingIdentity();
9575            try {
9576                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9577                if (stack == null) {
9578                    return;
9579                }
9580                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9581                for (int i = tasks.size() - 1; i >= 0; i--) {
9582                    removeTaskByIdLocked(
9583                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9584                }
9585            } finally {
9586                Binder.restoreCallingIdentity(ident);
9587            }
9588        }
9589    }
9590
9591    @Override
9592    public boolean removeTask(int taskId) {
9593        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9594        synchronized (this) {
9595            final long ident = Binder.clearCallingIdentity();
9596            try {
9597                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9598            } finally {
9599                Binder.restoreCallingIdentity(ident);
9600            }
9601        }
9602    }
9603
9604    /**
9605     * TODO: Add mController hook
9606     */
9607    @Override
9608    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9609        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9610
9611        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9612        synchronized(this) {
9613            moveTaskToFrontLocked(taskId, flags, bOptions);
9614        }
9615    }
9616
9617    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9618        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9619
9620        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9621                Binder.getCallingUid(), -1, -1, "Task to front")) {
9622            ActivityOptions.abort(options);
9623            return;
9624        }
9625        final long origId = Binder.clearCallingIdentity();
9626        try {
9627            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9628            if (task == null) {
9629                Slog.d(TAG, "Could not find task for id: "+ taskId);
9630                return;
9631            }
9632            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9633                mStackSupervisor.showLockTaskToast();
9634                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9635                return;
9636            }
9637            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9638            if (prev != null && prev.isRecentsActivity()) {
9639                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9640            }
9641            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9642                    false /* forceNonResizable */);
9643        } finally {
9644            Binder.restoreCallingIdentity(origId);
9645        }
9646        ActivityOptions.abort(options);
9647    }
9648
9649    /**
9650     * Moves an activity, and all of the other activities within the same task, to the bottom
9651     * of the history stack.  The activity's order within the task is unchanged.
9652     *
9653     * @param token A reference to the activity we wish to move
9654     * @param nonRoot If false then this only works if the activity is the root
9655     *                of a task; if true it will work for any activity in a task.
9656     * @return Returns true if the move completed, false if not.
9657     */
9658    @Override
9659    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9660        enforceNotIsolatedCaller("moveActivityTaskToBack");
9661        synchronized(this) {
9662            final long origId = Binder.clearCallingIdentity();
9663            try {
9664                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9665                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9666                if (task != null) {
9667                    if (mStackSupervisor.isLockedTask(task)) {
9668                        mStackSupervisor.showLockTaskToast();
9669                        return false;
9670                    }
9671                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9672                }
9673            } finally {
9674                Binder.restoreCallingIdentity(origId);
9675            }
9676        }
9677        return false;
9678    }
9679
9680    @Override
9681    public void moveTaskBackwards(int task) {
9682        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9683                "moveTaskBackwards()");
9684
9685        synchronized(this) {
9686            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9687                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9688                return;
9689            }
9690            final long origId = Binder.clearCallingIdentity();
9691            moveTaskBackwardsLocked(task);
9692            Binder.restoreCallingIdentity(origId);
9693        }
9694    }
9695
9696    private final void moveTaskBackwardsLocked(int task) {
9697        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9698    }
9699
9700    @Override
9701    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9702            IActivityContainerCallback callback) throws RemoteException {
9703        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9704        synchronized (this) {
9705            if (parentActivityToken == null) {
9706                throw new IllegalArgumentException("parent token must not be null");
9707            }
9708            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9709            if (r == null) {
9710                return null;
9711            }
9712            if (callback == null) {
9713                throw new IllegalArgumentException("callback must not be null");
9714            }
9715            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9716        }
9717    }
9718
9719    @Override
9720    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9721        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9722        synchronized (this) {
9723            mStackSupervisor.deleteActivityContainer(container);
9724        }
9725    }
9726
9727    @Override
9728    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9730        synchronized (this) {
9731            final int stackId = mStackSupervisor.getNextStackId();
9732            final ActivityStack stack =
9733                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9734            if (stack == null) {
9735                return null;
9736            }
9737            return stack.mActivityContainer;
9738        }
9739    }
9740
9741    @Override
9742    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9743        synchronized (this) {
9744            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9745            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9746                return stack.mActivityContainer.getDisplayId();
9747            }
9748            return Display.DEFAULT_DISPLAY;
9749        }
9750    }
9751
9752    @Override
9753    public int getActivityStackId(IBinder token) throws RemoteException {
9754        synchronized (this) {
9755            ActivityStack stack = ActivityRecord.getStackLocked(token);
9756            if (stack == null) {
9757                return INVALID_STACK_ID;
9758            }
9759            return stack.mStackId;
9760        }
9761    }
9762
9763    @Override
9764    public void exitFreeformMode(IBinder token) throws RemoteException {
9765        synchronized (this) {
9766            long ident = Binder.clearCallingIdentity();
9767            try {
9768                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9769                if (r == null) {
9770                    throw new IllegalArgumentException(
9771                            "exitFreeformMode: No activity record matching token=" + token);
9772                }
9773                final ActivityStack stack = r.getStackLocked(token);
9774                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9775                    throw new IllegalStateException(
9776                            "exitFreeformMode: You can only go fullscreen from freeform.");
9777                }
9778                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9779                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9780                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9781            } finally {
9782                Binder.restoreCallingIdentity(ident);
9783            }
9784        }
9785    }
9786
9787    @Override
9788    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9789        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9790        if (stackId == HOME_STACK_ID) {
9791            throw new IllegalArgumentException(
9792                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9793        }
9794        synchronized (this) {
9795            long ident = Binder.clearCallingIdentity();
9796            try {
9797                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9798                        + " to stackId=" + stackId + " toTop=" + toTop);
9799                if (stackId == DOCKED_STACK_ID) {
9800                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9801                            null /* initialBounds */);
9802                }
9803                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9804                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9805                if (result && stackId == DOCKED_STACK_ID) {
9806                    // If task moved to docked stack - show recents if needed.
9807                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9808                            "moveTaskToDockedStack");
9809                }
9810            } finally {
9811                Binder.restoreCallingIdentity(ident);
9812            }
9813        }
9814    }
9815
9816    @Override
9817    public void swapDockedAndFullscreenStack() throws RemoteException {
9818        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9819        synchronized (this) {
9820            long ident = Binder.clearCallingIdentity();
9821            try {
9822                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9823                        FULLSCREEN_WORKSPACE_STACK_ID);
9824                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9825                        : null;
9826                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9827                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9828                        : null;
9829                if (topTask == null || tasks == null || tasks.size() == 0) {
9830                    Slog.w(TAG,
9831                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9832                    return;
9833                }
9834
9835                // TODO: App transition
9836                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9837
9838                // Defer the resume so resume/pausing while moving stacks is dangerous.
9839                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9840                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9841                        ANIMATE, true /* deferResume */);
9842                final int size = tasks.size();
9843                for (int i = 0; i < size; i++) {
9844                    final int id = tasks.get(i).taskId;
9845                    if (id == topTask.taskId) {
9846                        continue;
9847                    }
9848                    mStackSupervisor.moveTaskToStackLocked(id,
9849                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9850                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9851                }
9852
9853                // Because we deferred the resume, to avoid conflicts with stack switches while
9854                // resuming, we need to do it after all the tasks are moved.
9855                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9856                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9857
9858                mWindowManager.executeAppTransition();
9859            } finally {
9860                Binder.restoreCallingIdentity(ident);
9861            }
9862        }
9863    }
9864
9865    /**
9866     * Moves the input task to the docked stack.
9867     *
9868     * @param taskId Id of task to move.
9869     * @param createMode The mode the docked stack should be created in if it doesn't exist
9870     *                   already. See
9871     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9872     *                   and
9873     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9874     * @param toTop If the task and stack should be moved to the top.
9875     * @param animate Whether we should play an animation for the moving the task
9876     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9877     *                      docked stack. Pass {@code null} to use default bounds.
9878     */
9879    @Override
9880    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9881            Rect initialBounds, boolean moveHomeStackFront) {
9882        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9883        synchronized (this) {
9884            long ident = Binder.clearCallingIdentity();
9885            try {
9886                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9887                        + " to createMode=" + createMode + " toTop=" + toTop);
9888                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9889                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9890                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9891                        animate, DEFER_RESUME);
9892                if (moved) {
9893                    if (moveHomeStackFront) {
9894                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9895                    }
9896                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9897                }
9898                return moved;
9899            } finally {
9900                Binder.restoreCallingIdentity(ident);
9901            }
9902        }
9903    }
9904
9905    /**
9906     * Moves the top activity in the input stackId to the pinned stack.
9907     *
9908     * @param stackId Id of stack to move the top activity to pinned stack.
9909     * @param bounds Bounds to use for pinned stack.
9910     *
9911     * @return True if the top activity of the input stack was successfully moved to the pinned
9912     *          stack.
9913     */
9914    @Override
9915    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9916        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9917        synchronized (this) {
9918            if (!mSupportsPictureInPicture) {
9919                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9920                        + "Device doesn't support picture-in-pciture mode");
9921            }
9922
9923            long ident = Binder.clearCallingIdentity();
9924            try {
9925                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9926            } finally {
9927                Binder.restoreCallingIdentity(ident);
9928            }
9929        }
9930    }
9931
9932    @Override
9933    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9934            boolean preserveWindows, boolean animate, int animationDuration) {
9935        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9936        long ident = Binder.clearCallingIdentity();
9937        try {
9938            synchronized (this) {
9939                if (animate) {
9940                    if (stackId == PINNED_STACK_ID) {
9941                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9942                    } else {
9943                        throw new IllegalArgumentException("Stack: " + stackId
9944                                + " doesn't support animated resize.");
9945                    }
9946                } else {
9947                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9948                            null /* tempTaskInsetBounds */, preserveWindows,
9949                            allowResizeInDockedMode, !DEFER_RESUME);
9950                }
9951            }
9952        } finally {
9953            Binder.restoreCallingIdentity(ident);
9954        }
9955    }
9956
9957    @Override
9958    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9959            Rect tempDockedTaskInsetBounds,
9960            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9961        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9962                "resizeDockedStack()");
9963        long ident = Binder.clearCallingIdentity();
9964        try {
9965            synchronized (this) {
9966                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9967                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9968                        PRESERVE_WINDOWS);
9969            }
9970        } finally {
9971            Binder.restoreCallingIdentity(ident);
9972        }
9973    }
9974
9975    @Override
9976    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9977        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9978                "resizePinnedStack()");
9979        final long ident = Binder.clearCallingIdentity();
9980        try {
9981            synchronized (this) {
9982                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9983            }
9984        } finally {
9985            Binder.restoreCallingIdentity(ident);
9986        }
9987    }
9988
9989    @Override
9990    public void positionTaskInStack(int taskId, int stackId, int position) {
9991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9992        if (stackId == HOME_STACK_ID) {
9993            throw new IllegalArgumentException(
9994                    "positionTaskInStack: Attempt to change the position of task "
9995                    + taskId + " in/to home stack");
9996        }
9997        synchronized (this) {
9998            long ident = Binder.clearCallingIdentity();
9999            try {
10000                if (DEBUG_STACK) Slog.d(TAG_STACK,
10001                        "positionTaskInStack: positioning task=" + taskId
10002                        + " in stackId=" + stackId + " at position=" + position);
10003                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10004            } finally {
10005                Binder.restoreCallingIdentity(ident);
10006            }
10007        }
10008    }
10009
10010    @Override
10011    public List<StackInfo> getAllStackInfos() {
10012        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10013        long ident = Binder.clearCallingIdentity();
10014        try {
10015            synchronized (this) {
10016                return mStackSupervisor.getAllStackInfosLocked();
10017            }
10018        } finally {
10019            Binder.restoreCallingIdentity(ident);
10020        }
10021    }
10022
10023    @Override
10024    public StackInfo getStackInfo(int stackId) {
10025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10026        long ident = Binder.clearCallingIdentity();
10027        try {
10028            synchronized (this) {
10029                return mStackSupervisor.getStackInfoLocked(stackId);
10030            }
10031        } finally {
10032            Binder.restoreCallingIdentity(ident);
10033        }
10034    }
10035
10036    @Override
10037    public boolean isInHomeStack(int taskId) {
10038        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10039        long ident = Binder.clearCallingIdentity();
10040        try {
10041            synchronized (this) {
10042                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10043                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10044                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10045            }
10046        } finally {
10047            Binder.restoreCallingIdentity(ident);
10048        }
10049    }
10050
10051    @Override
10052    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10053        synchronized(this) {
10054            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10055        }
10056    }
10057
10058    @Override
10059    public void updateDeviceOwner(String packageName) {
10060        final int callingUid = Binder.getCallingUid();
10061        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10062            throw new SecurityException("updateDeviceOwner called from non-system process");
10063        }
10064        synchronized (this) {
10065            mDeviceOwnerName = packageName;
10066        }
10067    }
10068
10069    @Override
10070    public void updateLockTaskPackages(int userId, String[] packages) {
10071        final int callingUid = Binder.getCallingUid();
10072        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10073            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10074                    "updateLockTaskPackages()");
10075        }
10076        synchronized (this) {
10077            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10078                    Arrays.toString(packages));
10079            mLockTaskPackages.put(userId, packages);
10080            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10081        }
10082    }
10083
10084
10085    void startLockTaskModeLocked(TaskRecord task) {
10086        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10087        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10088            return;
10089        }
10090
10091        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10092        // is initiated by system after the pinning request was shown and locked mode is initiated
10093        // by an authorized app directly
10094        final int callingUid = Binder.getCallingUid();
10095        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10096        long ident = Binder.clearCallingIdentity();
10097        try {
10098            if (!isSystemInitiated) {
10099                task.mLockTaskUid = callingUid;
10100                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10101                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10102                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10103                    StatusBarManagerInternal statusBarManager =
10104                            LocalServices.getService(StatusBarManagerInternal.class);
10105                    if (statusBarManager != null) {
10106                        statusBarManager.showScreenPinningRequest(task.taskId);
10107                    }
10108                    return;
10109                }
10110
10111                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10112                if (stack == null || task != stack.topTask()) {
10113                    throw new IllegalArgumentException("Invalid task, not in foreground");
10114                }
10115            }
10116            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10117                    "Locking fully");
10118            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10119                    ActivityManager.LOCK_TASK_MODE_PINNED :
10120                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10121                    "startLockTask", true);
10122        } finally {
10123            Binder.restoreCallingIdentity(ident);
10124        }
10125    }
10126
10127    @Override
10128    public void startLockTaskMode(int taskId) {
10129        synchronized (this) {
10130            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10131            if (task != null) {
10132                startLockTaskModeLocked(task);
10133            }
10134        }
10135    }
10136
10137    @Override
10138    public void startLockTaskMode(IBinder token) {
10139        synchronized (this) {
10140            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10141            if (r == null) {
10142                return;
10143            }
10144            final TaskRecord task = r.task;
10145            if (task != null) {
10146                startLockTaskModeLocked(task);
10147            }
10148        }
10149    }
10150
10151    @Override
10152    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10153        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10154        // This makes inner call to look as if it was initiated by system.
10155        long ident = Binder.clearCallingIdentity();
10156        try {
10157            synchronized (this) {
10158                startLockTaskMode(taskId);
10159            }
10160        } finally {
10161            Binder.restoreCallingIdentity(ident);
10162        }
10163    }
10164
10165    @Override
10166    public void stopLockTaskMode() {
10167        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10168        if (lockTask == null) {
10169            // Our work here is done.
10170            return;
10171        }
10172
10173        final int callingUid = Binder.getCallingUid();
10174        final int lockTaskUid = lockTask.mLockTaskUid;
10175        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10176        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10177            // Done.
10178            return;
10179        } else {
10180            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10181            // It is possible lockTaskMode was started by the system process because
10182            // android:lockTaskMode is set to a locking value in the application manifest
10183            // instead of the app calling startLockTaskMode. In this case
10184            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10185            // {@link TaskRecord.effectiveUid} instead. Also caller with
10186            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10187            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10188                    && callingUid != lockTaskUid
10189                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10190                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10191                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10192            }
10193        }
10194        long ident = Binder.clearCallingIdentity();
10195        try {
10196            Log.d(TAG, "stopLockTaskMode");
10197            // Stop lock task
10198            synchronized (this) {
10199                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10200                        "stopLockTask", true);
10201            }
10202            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10203            if (tm != null) {
10204                tm.showInCallScreen(false);
10205            }
10206        } finally {
10207            Binder.restoreCallingIdentity(ident);
10208        }
10209    }
10210
10211    /**
10212     * This API should be called by SystemUI only when user perform certain action to dismiss
10213     * lock task mode. We should only dismiss pinned lock task mode in this case.
10214     */
10215    @Override
10216    public void stopSystemLockTaskMode() throws RemoteException {
10217        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10218            stopLockTaskMode();
10219        } else {
10220            mStackSupervisor.showLockTaskToast();
10221        }
10222    }
10223
10224    @Override
10225    public boolean isInLockTaskMode() {
10226        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10227    }
10228
10229    @Override
10230    public int getLockTaskModeState() {
10231        synchronized (this) {
10232            return mStackSupervisor.getLockTaskModeState();
10233        }
10234    }
10235
10236    @Override
10237    public void showLockTaskEscapeMessage(IBinder token) {
10238        synchronized (this) {
10239            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10240            if (r == null) {
10241                return;
10242            }
10243            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10244        }
10245    }
10246
10247    // =========================================================
10248    // CONTENT PROVIDERS
10249    // =========================================================
10250
10251    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10252        List<ProviderInfo> providers = null;
10253        try {
10254            providers = AppGlobals.getPackageManager()
10255                    .queryContentProviders(app.processName, app.uid,
10256                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10257                                    | MATCH_DEBUG_TRIAGED_MISSING)
10258                    .getList();
10259        } catch (RemoteException ex) {
10260        }
10261        if (DEBUG_MU) Slog.v(TAG_MU,
10262                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10263        int userId = app.userId;
10264        if (providers != null) {
10265            int N = providers.size();
10266            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10267            for (int i=0; i<N; i++) {
10268                // TODO: keep logic in sync with installEncryptionUnawareProviders
10269                ProviderInfo cpi =
10270                    (ProviderInfo)providers.get(i);
10271                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10272                        cpi.name, cpi.flags);
10273                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10274                    // This is a singleton provider, but a user besides the
10275                    // default user is asking to initialize a process it runs
10276                    // in...  well, no, it doesn't actually run in this process,
10277                    // it runs in the process of the default user.  Get rid of it.
10278                    providers.remove(i);
10279                    N--;
10280                    i--;
10281                    continue;
10282                }
10283
10284                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10285                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10286                if (cpr == null) {
10287                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10288                    mProviderMap.putProviderByClass(comp, cpr);
10289                }
10290                if (DEBUG_MU) Slog.v(TAG_MU,
10291                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10292                app.pubProviders.put(cpi.name, cpr);
10293                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10294                    // Don't add this if it is a platform component that is marked
10295                    // to run in multiple processes, because this is actually
10296                    // part of the framework so doesn't make sense to track as a
10297                    // separate apk in the process.
10298                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10299                            mProcessStats);
10300                }
10301                notifyPackageUse(cpi.applicationInfo.packageName,
10302                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10303            }
10304        }
10305        return providers;
10306    }
10307
10308    /**
10309     * Check if {@link ProcessRecord} has a possible chance at accessing the
10310     * given {@link ProviderInfo}. Final permission checking is always done
10311     * in {@link ContentProvider}.
10312     */
10313    private final String checkContentProviderPermissionLocked(
10314            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10315        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10316        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10317        boolean checkedGrants = false;
10318        if (checkUser) {
10319            // Looking for cross-user grants before enforcing the typical cross-users permissions
10320            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10321            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10322                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10323                    return null;
10324                }
10325                checkedGrants = true;
10326            }
10327            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10328                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10329            if (userId != tmpTargetUserId) {
10330                // When we actually went to determine the final targer user ID, this ended
10331                // up different than our initial check for the authority.  This is because
10332                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10333                // SELF.  So we need to re-check the grants again.
10334                checkedGrants = false;
10335            }
10336        }
10337        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10338                cpi.applicationInfo.uid, cpi.exported)
10339                == PackageManager.PERMISSION_GRANTED) {
10340            return null;
10341        }
10342        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10343                cpi.applicationInfo.uid, cpi.exported)
10344                == PackageManager.PERMISSION_GRANTED) {
10345            return null;
10346        }
10347
10348        PathPermission[] pps = cpi.pathPermissions;
10349        if (pps != null) {
10350            int i = pps.length;
10351            while (i > 0) {
10352                i--;
10353                PathPermission pp = pps[i];
10354                String pprperm = pp.getReadPermission();
10355                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10356                        cpi.applicationInfo.uid, cpi.exported)
10357                        == PackageManager.PERMISSION_GRANTED) {
10358                    return null;
10359                }
10360                String ppwperm = pp.getWritePermission();
10361                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10362                        cpi.applicationInfo.uid, cpi.exported)
10363                        == PackageManager.PERMISSION_GRANTED) {
10364                    return null;
10365                }
10366            }
10367        }
10368        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10369            return null;
10370        }
10371
10372        String msg;
10373        if (!cpi.exported) {
10374            msg = "Permission Denial: opening provider " + cpi.name
10375                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10376                    + ", uid=" + callingUid + ") that is not exported from uid "
10377                    + cpi.applicationInfo.uid;
10378        } else {
10379            msg = "Permission Denial: opening provider " + cpi.name
10380                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10381                    + ", uid=" + callingUid + ") requires "
10382                    + cpi.readPermission + " or " + cpi.writePermission;
10383        }
10384        Slog.w(TAG, msg);
10385        return msg;
10386    }
10387
10388    /**
10389     * Returns if the ContentProvider has granted a uri to callingUid
10390     */
10391    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10392        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10393        if (perms != null) {
10394            for (int i=perms.size()-1; i>=0; i--) {
10395                GrantUri grantUri = perms.keyAt(i);
10396                if (grantUri.sourceUserId == userId || !checkUser) {
10397                    if (matchesProvider(grantUri.uri, cpi)) {
10398                        return true;
10399                    }
10400                }
10401            }
10402        }
10403        return false;
10404    }
10405
10406    /**
10407     * Returns true if the uri authority is one of the authorities specified in the provider.
10408     */
10409    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10410        String uriAuth = uri.getAuthority();
10411        String cpiAuth = cpi.authority;
10412        if (cpiAuth.indexOf(';') == -1) {
10413            return cpiAuth.equals(uriAuth);
10414        }
10415        String[] cpiAuths = cpiAuth.split(";");
10416        int length = cpiAuths.length;
10417        for (int i = 0; i < length; i++) {
10418            if (cpiAuths[i].equals(uriAuth)) return true;
10419        }
10420        return false;
10421    }
10422
10423    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10424            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10425        if (r != null) {
10426            for (int i=0; i<r.conProviders.size(); i++) {
10427                ContentProviderConnection conn = r.conProviders.get(i);
10428                if (conn.provider == cpr) {
10429                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10430                            "Adding provider requested by "
10431                            + r.processName + " from process "
10432                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10433                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10434                    if (stable) {
10435                        conn.stableCount++;
10436                        conn.numStableIncs++;
10437                    } else {
10438                        conn.unstableCount++;
10439                        conn.numUnstableIncs++;
10440                    }
10441                    return conn;
10442                }
10443            }
10444            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10445            if (stable) {
10446                conn.stableCount = 1;
10447                conn.numStableIncs = 1;
10448            } else {
10449                conn.unstableCount = 1;
10450                conn.numUnstableIncs = 1;
10451            }
10452            cpr.connections.add(conn);
10453            r.conProviders.add(conn);
10454            startAssociationLocked(r.uid, r.processName, r.curProcState,
10455                    cpr.uid, cpr.name, cpr.info.processName);
10456            return conn;
10457        }
10458        cpr.addExternalProcessHandleLocked(externalProcessToken);
10459        return null;
10460    }
10461
10462    boolean decProviderCountLocked(ContentProviderConnection conn,
10463            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10464        if (conn != null) {
10465            cpr = conn.provider;
10466            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10467                    "Removing provider requested by "
10468                    + conn.client.processName + " from process "
10469                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10470                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10471            if (stable) {
10472                conn.stableCount--;
10473            } else {
10474                conn.unstableCount--;
10475            }
10476            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10477                cpr.connections.remove(conn);
10478                conn.client.conProviders.remove(conn);
10479                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10480                    // The client is more important than last activity -- note the time this
10481                    // is happening, so we keep the old provider process around a bit as last
10482                    // activity to avoid thrashing it.
10483                    if (cpr.proc != null) {
10484                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10485                    }
10486                }
10487                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10488                return true;
10489            }
10490            return false;
10491        }
10492        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10493        return false;
10494    }
10495
10496    private void checkTime(long startTime, String where) {
10497        long now = SystemClock.uptimeMillis();
10498        if ((now-startTime) > 50) {
10499            // If we are taking more than 50ms, log about it.
10500            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10501        }
10502    }
10503
10504    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10505            String name, IBinder token, boolean stable, int userId) {
10506        ContentProviderRecord cpr;
10507        ContentProviderConnection conn = null;
10508        ProviderInfo cpi = null;
10509
10510        synchronized(this) {
10511            long startTime = SystemClock.uptimeMillis();
10512
10513            ProcessRecord r = null;
10514            if (caller != null) {
10515                r = getRecordForAppLocked(caller);
10516                if (r == null) {
10517                    throw new SecurityException(
10518                            "Unable to find app for caller " + caller
10519                          + " (pid=" + Binder.getCallingPid()
10520                          + ") when getting content provider " + name);
10521                }
10522            }
10523
10524            boolean checkCrossUser = true;
10525
10526            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10527
10528            // First check if this content provider has been published...
10529            cpr = mProviderMap.getProviderByName(name, userId);
10530            // If that didn't work, check if it exists for user 0 and then
10531            // verify that it's a singleton provider before using it.
10532            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10533                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10534                if (cpr != null) {
10535                    cpi = cpr.info;
10536                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10537                            cpi.name, cpi.flags)
10538                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10539                        userId = UserHandle.USER_SYSTEM;
10540                        checkCrossUser = false;
10541                    } else {
10542                        cpr = null;
10543                        cpi = null;
10544                    }
10545                }
10546            }
10547
10548            boolean providerRunning = cpr != null;
10549            if (providerRunning) {
10550                cpi = cpr.info;
10551                String msg;
10552                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10553                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10554                        != null) {
10555                    throw new SecurityException(msg);
10556                }
10557                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10558
10559                if (r != null && cpr.canRunHere(r)) {
10560                    // This provider has been published or is in the process
10561                    // of being published...  but it is also allowed to run
10562                    // in the caller's process, so don't make a connection
10563                    // and just let the caller instantiate its own instance.
10564                    ContentProviderHolder holder = cpr.newHolder(null);
10565                    // don't give caller the provider object, it needs
10566                    // to make its own.
10567                    holder.provider = null;
10568                    return holder;
10569                }
10570
10571                final long origId = Binder.clearCallingIdentity();
10572
10573                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10574
10575                // In this case the provider instance already exists, so we can
10576                // return it right away.
10577                conn = incProviderCountLocked(r, cpr, token, stable);
10578                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10579                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10580                        // If this is a perceptible app accessing the provider,
10581                        // make sure to count it as being accessed and thus
10582                        // back up on the LRU list.  This is good because
10583                        // content providers are often expensive to start.
10584                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10585                        updateLruProcessLocked(cpr.proc, false, null);
10586                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10587                    }
10588                }
10589
10590                if (cpr.proc != null) {
10591                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10592                    boolean success = updateOomAdjLocked(cpr.proc);
10593                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10594                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10595                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10596                    // NOTE: there is still a race here where a signal could be
10597                    // pending on the process even though we managed to update its
10598                    // adj level.  Not sure what to do about this, but at least
10599                    // the race is now smaller.
10600                    if (!success) {
10601                        // Uh oh...  it looks like the provider's process
10602                        // has been killed on us.  We need to wait for a new
10603                        // process to be started, and make sure its death
10604                        // doesn't kill our process.
10605                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10606                                + " is crashing; detaching " + r);
10607                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10608                        checkTime(startTime, "getContentProviderImpl: before appDied");
10609                        appDiedLocked(cpr.proc);
10610                        checkTime(startTime, "getContentProviderImpl: after appDied");
10611                        if (!lastRef) {
10612                            // This wasn't the last ref our process had on
10613                            // the provider...  we have now been killed, bail.
10614                            return null;
10615                        }
10616                        providerRunning = false;
10617                        conn = null;
10618                    }
10619                }
10620
10621                Binder.restoreCallingIdentity(origId);
10622            }
10623
10624            if (!providerRunning) {
10625                try {
10626                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10627                    cpi = AppGlobals.getPackageManager().
10628                        resolveContentProvider(name,
10629                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10630                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10631                } catch (RemoteException ex) {
10632                }
10633                if (cpi == null) {
10634                    return null;
10635                }
10636                // If the provider is a singleton AND
10637                // (it's a call within the same user || the provider is a
10638                // privileged app)
10639                // Then allow connecting to the singleton provider
10640                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10641                        cpi.name, cpi.flags)
10642                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10643                if (singleton) {
10644                    userId = UserHandle.USER_SYSTEM;
10645                }
10646                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10647                checkTime(startTime, "getContentProviderImpl: got app info for user");
10648
10649                String msg;
10650                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10651                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10652                        != null) {
10653                    throw new SecurityException(msg);
10654                }
10655                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10656
10657                if (!mProcessesReady
10658                        && !cpi.processName.equals("system")) {
10659                    // If this content provider does not run in the system
10660                    // process, and the system is not yet ready to run other
10661                    // processes, then fail fast instead of hanging.
10662                    throw new IllegalArgumentException(
10663                            "Attempt to launch content provider before system ready");
10664                }
10665
10666                // Make sure that the user who owns this provider is running.  If not,
10667                // we don't want to allow it to run.
10668                if (!mUserController.isUserRunningLocked(userId, 0)) {
10669                    Slog.w(TAG, "Unable to launch app "
10670                            + cpi.applicationInfo.packageName + "/"
10671                            + cpi.applicationInfo.uid + " for provider "
10672                            + name + ": user " + userId + " is stopped");
10673                    return null;
10674                }
10675
10676                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10677                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10678                cpr = mProviderMap.getProviderByClass(comp, userId);
10679                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10680                final boolean firstClass = cpr == null;
10681                if (firstClass) {
10682                    final long ident = Binder.clearCallingIdentity();
10683
10684                    // If permissions need a review before any of the app components can run,
10685                    // we return no provider and launch a review activity if the calling app
10686                    // is in the foreground.
10687                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10688                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10689                            return null;
10690                        }
10691                    }
10692
10693                    try {
10694                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10695                        ApplicationInfo ai =
10696                            AppGlobals.getPackageManager().
10697                                getApplicationInfo(
10698                                        cpi.applicationInfo.packageName,
10699                                        STOCK_PM_FLAGS, userId);
10700                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10701                        if (ai == null) {
10702                            Slog.w(TAG, "No package info for content provider "
10703                                    + cpi.name);
10704                            return null;
10705                        }
10706                        ai = getAppInfoForUser(ai, userId);
10707                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10708                    } catch (RemoteException ex) {
10709                        // pm is in same process, this will never happen.
10710                    } finally {
10711                        Binder.restoreCallingIdentity(ident);
10712                    }
10713                }
10714
10715                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10716
10717                if (r != null && cpr.canRunHere(r)) {
10718                    // If this is a multiprocess provider, then just return its
10719                    // info and allow the caller to instantiate it.  Only do
10720                    // this if the provider is the same user as the caller's
10721                    // process, or can run as root (so can be in any process).
10722                    return cpr.newHolder(null);
10723                }
10724
10725                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10726                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10727                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10728
10729                // This is single process, and our app is now connecting to it.
10730                // See if we are already in the process of launching this
10731                // provider.
10732                final int N = mLaunchingProviders.size();
10733                int i;
10734                for (i = 0; i < N; i++) {
10735                    if (mLaunchingProviders.get(i) == cpr) {
10736                        break;
10737                    }
10738                }
10739
10740                // If the provider is not already being launched, then get it
10741                // started.
10742                if (i >= N) {
10743                    final long origId = Binder.clearCallingIdentity();
10744
10745                    try {
10746                        // Content provider is now in use, its package can't be stopped.
10747                        try {
10748                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10749                            AppGlobals.getPackageManager().setPackageStoppedState(
10750                                    cpr.appInfo.packageName, false, userId);
10751                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10752                        } catch (RemoteException e) {
10753                        } catch (IllegalArgumentException e) {
10754                            Slog.w(TAG, "Failed trying to unstop package "
10755                                    + cpr.appInfo.packageName + ": " + e);
10756                        }
10757
10758                        // Use existing process if already started
10759                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10760                        ProcessRecord proc = getProcessRecordLocked(
10761                                cpi.processName, cpr.appInfo.uid, false);
10762                        if (proc != null && proc.thread != null) {
10763                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10764                                    "Installing in existing process " + proc);
10765                            if (!proc.pubProviders.containsKey(cpi.name)) {
10766                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10767                                proc.pubProviders.put(cpi.name, cpr);
10768                                try {
10769                                    proc.thread.scheduleInstallProvider(cpi);
10770                                } catch (RemoteException e) {
10771                                }
10772                            }
10773                        } else {
10774                            checkTime(startTime, "getContentProviderImpl: before start process");
10775                            proc = startProcessLocked(cpi.processName,
10776                                    cpr.appInfo, false, 0, "content provider",
10777                                    new ComponentName(cpi.applicationInfo.packageName,
10778                                            cpi.name), false, false, false);
10779                            checkTime(startTime, "getContentProviderImpl: after start process");
10780                            if (proc == null) {
10781                                Slog.w(TAG, "Unable to launch app "
10782                                        + cpi.applicationInfo.packageName + "/"
10783                                        + cpi.applicationInfo.uid + " for provider "
10784                                        + name + ": process is bad");
10785                                return null;
10786                            }
10787                        }
10788                        cpr.launchingApp = proc;
10789                        mLaunchingProviders.add(cpr);
10790                    } finally {
10791                        Binder.restoreCallingIdentity(origId);
10792                    }
10793                }
10794
10795                checkTime(startTime, "getContentProviderImpl: updating data structures");
10796
10797                // Make sure the provider is published (the same provider class
10798                // may be published under multiple names).
10799                if (firstClass) {
10800                    mProviderMap.putProviderByClass(comp, cpr);
10801                }
10802
10803                mProviderMap.putProviderByName(name, cpr);
10804                conn = incProviderCountLocked(r, cpr, token, stable);
10805                if (conn != null) {
10806                    conn.waiting = true;
10807                }
10808            }
10809            checkTime(startTime, "getContentProviderImpl: done!");
10810        }
10811
10812        // Wait for the provider to be published...
10813        synchronized (cpr) {
10814            while (cpr.provider == null) {
10815                if (cpr.launchingApp == null) {
10816                    Slog.w(TAG, "Unable to launch app "
10817                            + cpi.applicationInfo.packageName + "/"
10818                            + cpi.applicationInfo.uid + " for provider "
10819                            + name + ": launching app became null");
10820                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10821                            UserHandle.getUserId(cpi.applicationInfo.uid),
10822                            cpi.applicationInfo.packageName,
10823                            cpi.applicationInfo.uid, name);
10824                    return null;
10825                }
10826                try {
10827                    if (DEBUG_MU) Slog.v(TAG_MU,
10828                            "Waiting to start provider " + cpr
10829                            + " launchingApp=" + cpr.launchingApp);
10830                    if (conn != null) {
10831                        conn.waiting = true;
10832                    }
10833                    cpr.wait();
10834                } catch (InterruptedException ex) {
10835                } finally {
10836                    if (conn != null) {
10837                        conn.waiting = false;
10838                    }
10839                }
10840            }
10841        }
10842        return cpr != null ? cpr.newHolder(conn) : null;
10843    }
10844
10845    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10846            ProcessRecord r, final int userId) {
10847        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10848                cpi.packageName, userId)) {
10849
10850            final boolean callerForeground = r == null || r.setSchedGroup
10851                    != ProcessList.SCHED_GROUP_BACKGROUND;
10852
10853            // Show a permission review UI only for starting from a foreground app
10854            if (!callerForeground) {
10855                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10856                        + cpi.packageName + " requires a permissions review");
10857                return false;
10858            }
10859
10860            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10861            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10862                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10863            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10864
10865            if (DEBUG_PERMISSIONS_REVIEW) {
10866                Slog.i(TAG, "u" + userId + " Launching permission review "
10867                        + "for package " + cpi.packageName);
10868            }
10869
10870            final UserHandle userHandle = new UserHandle(userId);
10871            mHandler.post(new Runnable() {
10872                @Override
10873                public void run() {
10874                    mContext.startActivityAsUser(intent, userHandle);
10875                }
10876            });
10877
10878            return false;
10879        }
10880
10881        return true;
10882    }
10883
10884    PackageManagerInternal getPackageManagerInternalLocked() {
10885        if (mPackageManagerInt == null) {
10886            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10887        }
10888        return mPackageManagerInt;
10889    }
10890
10891    @Override
10892    public final ContentProviderHolder getContentProvider(
10893            IApplicationThread caller, String name, int userId, boolean stable) {
10894        enforceNotIsolatedCaller("getContentProvider");
10895        if (caller == null) {
10896            String msg = "null IApplicationThread when getting content provider "
10897                    + name;
10898            Slog.w(TAG, msg);
10899            throw new SecurityException(msg);
10900        }
10901        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10902        // with cross-user grant.
10903        return getContentProviderImpl(caller, name, null, stable, userId);
10904    }
10905
10906    public ContentProviderHolder getContentProviderExternal(
10907            String name, int userId, IBinder token) {
10908        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10909            "Do not have permission in call getContentProviderExternal()");
10910        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10911                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10912        return getContentProviderExternalUnchecked(name, token, userId);
10913    }
10914
10915    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10916            IBinder token, int userId) {
10917        return getContentProviderImpl(null, name, token, true, userId);
10918    }
10919
10920    /**
10921     * Drop a content provider from a ProcessRecord's bookkeeping
10922     */
10923    public void removeContentProvider(IBinder connection, boolean stable) {
10924        enforceNotIsolatedCaller("removeContentProvider");
10925        long ident = Binder.clearCallingIdentity();
10926        try {
10927            synchronized (this) {
10928                ContentProviderConnection conn;
10929                try {
10930                    conn = (ContentProviderConnection)connection;
10931                } catch (ClassCastException e) {
10932                    String msg ="removeContentProvider: " + connection
10933                            + " not a ContentProviderConnection";
10934                    Slog.w(TAG, msg);
10935                    throw new IllegalArgumentException(msg);
10936                }
10937                if (conn == null) {
10938                    throw new NullPointerException("connection is null");
10939                }
10940                if (decProviderCountLocked(conn, null, null, stable)) {
10941                    updateOomAdjLocked();
10942                }
10943            }
10944        } finally {
10945            Binder.restoreCallingIdentity(ident);
10946        }
10947    }
10948
10949    public void removeContentProviderExternal(String name, IBinder token) {
10950        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10951            "Do not have permission in call removeContentProviderExternal()");
10952        int userId = UserHandle.getCallingUserId();
10953        long ident = Binder.clearCallingIdentity();
10954        try {
10955            removeContentProviderExternalUnchecked(name, token, userId);
10956        } finally {
10957            Binder.restoreCallingIdentity(ident);
10958        }
10959    }
10960
10961    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10962        synchronized (this) {
10963            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10964            if(cpr == null) {
10965                //remove from mProvidersByClass
10966                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10967                return;
10968            }
10969
10970            //update content provider record entry info
10971            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10972            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10973            if (localCpr.hasExternalProcessHandles()) {
10974                if (localCpr.removeExternalProcessHandleLocked(token)) {
10975                    updateOomAdjLocked();
10976                } else {
10977                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10978                            + " with no external reference for token: "
10979                            + token + ".");
10980                }
10981            } else {
10982                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10983                        + " with no external references.");
10984            }
10985        }
10986    }
10987
10988    public final void publishContentProviders(IApplicationThread caller,
10989            List<ContentProviderHolder> providers) {
10990        if (providers == null) {
10991            return;
10992        }
10993
10994        enforceNotIsolatedCaller("publishContentProviders");
10995        synchronized (this) {
10996            final ProcessRecord r = getRecordForAppLocked(caller);
10997            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10998            if (r == null) {
10999                throw new SecurityException(
11000                        "Unable to find app for caller " + caller
11001                      + " (pid=" + Binder.getCallingPid()
11002                      + ") when publishing content providers");
11003            }
11004
11005            final long origId = Binder.clearCallingIdentity();
11006
11007            final int N = providers.size();
11008            for (int i = 0; i < N; i++) {
11009                ContentProviderHolder src = providers.get(i);
11010                if (src == null || src.info == null || src.provider == null) {
11011                    continue;
11012                }
11013                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11014                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11015                if (dst != null) {
11016                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11017                    mProviderMap.putProviderByClass(comp, dst);
11018                    String names[] = dst.info.authority.split(";");
11019                    for (int j = 0; j < names.length; j++) {
11020                        mProviderMap.putProviderByName(names[j], dst);
11021                    }
11022
11023                    int launchingCount = mLaunchingProviders.size();
11024                    int j;
11025                    boolean wasInLaunchingProviders = false;
11026                    for (j = 0; j < launchingCount; j++) {
11027                        if (mLaunchingProviders.get(j) == dst) {
11028                            mLaunchingProviders.remove(j);
11029                            wasInLaunchingProviders = true;
11030                            j--;
11031                            launchingCount--;
11032                        }
11033                    }
11034                    if (wasInLaunchingProviders) {
11035                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11036                    }
11037                    synchronized (dst) {
11038                        dst.provider = src.provider;
11039                        dst.proc = r;
11040                        dst.notifyAll();
11041                    }
11042                    updateOomAdjLocked(r);
11043                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11044                            src.info.authority);
11045                }
11046            }
11047
11048            Binder.restoreCallingIdentity(origId);
11049        }
11050    }
11051
11052    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11053        ContentProviderConnection conn;
11054        try {
11055            conn = (ContentProviderConnection)connection;
11056        } catch (ClassCastException e) {
11057            String msg ="refContentProvider: " + connection
11058                    + " not a ContentProviderConnection";
11059            Slog.w(TAG, msg);
11060            throw new IllegalArgumentException(msg);
11061        }
11062        if (conn == null) {
11063            throw new NullPointerException("connection is null");
11064        }
11065
11066        synchronized (this) {
11067            if (stable > 0) {
11068                conn.numStableIncs += stable;
11069            }
11070            stable = conn.stableCount + stable;
11071            if (stable < 0) {
11072                throw new IllegalStateException("stableCount < 0: " + stable);
11073            }
11074
11075            if (unstable > 0) {
11076                conn.numUnstableIncs += unstable;
11077            }
11078            unstable = conn.unstableCount + unstable;
11079            if (unstable < 0) {
11080                throw new IllegalStateException("unstableCount < 0: " + unstable);
11081            }
11082
11083            if ((stable+unstable) <= 0) {
11084                throw new IllegalStateException("ref counts can't go to zero here: stable="
11085                        + stable + " unstable=" + unstable);
11086            }
11087            conn.stableCount = stable;
11088            conn.unstableCount = unstable;
11089            return !conn.dead;
11090        }
11091    }
11092
11093    public void unstableProviderDied(IBinder connection) {
11094        ContentProviderConnection conn;
11095        try {
11096            conn = (ContentProviderConnection)connection;
11097        } catch (ClassCastException e) {
11098            String msg ="refContentProvider: " + connection
11099                    + " not a ContentProviderConnection";
11100            Slog.w(TAG, msg);
11101            throw new IllegalArgumentException(msg);
11102        }
11103        if (conn == null) {
11104            throw new NullPointerException("connection is null");
11105        }
11106
11107        // Safely retrieve the content provider associated with the connection.
11108        IContentProvider provider;
11109        synchronized (this) {
11110            provider = conn.provider.provider;
11111        }
11112
11113        if (provider == null) {
11114            // Um, yeah, we're way ahead of you.
11115            return;
11116        }
11117
11118        // Make sure the caller is being honest with us.
11119        if (provider.asBinder().pingBinder()) {
11120            // Er, no, still looks good to us.
11121            synchronized (this) {
11122                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11123                        + " says " + conn + " died, but we don't agree");
11124                return;
11125            }
11126        }
11127
11128        // Well look at that!  It's dead!
11129        synchronized (this) {
11130            if (conn.provider.provider != provider) {
11131                // But something changed...  good enough.
11132                return;
11133            }
11134
11135            ProcessRecord proc = conn.provider.proc;
11136            if (proc == null || proc.thread == null) {
11137                // Seems like the process is already cleaned up.
11138                return;
11139            }
11140
11141            // As far as we're concerned, this is just like receiving a
11142            // death notification...  just a bit prematurely.
11143            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11144                    + ") early provider death");
11145            final long ident = Binder.clearCallingIdentity();
11146            try {
11147                appDiedLocked(proc);
11148            } finally {
11149                Binder.restoreCallingIdentity(ident);
11150            }
11151        }
11152    }
11153
11154    @Override
11155    public void appNotRespondingViaProvider(IBinder connection) {
11156        enforceCallingPermission(
11157                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11158
11159        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11160        if (conn == null) {
11161            Slog.w(TAG, "ContentProviderConnection is null");
11162            return;
11163        }
11164
11165        final ProcessRecord host = conn.provider.proc;
11166        if (host == null) {
11167            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11168            return;
11169        }
11170
11171        mHandler.post(new Runnable() {
11172            @Override
11173            public void run() {
11174                mAppErrors.appNotResponding(host, null, null, false,
11175                        "ContentProvider not responding");
11176            }
11177        });
11178    }
11179
11180    public final void installSystemProviders() {
11181        List<ProviderInfo> providers;
11182        synchronized (this) {
11183            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11184            providers = generateApplicationProvidersLocked(app);
11185            if (providers != null) {
11186                for (int i=providers.size()-1; i>=0; i--) {
11187                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11188                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11189                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11190                                + ": not system .apk");
11191                        providers.remove(i);
11192                    }
11193                }
11194            }
11195        }
11196        if (providers != null) {
11197            mSystemThread.installSystemProviders(providers);
11198        }
11199
11200        mCoreSettingsObserver = new CoreSettingsObserver(this);
11201        mFontScaleSettingObserver = new FontScaleSettingObserver();
11202
11203        //mUsageStatsService.monitorPackages();
11204    }
11205
11206    private void startPersistentApps(int matchFlags) {
11207        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11208
11209        synchronized (this) {
11210            try {
11211                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11212                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11213                for (ApplicationInfo app : apps) {
11214                    if (!"android".equals(app.packageName)) {
11215                        addAppLocked(app, false, null /* ABI override */);
11216                    }
11217                }
11218            } catch (RemoteException ex) {
11219            }
11220        }
11221    }
11222
11223    /**
11224     * When a user is unlocked, we need to install encryption-unaware providers
11225     * belonging to any running apps.
11226     */
11227    private void installEncryptionUnawareProviders(int userId) {
11228        // We're only interested in providers that are encryption unaware, and
11229        // we don't care about uninstalled apps, since there's no way they're
11230        // running at this point.
11231        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11232
11233        synchronized (this) {
11234            final int NP = mProcessNames.getMap().size();
11235            for (int ip = 0; ip < NP; ip++) {
11236                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11237                final int NA = apps.size();
11238                for (int ia = 0; ia < NA; ia++) {
11239                    final ProcessRecord app = apps.valueAt(ia);
11240                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11241
11242                    final int NG = app.pkgList.size();
11243                    for (int ig = 0; ig < NG; ig++) {
11244                        try {
11245                            final String pkgName = app.pkgList.keyAt(ig);
11246                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11247                                    .getPackageInfo(pkgName, matchFlags, userId);
11248                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11249                                for (ProviderInfo pi : pkgInfo.providers) {
11250                                    // TODO: keep in sync with generateApplicationProvidersLocked
11251                                    final boolean processMatch = Objects.equals(pi.processName,
11252                                            app.processName) || pi.multiprocess;
11253                                    final boolean userMatch = isSingleton(pi.processName,
11254                                            pi.applicationInfo, pi.name, pi.flags)
11255                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11256                                    if (processMatch && userMatch) {
11257                                        Log.v(TAG, "Installing " + pi);
11258                                        app.thread.scheduleInstallProvider(pi);
11259                                    } else {
11260                                        Log.v(TAG, "Skipping " + pi);
11261                                    }
11262                                }
11263                            }
11264                        } catch (RemoteException ignored) {
11265                        }
11266                    }
11267                }
11268            }
11269        }
11270    }
11271
11272    /**
11273     * Allows apps to retrieve the MIME type of a URI.
11274     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11275     * users, then it does not need permission to access the ContentProvider.
11276     * Either, it needs cross-user uri grants.
11277     *
11278     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11279     *
11280     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11281     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11282     */
11283    public String getProviderMimeType(Uri uri, int userId) {
11284        enforceNotIsolatedCaller("getProviderMimeType");
11285        final String name = uri.getAuthority();
11286        int callingUid = Binder.getCallingUid();
11287        int callingPid = Binder.getCallingPid();
11288        long ident = 0;
11289        boolean clearedIdentity = false;
11290        synchronized (this) {
11291            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11292        }
11293        if (canClearIdentity(callingPid, callingUid, userId)) {
11294            clearedIdentity = true;
11295            ident = Binder.clearCallingIdentity();
11296        }
11297        ContentProviderHolder holder = null;
11298        try {
11299            holder = getContentProviderExternalUnchecked(name, null, userId);
11300            if (holder != null) {
11301                return holder.provider.getType(uri);
11302            }
11303        } catch (RemoteException e) {
11304            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11305            return null;
11306        } catch (Exception e) {
11307            Log.w(TAG, "Exception while determining type of " + uri, e);
11308            return null;
11309        } finally {
11310            // We need to clear the identity to call removeContentProviderExternalUnchecked
11311            if (!clearedIdentity) {
11312                ident = Binder.clearCallingIdentity();
11313            }
11314            try {
11315                if (holder != null) {
11316                    removeContentProviderExternalUnchecked(name, null, userId);
11317                }
11318            } finally {
11319                Binder.restoreCallingIdentity(ident);
11320            }
11321        }
11322
11323        return null;
11324    }
11325
11326    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11327        if (UserHandle.getUserId(callingUid) == userId) {
11328            return true;
11329        }
11330        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11331                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11332                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11333                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11334                return true;
11335        }
11336        return false;
11337    }
11338
11339    // =========================================================
11340    // GLOBAL MANAGEMENT
11341    // =========================================================
11342
11343    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11344            boolean isolated, int isolatedUid) {
11345        String proc = customProcess != null ? customProcess : info.processName;
11346        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11347        final int userId = UserHandle.getUserId(info.uid);
11348        int uid = info.uid;
11349        if (isolated) {
11350            if (isolatedUid == 0) {
11351                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11352                while (true) {
11353                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11354                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11355                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11356                    }
11357                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11358                    mNextIsolatedProcessUid++;
11359                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11360                        // No process for this uid, use it.
11361                        break;
11362                    }
11363                    stepsLeft--;
11364                    if (stepsLeft <= 0) {
11365                        return null;
11366                    }
11367                }
11368            } else {
11369                // Special case for startIsolatedProcess (internal only), where
11370                // the uid of the isolated process is specified by the caller.
11371                uid = isolatedUid;
11372            }
11373        }
11374        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11375        if (!mBooted && !mBooting
11376                && userId == UserHandle.USER_SYSTEM
11377                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11378            r.persistent = true;
11379        }
11380        addProcessNameLocked(r);
11381        return r;
11382    }
11383
11384    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11385            String abiOverride) {
11386        ProcessRecord app;
11387        if (!isolated) {
11388            app = getProcessRecordLocked(info.processName, info.uid, true);
11389        } else {
11390            app = null;
11391        }
11392
11393        if (app == null) {
11394            app = newProcessRecordLocked(info, null, isolated, 0);
11395            updateLruProcessLocked(app, false, null);
11396            updateOomAdjLocked();
11397        }
11398
11399        // This package really, really can not be stopped.
11400        try {
11401            AppGlobals.getPackageManager().setPackageStoppedState(
11402                    info.packageName, false, UserHandle.getUserId(app.uid));
11403        } catch (RemoteException e) {
11404        } catch (IllegalArgumentException e) {
11405            Slog.w(TAG, "Failed trying to unstop package "
11406                    + info.packageName + ": " + e);
11407        }
11408
11409        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11410            app.persistent = true;
11411            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11412        }
11413        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11414            mPersistentStartingProcesses.add(app);
11415            startProcessLocked(app, "added application", app.processName, abiOverride,
11416                    null /* entryPoint */, null /* entryPointArgs */);
11417        }
11418
11419        return app;
11420    }
11421
11422    public void unhandledBack() {
11423        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11424                "unhandledBack()");
11425
11426        synchronized(this) {
11427            final long origId = Binder.clearCallingIdentity();
11428            try {
11429                getFocusedStack().unhandledBackLocked();
11430            } finally {
11431                Binder.restoreCallingIdentity(origId);
11432            }
11433        }
11434    }
11435
11436    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11437        enforceNotIsolatedCaller("openContentUri");
11438        final int userId = UserHandle.getCallingUserId();
11439        String name = uri.getAuthority();
11440        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11441        ParcelFileDescriptor pfd = null;
11442        if (cph != null) {
11443            // We record the binder invoker's uid in thread-local storage before
11444            // going to the content provider to open the file.  Later, in the code
11445            // that handles all permissions checks, we look for this uid and use
11446            // that rather than the Activity Manager's own uid.  The effect is that
11447            // we do the check against the caller's permissions even though it looks
11448            // to the content provider like the Activity Manager itself is making
11449            // the request.
11450            Binder token = new Binder();
11451            sCallerIdentity.set(new Identity(
11452                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11453            try {
11454                pfd = cph.provider.openFile(null, uri, "r", null, token);
11455            } catch (FileNotFoundException e) {
11456                // do nothing; pfd will be returned null
11457            } finally {
11458                // Ensure that whatever happens, we clean up the identity state
11459                sCallerIdentity.remove();
11460                // Ensure we're done with the provider.
11461                removeContentProviderExternalUnchecked(name, null, userId);
11462            }
11463        } else {
11464            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11465        }
11466        return pfd;
11467    }
11468
11469    // Actually is sleeping or shutting down or whatever else in the future
11470    // is an inactive state.
11471    public boolean isSleepingOrShuttingDown() {
11472        return isSleeping() || mShuttingDown;
11473    }
11474
11475    public boolean isSleeping() {
11476        return mSleeping;
11477    }
11478
11479    void onWakefulnessChanged(int wakefulness) {
11480        synchronized(this) {
11481            mWakefulness = wakefulness;
11482            updateSleepIfNeededLocked();
11483        }
11484    }
11485
11486    void finishRunningVoiceLocked() {
11487        if (mRunningVoice != null) {
11488            mRunningVoice = null;
11489            mVoiceWakeLock.release();
11490            updateSleepIfNeededLocked();
11491        }
11492    }
11493
11494    void startTimeTrackingFocusedActivityLocked() {
11495        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11496            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11497        }
11498    }
11499
11500    void updateSleepIfNeededLocked() {
11501        if (mSleeping && !shouldSleepLocked()) {
11502            mSleeping = false;
11503            startTimeTrackingFocusedActivityLocked();
11504            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11505            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11506            updateOomAdjLocked();
11507        } else if (!mSleeping && shouldSleepLocked()) {
11508            mSleeping = true;
11509            if (mCurAppTimeTracker != null) {
11510                mCurAppTimeTracker.stop();
11511            }
11512            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11513            mStackSupervisor.goingToSleepLocked();
11514            updateOomAdjLocked();
11515
11516            // Initialize the wake times of all processes.
11517            checkExcessivePowerUsageLocked(false);
11518            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11519            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11520            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11521        }
11522    }
11523
11524    private boolean shouldSleepLocked() {
11525        // Resume applications while running a voice interactor.
11526        if (mRunningVoice != null) {
11527            return false;
11528        }
11529
11530        // TODO: Transform the lock screen state into a sleep token instead.
11531        switch (mWakefulness) {
11532            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11533            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11534            case PowerManagerInternal.WAKEFULNESS_DOZING:
11535                // Pause applications whenever the lock screen is shown or any sleep
11536                // tokens have been acquired.
11537                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11538            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11539            default:
11540                // If we're asleep then pause applications unconditionally.
11541                return true;
11542        }
11543    }
11544
11545    /** Pokes the task persister. */
11546    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11547        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11548    }
11549
11550    /** Notifies all listeners when the task stack has changed. */
11551    void notifyTaskStackChangedLocked() {
11552        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11553        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11554        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11555        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11556    }
11557
11558    /** Notifies all listeners when an Activity is pinned. */
11559    void notifyActivityPinnedLocked() {
11560        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11561        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11562    }
11563
11564    /**
11565     * Notifies all listeners when an attempt was made to start an an activity that is already
11566     * running in the pinned stack and the activity was not actually started, but the task is
11567     * either brought to the front or a new Intent is delivered to it.
11568     */
11569    void notifyPinnedActivityRestartAttemptLocked() {
11570        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11571        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11572    }
11573
11574    /** Notifies all listeners when the pinned stack animation ends. */
11575    @Override
11576    public void notifyPinnedStackAnimationEnded() {
11577        synchronized (this) {
11578            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11579            mHandler.obtainMessage(
11580                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11581        }
11582    }
11583
11584    @Override
11585    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11586        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11587    }
11588
11589    @Override
11590    public boolean shutdown(int timeout) {
11591        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11592                != PackageManager.PERMISSION_GRANTED) {
11593            throw new SecurityException("Requires permission "
11594                    + android.Manifest.permission.SHUTDOWN);
11595        }
11596
11597        boolean timedout = false;
11598
11599        synchronized(this) {
11600            mShuttingDown = true;
11601            updateEventDispatchingLocked();
11602            timedout = mStackSupervisor.shutdownLocked(timeout);
11603        }
11604
11605        mAppOpsService.shutdown();
11606        if (mUsageStatsService != null) {
11607            mUsageStatsService.prepareShutdown();
11608        }
11609        mBatteryStatsService.shutdown();
11610        synchronized (this) {
11611            mProcessStats.shutdownLocked();
11612            notifyTaskPersisterLocked(null, true);
11613        }
11614
11615        return timedout;
11616    }
11617
11618    public final void activitySlept(IBinder token) {
11619        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11620
11621        final long origId = Binder.clearCallingIdentity();
11622
11623        synchronized (this) {
11624            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11625            if (r != null) {
11626                mStackSupervisor.activitySleptLocked(r);
11627            }
11628        }
11629
11630        Binder.restoreCallingIdentity(origId);
11631    }
11632
11633    private String lockScreenShownToString() {
11634        switch (mLockScreenShown) {
11635            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11636            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11637            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11638            default: return "Unknown=" + mLockScreenShown;
11639        }
11640    }
11641
11642    void logLockScreen(String msg) {
11643        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11644                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11645                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11646                + " mSleeping=" + mSleeping);
11647    }
11648
11649    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11650        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11651        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11652        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11653            boolean wasRunningVoice = mRunningVoice != null;
11654            mRunningVoice = session;
11655            if (!wasRunningVoice) {
11656                mVoiceWakeLock.acquire();
11657                updateSleepIfNeededLocked();
11658            }
11659        }
11660    }
11661
11662    private void updateEventDispatchingLocked() {
11663        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11664    }
11665
11666    public void setLockScreenShown(boolean showing, boolean occluded) {
11667        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11668                != PackageManager.PERMISSION_GRANTED) {
11669            throw new SecurityException("Requires permission "
11670                    + android.Manifest.permission.DEVICE_POWER);
11671        }
11672
11673        synchronized(this) {
11674            long ident = Binder.clearCallingIdentity();
11675            try {
11676                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11677                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11678                if (showing && occluded) {
11679                    // The lock screen is currently showing, but is occluded by a window that can
11680                    // show on top of the lock screen. In this can we want to dismiss the docked
11681                    // stack since it will be complicated/risky to try to put the activity on top
11682                    // of the lock screen in the right fullscreen configuration.
11683                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11684                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11685                }
11686
11687                updateSleepIfNeededLocked();
11688            } finally {
11689                Binder.restoreCallingIdentity(ident);
11690            }
11691        }
11692    }
11693
11694    @Override
11695    public void notifyLockedProfile(@UserIdInt int userId) {
11696        try {
11697            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11698                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11699            }
11700        } catch (RemoteException ex) {
11701            throw new SecurityException("Fail to check is caller a privileged app", ex);
11702        }
11703
11704        synchronized (this) {
11705            if (mStackSupervisor.isUserLockedProfile(userId)) {
11706                final long ident = Binder.clearCallingIdentity();
11707                try {
11708                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11709                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11710                        // If there is no device lock, we will show the profile's credential page.
11711                        mActivityStarter.showConfirmDeviceCredential(userId);
11712                    } else {
11713                        // Showing launcher to avoid user entering credential twice.
11714                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11715                    }
11716                } finally {
11717                    Binder.restoreCallingIdentity(ident);
11718                }
11719            }
11720        }
11721    }
11722
11723    @Override
11724    public void startConfirmDeviceCredentialIntent(Intent intent) {
11725        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11726        synchronized (this) {
11727            final long ident = Binder.clearCallingIdentity();
11728            try {
11729                mActivityStarter.startConfirmCredentialIntent(intent);
11730            } finally {
11731                Binder.restoreCallingIdentity(ident);
11732            }
11733        }
11734    }
11735
11736    @Override
11737    public void stopAppSwitches() {
11738        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11739                != PackageManager.PERMISSION_GRANTED) {
11740            throw new SecurityException("viewquires permission "
11741                    + android.Manifest.permission.STOP_APP_SWITCHES);
11742        }
11743
11744        synchronized(this) {
11745            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11746                    + APP_SWITCH_DELAY_TIME;
11747            mDidAppSwitch = false;
11748            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11749            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11750            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11751        }
11752    }
11753
11754    public void resumeAppSwitches() {
11755        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11756                != PackageManager.PERMISSION_GRANTED) {
11757            throw new SecurityException("Requires permission "
11758                    + android.Manifest.permission.STOP_APP_SWITCHES);
11759        }
11760
11761        synchronized(this) {
11762            // Note that we don't execute any pending app switches... we will
11763            // let those wait until either the timeout, or the next start
11764            // activity request.
11765            mAppSwitchesAllowedTime = 0;
11766        }
11767    }
11768
11769    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11770            int callingPid, int callingUid, String name) {
11771        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11772            return true;
11773        }
11774
11775        int perm = checkComponentPermission(
11776                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11777                sourceUid, -1, true);
11778        if (perm == PackageManager.PERMISSION_GRANTED) {
11779            return true;
11780        }
11781
11782        // If the actual IPC caller is different from the logical source, then
11783        // also see if they are allowed to control app switches.
11784        if (callingUid != -1 && callingUid != sourceUid) {
11785            perm = checkComponentPermission(
11786                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11787                    callingUid, -1, true);
11788            if (perm == PackageManager.PERMISSION_GRANTED) {
11789                return true;
11790            }
11791        }
11792
11793        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11794        return false;
11795    }
11796
11797    public void setDebugApp(String packageName, boolean waitForDebugger,
11798            boolean persistent) {
11799        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11800                "setDebugApp()");
11801
11802        long ident = Binder.clearCallingIdentity();
11803        try {
11804            // Note that this is not really thread safe if there are multiple
11805            // callers into it at the same time, but that's not a situation we
11806            // care about.
11807            if (persistent) {
11808                final ContentResolver resolver = mContext.getContentResolver();
11809                Settings.Global.putString(
11810                    resolver, Settings.Global.DEBUG_APP,
11811                    packageName);
11812                Settings.Global.putInt(
11813                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11814                    waitForDebugger ? 1 : 0);
11815            }
11816
11817            synchronized (this) {
11818                if (!persistent) {
11819                    mOrigDebugApp = mDebugApp;
11820                    mOrigWaitForDebugger = mWaitForDebugger;
11821                }
11822                mDebugApp = packageName;
11823                mWaitForDebugger = waitForDebugger;
11824                mDebugTransient = !persistent;
11825                if (packageName != null) {
11826                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11827                            false, UserHandle.USER_ALL, "set debug app");
11828                }
11829            }
11830        } finally {
11831            Binder.restoreCallingIdentity(ident);
11832        }
11833    }
11834
11835    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11836        synchronized (this) {
11837            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11838            if (!isDebuggable) {
11839                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11840                    throw new SecurityException("Process not debuggable: " + app.packageName);
11841                }
11842            }
11843
11844            mTrackAllocationApp = processName;
11845        }
11846    }
11847
11848    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11849        synchronized (this) {
11850            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11851            if (!isDebuggable) {
11852                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11853                    throw new SecurityException("Process not debuggable: " + app.packageName);
11854                }
11855            }
11856            mProfileApp = processName;
11857            mProfileFile = profilerInfo.profileFile;
11858            if (mProfileFd != null) {
11859                try {
11860                    mProfileFd.close();
11861                } catch (IOException e) {
11862                }
11863                mProfileFd = null;
11864            }
11865            mProfileFd = profilerInfo.profileFd;
11866            mSamplingInterval = profilerInfo.samplingInterval;
11867            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11868            mProfileType = 0;
11869        }
11870    }
11871
11872    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11873        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11874        if (!isDebuggable) {
11875            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11876                throw new SecurityException("Process not debuggable: " + app.packageName);
11877            }
11878        }
11879        mNativeDebuggingApp = processName;
11880    }
11881
11882    @Override
11883    public void setAlwaysFinish(boolean enabled) {
11884        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11885                "setAlwaysFinish()");
11886
11887        long ident = Binder.clearCallingIdentity();
11888        try {
11889            Settings.Global.putInt(
11890                    mContext.getContentResolver(),
11891                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11892
11893            synchronized (this) {
11894                mAlwaysFinishActivities = enabled;
11895            }
11896        } finally {
11897            Binder.restoreCallingIdentity(ident);
11898        }
11899    }
11900
11901    @Override
11902    public void setLenientBackgroundCheck(boolean enabled) {
11903        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11904                "setLenientBackgroundCheck()");
11905
11906        long ident = Binder.clearCallingIdentity();
11907        try {
11908            Settings.Global.putInt(
11909                    mContext.getContentResolver(),
11910                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11911
11912            synchronized (this) {
11913                mLenientBackgroundCheck = enabled;
11914            }
11915        } finally {
11916            Binder.restoreCallingIdentity(ident);
11917        }
11918    }
11919
11920    @Override
11921    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11922        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11923                "setActivityController()");
11924        synchronized (this) {
11925            mController = controller;
11926            mControllerIsAMonkey = imAMonkey;
11927            Watchdog.getInstance().setActivityController(controller);
11928        }
11929    }
11930
11931    @Override
11932    public void setUserIsMonkey(boolean userIsMonkey) {
11933        synchronized (this) {
11934            synchronized (mPidsSelfLocked) {
11935                final int callingPid = Binder.getCallingPid();
11936                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11937                if (precessRecord == null) {
11938                    throw new SecurityException("Unknown process: " + callingPid);
11939                }
11940                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11941                    throw new SecurityException("Only an instrumentation process "
11942                            + "with a UiAutomation can call setUserIsMonkey");
11943                }
11944            }
11945            mUserIsMonkey = userIsMonkey;
11946        }
11947    }
11948
11949    @Override
11950    public boolean isUserAMonkey() {
11951        synchronized (this) {
11952            // If there is a controller also implies the user is a monkey.
11953            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11954        }
11955    }
11956
11957    public void requestBugReport(int bugreportType) {
11958        String service = null;
11959        switch (bugreportType) {
11960            case ActivityManager.BUGREPORT_OPTION_FULL:
11961                service = "bugreport";
11962                break;
11963            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11964                service = "bugreportplus";
11965                break;
11966            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11967                service = "bugreportremote";
11968                break;
11969        }
11970        if (service == null) {
11971            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11972                    + bugreportType);
11973        }
11974        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11975        SystemProperties.set("ctl.start", service);
11976    }
11977
11978    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11979        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11980    }
11981
11982    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11983        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11984            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11985        }
11986        return KEY_DISPATCHING_TIMEOUT;
11987    }
11988
11989    @Override
11990    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11991        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11992                != PackageManager.PERMISSION_GRANTED) {
11993            throw new SecurityException("Requires permission "
11994                    + android.Manifest.permission.FILTER_EVENTS);
11995        }
11996        ProcessRecord proc;
11997        long timeout;
11998        synchronized (this) {
11999            synchronized (mPidsSelfLocked) {
12000                proc = mPidsSelfLocked.get(pid);
12001            }
12002            timeout = getInputDispatchingTimeoutLocked(proc);
12003        }
12004
12005        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12006            return -1;
12007        }
12008
12009        return timeout;
12010    }
12011
12012    /**
12013     * Handle input dispatching timeouts.
12014     * Returns whether input dispatching should be aborted or not.
12015     */
12016    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12017            final ActivityRecord activity, final ActivityRecord parent,
12018            final boolean aboveSystem, String reason) {
12019        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12020                != PackageManager.PERMISSION_GRANTED) {
12021            throw new SecurityException("Requires permission "
12022                    + android.Manifest.permission.FILTER_EVENTS);
12023        }
12024
12025        final String annotation;
12026        if (reason == null) {
12027            annotation = "Input dispatching timed out";
12028        } else {
12029            annotation = "Input dispatching timed out (" + reason + ")";
12030        }
12031
12032        if (proc != null) {
12033            synchronized (this) {
12034                if (proc.debugging) {
12035                    return false;
12036                }
12037
12038                if (mDidDexOpt) {
12039                    // Give more time since we were dexopting.
12040                    mDidDexOpt = false;
12041                    return false;
12042                }
12043
12044                if (proc.instrumentationClass != null) {
12045                    Bundle info = new Bundle();
12046                    info.putString("shortMsg", "keyDispatchingTimedOut");
12047                    info.putString("longMsg", annotation);
12048                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12049                    return true;
12050                }
12051            }
12052            mHandler.post(new Runnable() {
12053                @Override
12054                public void run() {
12055                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12056                }
12057            });
12058        }
12059
12060        return true;
12061    }
12062
12063    @Override
12064    public Bundle getAssistContextExtras(int requestType) {
12065        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12066                null, null, true /* focused */, true /* newSessionId */,
12067                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12068        if (pae == null) {
12069            return null;
12070        }
12071        synchronized (pae) {
12072            while (!pae.haveResult) {
12073                try {
12074                    pae.wait();
12075                } catch (InterruptedException e) {
12076                }
12077            }
12078        }
12079        synchronized (this) {
12080            buildAssistBundleLocked(pae, pae.result);
12081            mPendingAssistExtras.remove(pae);
12082            mUiHandler.removeCallbacks(pae);
12083        }
12084        return pae.extras;
12085    }
12086
12087    @Override
12088    public boolean isAssistDataAllowedOnCurrentActivity() {
12089        int userId;
12090        synchronized (this) {
12091            userId = mUserController.getCurrentUserIdLocked();
12092            ActivityRecord activity = getFocusedStack().topActivity();
12093            if (activity == null) {
12094                return false;
12095            }
12096            userId = activity.userId;
12097        }
12098        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12099                Context.DEVICE_POLICY_SERVICE);
12100        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12101    }
12102
12103    @Override
12104    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12105        long ident = Binder.clearCallingIdentity();
12106        try {
12107            synchronized (this) {
12108                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12109                ActivityRecord top = getFocusedStack().topActivity();
12110                if (top != caller) {
12111                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12112                            + " is not current top " + top);
12113                    return false;
12114                }
12115                if (!top.nowVisible) {
12116                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12117                            + " is not visible");
12118                    return false;
12119                }
12120            }
12121            AssistUtils utils = new AssistUtils(mContext);
12122            return utils.showSessionForActiveService(args,
12123                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12124        } finally {
12125            Binder.restoreCallingIdentity(ident);
12126        }
12127    }
12128
12129    @Override
12130    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12131            Bundle receiverExtras,
12132            IBinder activityToken, boolean focused, boolean newSessionId) {
12133        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12134                activityToken, focused, newSessionId,
12135                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12136                != null;
12137    }
12138
12139    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12140            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12141            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12142        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12143                "enqueueAssistContext()");
12144        synchronized (this) {
12145            ActivityRecord activity = getFocusedStack().topActivity();
12146            if (activity == null) {
12147                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12148                return null;
12149            }
12150            if (activity.app == null || activity.app.thread == null) {
12151                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12152                return null;
12153            }
12154            if (focused) {
12155                if (activityToken != null) {
12156                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12157                    if (activity != caller) {
12158                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12159                                + " is not current top " + activity);
12160                        return null;
12161                    }
12162                }
12163            } else {
12164                activity = ActivityRecord.forTokenLocked(activityToken);
12165                if (activity == null) {
12166                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12167                            + " couldn't be found");
12168                    return null;
12169                }
12170            }
12171
12172            PendingAssistExtras pae;
12173            Bundle extras = new Bundle();
12174            if (args != null) {
12175                extras.putAll(args);
12176            }
12177            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12178            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12179            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12180                    userHandle);
12181            // Increment the sessionId if necessary
12182            if (newSessionId) {
12183                mViSessionId++;
12184            }
12185            try {
12186                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12187                        requestType, mViSessionId);
12188                mPendingAssistExtras.add(pae);
12189                mUiHandler.postDelayed(pae, timeout);
12190            } catch (RemoteException e) {
12191                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12192                return null;
12193            }
12194            return pae;
12195        }
12196    }
12197
12198    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12199        IResultReceiver receiver;
12200        synchronized (this) {
12201            mPendingAssistExtras.remove(pae);
12202            receiver = pae.receiver;
12203        }
12204        if (receiver != null) {
12205            // Caller wants result sent back to them.
12206            Bundle sendBundle = new Bundle();
12207            // At least return the receiver extras
12208            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12209                    pae.receiverExtras);
12210            try {
12211                pae.receiver.send(0, sendBundle);
12212            } catch (RemoteException e) {
12213            }
12214        }
12215    }
12216
12217    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12218        if (result != null) {
12219            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12220        }
12221        if (pae.hint != null) {
12222            pae.extras.putBoolean(pae.hint, true);
12223        }
12224    }
12225
12226    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12227            AssistContent content, Uri referrer) {
12228        PendingAssistExtras pae = (PendingAssistExtras)token;
12229        synchronized (pae) {
12230            pae.result = extras;
12231            pae.structure = structure;
12232            pae.content = content;
12233            if (referrer != null) {
12234                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12235            }
12236            pae.haveResult = true;
12237            pae.notifyAll();
12238            if (pae.intent == null && pae.receiver == null) {
12239                // Caller is just waiting for the result.
12240                return;
12241            }
12242        }
12243
12244        // We are now ready to launch the assist activity.
12245        IResultReceiver sendReceiver = null;
12246        Bundle sendBundle = null;
12247        synchronized (this) {
12248            buildAssistBundleLocked(pae, extras);
12249            boolean exists = mPendingAssistExtras.remove(pae);
12250            mUiHandler.removeCallbacks(pae);
12251            if (!exists) {
12252                // Timed out.
12253                return;
12254            }
12255            if ((sendReceiver=pae.receiver) != null) {
12256                // Caller wants result sent back to them.
12257                sendBundle = new Bundle();
12258                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12259                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12260                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12261                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12262                        pae.receiverExtras);
12263            }
12264        }
12265        if (sendReceiver != null) {
12266            try {
12267                sendReceiver.send(0, sendBundle);
12268            } catch (RemoteException e) {
12269            }
12270            return;
12271        }
12272
12273        long ident = Binder.clearCallingIdentity();
12274        try {
12275            pae.intent.replaceExtras(pae.extras);
12276            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12277                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12278                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12279            closeSystemDialogs("assist");
12280            try {
12281                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12282            } catch (ActivityNotFoundException e) {
12283                Slog.w(TAG, "No activity to handle assist action.", e);
12284            }
12285        } finally {
12286            Binder.restoreCallingIdentity(ident);
12287        }
12288    }
12289
12290    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12291            Bundle args) {
12292        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12293                true /* focused */, true /* newSessionId */,
12294                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12295    }
12296
12297    public void registerProcessObserver(IProcessObserver observer) {
12298        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12299                "registerProcessObserver()");
12300        synchronized (this) {
12301            mProcessObservers.register(observer);
12302        }
12303    }
12304
12305    @Override
12306    public void unregisterProcessObserver(IProcessObserver observer) {
12307        synchronized (this) {
12308            mProcessObservers.unregister(observer);
12309        }
12310    }
12311
12312    @Override
12313    public void registerUidObserver(IUidObserver observer, int which) {
12314        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12315                "registerUidObserver()");
12316        synchronized (this) {
12317            mUidObservers.register(observer, which);
12318        }
12319    }
12320
12321    @Override
12322    public void unregisterUidObserver(IUidObserver observer) {
12323        synchronized (this) {
12324            mUidObservers.unregister(observer);
12325        }
12326    }
12327
12328    @Override
12329    public boolean convertFromTranslucent(IBinder token) {
12330        final long origId = Binder.clearCallingIdentity();
12331        try {
12332            synchronized (this) {
12333                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12334                if (r == null) {
12335                    return false;
12336                }
12337                final boolean translucentChanged = r.changeWindowTranslucency(true);
12338                if (translucentChanged) {
12339                    r.task.stack.releaseBackgroundResources(r);
12340                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12341                }
12342                mWindowManager.setAppFullscreen(token, true);
12343                return translucentChanged;
12344            }
12345        } finally {
12346            Binder.restoreCallingIdentity(origId);
12347        }
12348    }
12349
12350    @Override
12351    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12352        final long origId = Binder.clearCallingIdentity();
12353        try {
12354            synchronized (this) {
12355                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12356                if (r == null) {
12357                    return false;
12358                }
12359                int index = r.task.mActivities.lastIndexOf(r);
12360                if (index > 0) {
12361                    ActivityRecord under = r.task.mActivities.get(index - 1);
12362                    under.returningOptions = options;
12363                }
12364                final boolean translucentChanged = r.changeWindowTranslucency(false);
12365                if (translucentChanged) {
12366                    r.task.stack.convertActivityToTranslucent(r);
12367                }
12368                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12369                mWindowManager.setAppFullscreen(token, false);
12370                return translucentChanged;
12371            }
12372        } finally {
12373            Binder.restoreCallingIdentity(origId);
12374        }
12375    }
12376
12377    @Override
12378    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12379        final long origId = Binder.clearCallingIdentity();
12380        try {
12381            synchronized (this) {
12382                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12383                if (r != null) {
12384                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12385                }
12386            }
12387            return false;
12388        } finally {
12389            Binder.restoreCallingIdentity(origId);
12390        }
12391    }
12392
12393    @Override
12394    public boolean isBackgroundVisibleBehind(IBinder token) {
12395        final long origId = Binder.clearCallingIdentity();
12396        try {
12397            synchronized (this) {
12398                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12399                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12400                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12401                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12402                return visible;
12403            }
12404        } finally {
12405            Binder.restoreCallingIdentity(origId);
12406        }
12407    }
12408
12409    @Override
12410    public ActivityOptions getActivityOptions(IBinder token) {
12411        final long origId = Binder.clearCallingIdentity();
12412        try {
12413            synchronized (this) {
12414                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12415                if (r != null) {
12416                    final ActivityOptions activityOptions = r.pendingOptions;
12417                    r.pendingOptions = null;
12418                    return activityOptions;
12419                }
12420                return null;
12421            }
12422        } finally {
12423            Binder.restoreCallingIdentity(origId);
12424        }
12425    }
12426
12427    @Override
12428    public void setImmersive(IBinder token, boolean immersive) {
12429        synchronized(this) {
12430            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12431            if (r == null) {
12432                throw new IllegalArgumentException();
12433            }
12434            r.immersive = immersive;
12435
12436            // update associated state if we're frontmost
12437            if (r == mFocusedActivity) {
12438                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12439                applyUpdateLockStateLocked(r);
12440            }
12441        }
12442    }
12443
12444    @Override
12445    public boolean isImmersive(IBinder token) {
12446        synchronized (this) {
12447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12448            if (r == null) {
12449                throw new IllegalArgumentException();
12450            }
12451            return r.immersive;
12452        }
12453    }
12454
12455    @Override
12456    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12457        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12458            throw new UnsupportedOperationException("VR mode not supported on this device!");
12459        }
12460
12461        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12462
12463        ActivityRecord r;
12464        synchronized (this) {
12465            r = ActivityRecord.isInStackLocked(token);
12466        }
12467
12468        if (r == null) {
12469            throw new IllegalArgumentException();
12470        }
12471
12472        int err;
12473        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12474                VrManagerInternal.NO_ERROR) {
12475            return err;
12476        }
12477
12478        synchronized(this) {
12479            r.requestedVrComponent = (enabled) ? packageName : null;
12480
12481            // Update associated state if this activity is currently focused
12482            if (r == mFocusedActivity) {
12483                applyUpdateVrModeLocked(r);
12484            }
12485            return 0;
12486        }
12487    }
12488
12489    @Override
12490    public boolean isVrModePackageEnabled(ComponentName packageName) {
12491        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12492            throw new UnsupportedOperationException("VR mode not supported on this device!");
12493        }
12494
12495        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12496
12497        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12498                VrManagerInternal.NO_ERROR;
12499    }
12500
12501    public boolean isTopActivityImmersive() {
12502        enforceNotIsolatedCaller("startActivity");
12503        synchronized (this) {
12504            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12505            return (r != null) ? r.immersive : false;
12506        }
12507    }
12508
12509    @Override
12510    public boolean isTopOfTask(IBinder token) {
12511        synchronized (this) {
12512            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12513            if (r == null) {
12514                throw new IllegalArgumentException();
12515            }
12516            return r.task.getTopActivity() == r;
12517        }
12518    }
12519
12520    public final void enterSafeMode() {
12521        synchronized(this) {
12522            // It only makes sense to do this before the system is ready
12523            // and started launching other packages.
12524            if (!mSystemReady) {
12525                try {
12526                    AppGlobals.getPackageManager().enterSafeMode();
12527                } catch (RemoteException e) {
12528                }
12529            }
12530
12531            mSafeMode = true;
12532        }
12533    }
12534
12535    public final void showSafeModeOverlay() {
12536        View v = LayoutInflater.from(mContext).inflate(
12537                com.android.internal.R.layout.safe_mode, null);
12538        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12539        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12540        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12541        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12542        lp.gravity = Gravity.BOTTOM | Gravity.START;
12543        lp.format = v.getBackground().getOpacity();
12544        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12545                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12546        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12547        ((WindowManager)mContext.getSystemService(
12548                Context.WINDOW_SERVICE)).addView(v, lp);
12549    }
12550
12551    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12552        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12553            return;
12554        }
12555        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12556        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12557        synchronized (stats) {
12558            if (mBatteryStatsService.isOnBattery()) {
12559                mBatteryStatsService.enforceCallingPermission();
12560                int MY_UID = Binder.getCallingUid();
12561                final int uid;
12562                if (sender == null) {
12563                    uid = sourceUid;
12564                } else {
12565                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12566                }
12567                BatteryStatsImpl.Uid.Pkg pkg =
12568                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12569                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12570                pkg.noteWakeupAlarmLocked(tag);
12571            }
12572        }
12573    }
12574
12575    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12576        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12577            return;
12578        }
12579        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12580        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12581        synchronized (stats) {
12582            mBatteryStatsService.enforceCallingPermission();
12583            int MY_UID = Binder.getCallingUid();
12584            final int uid;
12585            if (sender == null) {
12586                uid = sourceUid;
12587            } else {
12588                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12589            }
12590            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12591        }
12592    }
12593
12594    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12595        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12596            return;
12597        }
12598        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12599        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12600        synchronized (stats) {
12601            mBatteryStatsService.enforceCallingPermission();
12602            int MY_UID = Binder.getCallingUid();
12603            final int uid;
12604            if (sender == null) {
12605                uid = sourceUid;
12606            } else {
12607                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12608            }
12609            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12610        }
12611    }
12612
12613    public boolean killPids(int[] pids, String pReason, boolean secure) {
12614        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12615            throw new SecurityException("killPids only available to the system");
12616        }
12617        String reason = (pReason == null) ? "Unknown" : pReason;
12618        // XXX Note: don't acquire main activity lock here, because the window
12619        // manager calls in with its locks held.
12620
12621        boolean killed = false;
12622        synchronized (mPidsSelfLocked) {
12623            int worstType = 0;
12624            for (int i=0; i<pids.length; i++) {
12625                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12626                if (proc != null) {
12627                    int type = proc.setAdj;
12628                    if (type > worstType) {
12629                        worstType = type;
12630                    }
12631                }
12632            }
12633
12634            // If the worst oom_adj is somewhere in the cached proc LRU range,
12635            // then constrain it so we will kill all cached procs.
12636            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12637                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12638                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12639            }
12640
12641            // If this is not a secure call, don't let it kill processes that
12642            // are important.
12643            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12644                worstType = ProcessList.SERVICE_ADJ;
12645            }
12646
12647            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12648            for (int i=0; i<pids.length; i++) {
12649                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12650                if (proc == null) {
12651                    continue;
12652                }
12653                int adj = proc.setAdj;
12654                if (adj >= worstType && !proc.killedByAm) {
12655                    proc.kill(reason, true);
12656                    killed = true;
12657                }
12658            }
12659        }
12660        return killed;
12661    }
12662
12663    @Override
12664    public void killUid(int appId, int userId, String reason) {
12665        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12666        synchronized (this) {
12667            final long identity = Binder.clearCallingIdentity();
12668            try {
12669                killPackageProcessesLocked(null, appId, userId,
12670                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12671                        reason != null ? reason : "kill uid");
12672            } finally {
12673                Binder.restoreCallingIdentity(identity);
12674            }
12675        }
12676    }
12677
12678    @Override
12679    public boolean killProcessesBelowForeground(String reason) {
12680        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12681            throw new SecurityException("killProcessesBelowForeground() only available to system");
12682        }
12683
12684        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12685    }
12686
12687    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12689            throw new SecurityException("killProcessesBelowAdj() only available to system");
12690        }
12691
12692        boolean killed = false;
12693        synchronized (mPidsSelfLocked) {
12694            final int size = mPidsSelfLocked.size();
12695            for (int i = 0; i < size; i++) {
12696                final int pid = mPidsSelfLocked.keyAt(i);
12697                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12698                if (proc == null) continue;
12699
12700                final int adj = proc.setAdj;
12701                if (adj > belowAdj && !proc.killedByAm) {
12702                    proc.kill(reason, true);
12703                    killed = true;
12704                }
12705            }
12706        }
12707        return killed;
12708    }
12709
12710    @Override
12711    public void hang(final IBinder who, boolean allowRestart) {
12712        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12713                != PackageManager.PERMISSION_GRANTED) {
12714            throw new SecurityException("Requires permission "
12715                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12716        }
12717
12718        final IBinder.DeathRecipient death = new DeathRecipient() {
12719            @Override
12720            public void binderDied() {
12721                synchronized (this) {
12722                    notifyAll();
12723                }
12724            }
12725        };
12726
12727        try {
12728            who.linkToDeath(death, 0);
12729        } catch (RemoteException e) {
12730            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12731            return;
12732        }
12733
12734        synchronized (this) {
12735            Watchdog.getInstance().setAllowRestart(allowRestart);
12736            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12737            synchronized (death) {
12738                while (who.isBinderAlive()) {
12739                    try {
12740                        death.wait();
12741                    } catch (InterruptedException e) {
12742                    }
12743                }
12744            }
12745            Watchdog.getInstance().setAllowRestart(true);
12746        }
12747    }
12748
12749    @Override
12750    public void restart() {
12751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12752                != PackageManager.PERMISSION_GRANTED) {
12753            throw new SecurityException("Requires permission "
12754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12755        }
12756
12757        Log.i(TAG, "Sending shutdown broadcast...");
12758
12759        BroadcastReceiver br = new BroadcastReceiver() {
12760            @Override public void onReceive(Context context, Intent intent) {
12761                // Now the broadcast is done, finish up the low-level shutdown.
12762                Log.i(TAG, "Shutting down activity manager...");
12763                shutdown(10000);
12764                Log.i(TAG, "Shutdown complete, restarting!");
12765                Process.killProcess(Process.myPid());
12766                System.exit(10);
12767            }
12768        };
12769
12770        // First send the high-level shut down broadcast.
12771        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12772        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12773        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12774        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12775        mContext.sendOrderedBroadcastAsUser(intent,
12776                UserHandle.ALL, null, br, mHandler, 0, null, null);
12777        */
12778        br.onReceive(mContext, intent);
12779    }
12780
12781    private long getLowRamTimeSinceIdle(long now) {
12782        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12783    }
12784
12785    @Override
12786    public void performIdleMaintenance() {
12787        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12788                != PackageManager.PERMISSION_GRANTED) {
12789            throw new SecurityException("Requires permission "
12790                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12791        }
12792
12793        synchronized (this) {
12794            final long now = SystemClock.uptimeMillis();
12795            final long timeSinceLastIdle = now - mLastIdleTime;
12796            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12797            mLastIdleTime = now;
12798            mLowRamTimeSinceLastIdle = 0;
12799            if (mLowRamStartTime != 0) {
12800                mLowRamStartTime = now;
12801            }
12802
12803            StringBuilder sb = new StringBuilder(128);
12804            sb.append("Idle maintenance over ");
12805            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12806            sb.append(" low RAM for ");
12807            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12808            Slog.i(TAG, sb.toString());
12809
12810            // If at least 1/3 of our time since the last idle period has been spent
12811            // with RAM low, then we want to kill processes.
12812            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12813
12814            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12815                ProcessRecord proc = mLruProcesses.get(i);
12816                if (proc.notCachedSinceIdle) {
12817                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12818                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12819                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12820                        if (doKilling && proc.initialIdlePss != 0
12821                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12822                            sb = new StringBuilder(128);
12823                            sb.append("Kill");
12824                            sb.append(proc.processName);
12825                            sb.append(" in idle maint: pss=");
12826                            sb.append(proc.lastPss);
12827                            sb.append(", swapPss=");
12828                            sb.append(proc.lastSwapPss);
12829                            sb.append(", initialPss=");
12830                            sb.append(proc.initialIdlePss);
12831                            sb.append(", period=");
12832                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12833                            sb.append(", lowRamPeriod=");
12834                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12835                            Slog.wtfQuiet(TAG, sb.toString());
12836                            proc.kill("idle maint (pss " + proc.lastPss
12837                                    + " from " + proc.initialIdlePss + ")", true);
12838                        }
12839                    }
12840                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12841                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12842                    proc.notCachedSinceIdle = true;
12843                    proc.initialIdlePss = 0;
12844                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12845                            mTestPssMode, isSleeping(), now);
12846                }
12847            }
12848
12849            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12850            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12851        }
12852    }
12853
12854    @Override
12855    public void sendIdleJobTrigger() {
12856        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12857                != PackageManager.PERMISSION_GRANTED) {
12858            throw new SecurityException("Requires permission "
12859                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12860        }
12861
12862        final long ident = Binder.clearCallingIdentity();
12863        try {
12864            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12865                    .setPackage("android")
12866                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12867            broadcastIntent(null, intent, null, null, 0, null, null, null,
12868                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12869        } finally {
12870            Binder.restoreCallingIdentity(ident);
12871        }
12872    }
12873
12874    private void retrieveSettings() {
12875        final ContentResolver resolver = mContext.getContentResolver();
12876        final boolean freeformWindowManagement =
12877                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12878                        || Settings.Global.getInt(
12879                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12880        final boolean supportsPictureInPicture =
12881                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12882
12883        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12884        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12885        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12886        final boolean alwaysFinishActivities =
12887                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12888        final boolean lenientBackgroundCheck =
12889                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12890        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12891        final boolean forceResizable = Settings.Global.getInt(
12892                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12893        final boolean supportsLeanbackOnly =
12894                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12895
12896        // Transfer any global setting for forcing RTL layout, into a System Property
12897        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12898
12899        final Configuration configuration = new Configuration();
12900        Settings.System.getConfiguration(resolver, configuration);
12901        if (forceRtl) {
12902            // This will take care of setting the correct layout direction flags
12903            configuration.setLayoutDirection(configuration.locale);
12904        }
12905
12906        synchronized (this) {
12907            mDebugApp = mOrigDebugApp = debugApp;
12908            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12909            mAlwaysFinishActivities = alwaysFinishActivities;
12910            mLenientBackgroundCheck = lenientBackgroundCheck;
12911            mSupportsLeanbackOnly = supportsLeanbackOnly;
12912            mForceResizableActivities = forceResizable;
12913            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12914            if (supportsMultiWindow || forceResizable) {
12915                mSupportsMultiWindow = true;
12916                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12917                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12918            } else {
12919                mSupportsMultiWindow = false;
12920                mSupportsFreeformWindowManagement = false;
12921                mSupportsPictureInPicture = false;
12922            }
12923            // This happens before any activities are started, so we can
12924            // change mConfiguration in-place.
12925            updateConfigurationLocked(configuration, null, true);
12926            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12927                    "Initial config: " + mConfiguration);
12928
12929            // Load resources only after the current configuration has been set.
12930            final Resources res = mContext.getResources();
12931            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12932            mThumbnailWidth = res.getDimensionPixelSize(
12933                    com.android.internal.R.dimen.thumbnail_width);
12934            mThumbnailHeight = res.getDimensionPixelSize(
12935                    com.android.internal.R.dimen.thumbnail_height);
12936            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12937                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12938            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12939                    com.android.internal.R.string.config_appsNotReportingCrashes));
12940            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12941                mFullscreenThumbnailScale = (float) res
12942                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12943                    (float) mConfiguration.screenWidthDp;
12944            } else {
12945                mFullscreenThumbnailScale = res.getFraction(
12946                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12947            }
12948        }
12949    }
12950
12951    public boolean testIsSystemReady() {
12952        // no need to synchronize(this) just to read & return the value
12953        return mSystemReady;
12954    }
12955
12956    public void systemReady(final Runnable goingCallback) {
12957        synchronized(this) {
12958            if (mSystemReady) {
12959                // If we're done calling all the receivers, run the next "boot phase" passed in
12960                // by the SystemServer
12961                if (goingCallback != null) {
12962                    goingCallback.run();
12963                }
12964                return;
12965            }
12966
12967            mLocalDeviceIdleController
12968                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12969
12970            // Make sure we have the current profile info, since it is needed for security checks.
12971            mUserController.onSystemReady();
12972            mRecentTasks.onSystemReadyLocked();
12973            mAppOpsService.systemReady();
12974            mSystemReady = true;
12975        }
12976
12977        ArrayList<ProcessRecord> procsToKill = null;
12978        synchronized(mPidsSelfLocked) {
12979            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12980                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12981                if (!isAllowedWhileBooting(proc.info)){
12982                    if (procsToKill == null) {
12983                        procsToKill = new ArrayList<ProcessRecord>();
12984                    }
12985                    procsToKill.add(proc);
12986                }
12987            }
12988        }
12989
12990        synchronized(this) {
12991            if (procsToKill != null) {
12992                for (int i=procsToKill.size()-1; i>=0; i--) {
12993                    ProcessRecord proc = procsToKill.get(i);
12994                    Slog.i(TAG, "Removing system update proc: " + proc);
12995                    removeProcessLocked(proc, true, false, "system update done");
12996                }
12997            }
12998
12999            // Now that we have cleaned up any update processes, we
13000            // are ready to start launching real processes and know that
13001            // we won't trample on them any more.
13002            mProcessesReady = true;
13003        }
13004
13005        Slog.i(TAG, "System now ready");
13006        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13007            SystemClock.uptimeMillis());
13008
13009        synchronized(this) {
13010            // Make sure we have no pre-ready processes sitting around.
13011
13012            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13013                ResolveInfo ri = mContext.getPackageManager()
13014                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13015                                STOCK_PM_FLAGS);
13016                CharSequence errorMsg = null;
13017                if (ri != null) {
13018                    ActivityInfo ai = ri.activityInfo;
13019                    ApplicationInfo app = ai.applicationInfo;
13020                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13021                        mTopAction = Intent.ACTION_FACTORY_TEST;
13022                        mTopData = null;
13023                        mTopComponent = new ComponentName(app.packageName,
13024                                ai.name);
13025                    } else {
13026                        errorMsg = mContext.getResources().getText(
13027                                com.android.internal.R.string.factorytest_not_system);
13028                    }
13029                } else {
13030                    errorMsg = mContext.getResources().getText(
13031                            com.android.internal.R.string.factorytest_no_action);
13032                }
13033                if (errorMsg != null) {
13034                    mTopAction = null;
13035                    mTopData = null;
13036                    mTopComponent = null;
13037                    Message msg = Message.obtain();
13038                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13039                    msg.getData().putCharSequence("msg", errorMsg);
13040                    mUiHandler.sendMessage(msg);
13041                }
13042            }
13043        }
13044
13045        retrieveSettings();
13046        final int currentUserId;
13047        synchronized (this) {
13048            currentUserId = mUserController.getCurrentUserIdLocked();
13049            readGrantedUriPermissionsLocked();
13050        }
13051
13052        if (goingCallback != null) goingCallback.run();
13053
13054        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13055                Integer.toString(currentUserId), currentUserId);
13056        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13057                Integer.toString(currentUserId), currentUserId);
13058        mSystemServiceManager.startUser(currentUserId);
13059
13060        synchronized (this) {
13061            // Only start up encryption-aware persistent apps; once user is
13062            // unlocked we'll come back around and start unaware apps
13063            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13064
13065            // Start up initial activity.
13066            mBooting = true;
13067            // Enable home activity for system user, so that the system can always boot
13068            if (UserManager.isSplitSystemUser()) {
13069                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13070                try {
13071                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13072                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13073                            UserHandle.USER_SYSTEM);
13074                } catch (RemoteException e) {
13075                    throw e.rethrowAsRuntimeException();
13076                }
13077            }
13078            startHomeActivityLocked(currentUserId, "systemReady");
13079
13080            try {
13081                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13082                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13083                            + " data partition or your device will be unstable.");
13084                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13085                }
13086            } catch (RemoteException e) {
13087            }
13088
13089            if (!Build.isBuildConsistent()) {
13090                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13091                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13092            }
13093
13094            long ident = Binder.clearCallingIdentity();
13095            try {
13096                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13097                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13098                        | Intent.FLAG_RECEIVER_FOREGROUND);
13099                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13100                broadcastIntentLocked(null, null, intent,
13101                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13102                        null, false, false, MY_PID, Process.SYSTEM_UID,
13103                        currentUserId);
13104                intent = new Intent(Intent.ACTION_USER_STARTING);
13105                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13106                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13107                broadcastIntentLocked(null, null, intent,
13108                        null, new IIntentReceiver.Stub() {
13109                            @Override
13110                            public void performReceive(Intent intent, int resultCode, String data,
13111                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13112                                    throws RemoteException {
13113                            }
13114                        }, 0, null, null,
13115                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13116                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13117            } catch (Throwable t) {
13118                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13119            } finally {
13120                Binder.restoreCallingIdentity(ident);
13121            }
13122            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13123            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13124        }
13125    }
13126
13127    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13128        synchronized (this) {
13129            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13130        }
13131    }
13132
13133    void skipCurrentReceiverLocked(ProcessRecord app) {
13134        for (BroadcastQueue queue : mBroadcastQueues) {
13135            queue.skipCurrentReceiverLocked(app);
13136        }
13137    }
13138
13139    /**
13140     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13141     * The application process will exit immediately after this call returns.
13142     * @param app object of the crashing app, null for the system server
13143     * @param crashInfo describing the exception
13144     */
13145    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13146        ProcessRecord r = findAppProcess(app, "Crash");
13147        final String processName = app == null ? "system_server"
13148                : (r == null ? "unknown" : r.processName);
13149
13150        handleApplicationCrashInner("crash", r, processName, crashInfo);
13151    }
13152
13153    /* Native crash reporting uses this inner version because it needs to be somewhat
13154     * decoupled from the AM-managed cleanup lifecycle
13155     */
13156    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13157            ApplicationErrorReport.CrashInfo crashInfo) {
13158        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13159                UserHandle.getUserId(Binder.getCallingUid()), processName,
13160                r == null ? -1 : r.info.flags,
13161                crashInfo.exceptionClassName,
13162                crashInfo.exceptionMessage,
13163                crashInfo.throwFileName,
13164                crashInfo.throwLineNumber);
13165
13166        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13167
13168        mAppErrors.crashApplication(r, crashInfo);
13169    }
13170
13171    public void handleApplicationStrictModeViolation(
13172            IBinder app,
13173            int violationMask,
13174            StrictMode.ViolationInfo info) {
13175        ProcessRecord r = findAppProcess(app, "StrictMode");
13176        if (r == null) {
13177            return;
13178        }
13179
13180        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13181            Integer stackFingerprint = info.hashCode();
13182            boolean logIt = true;
13183            synchronized (mAlreadyLoggedViolatedStacks) {
13184                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13185                    logIt = false;
13186                    // TODO: sub-sample into EventLog for these, with
13187                    // the info.durationMillis?  Then we'd get
13188                    // the relative pain numbers, without logging all
13189                    // the stack traces repeatedly.  We'd want to do
13190                    // likewise in the client code, which also does
13191                    // dup suppression, before the Binder call.
13192                } else {
13193                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13194                        mAlreadyLoggedViolatedStacks.clear();
13195                    }
13196                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13197                }
13198            }
13199            if (logIt) {
13200                logStrictModeViolationToDropBox(r, info);
13201            }
13202        }
13203
13204        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13205            AppErrorResult result = new AppErrorResult();
13206            synchronized (this) {
13207                final long origId = Binder.clearCallingIdentity();
13208
13209                Message msg = Message.obtain();
13210                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13211                HashMap<String, Object> data = new HashMap<String, Object>();
13212                data.put("result", result);
13213                data.put("app", r);
13214                data.put("violationMask", violationMask);
13215                data.put("info", info);
13216                msg.obj = data;
13217                mUiHandler.sendMessage(msg);
13218
13219                Binder.restoreCallingIdentity(origId);
13220            }
13221            int res = result.get();
13222            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13223        }
13224    }
13225
13226    // Depending on the policy in effect, there could be a bunch of
13227    // these in quick succession so we try to batch these together to
13228    // minimize disk writes, number of dropbox entries, and maximize
13229    // compression, by having more fewer, larger records.
13230    private void logStrictModeViolationToDropBox(
13231            ProcessRecord process,
13232            StrictMode.ViolationInfo info) {
13233        if (info == null) {
13234            return;
13235        }
13236        final boolean isSystemApp = process == null ||
13237                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13238                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13239        final String processName = process == null ? "unknown" : process.processName;
13240        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13241        final DropBoxManager dbox = (DropBoxManager)
13242                mContext.getSystemService(Context.DROPBOX_SERVICE);
13243
13244        // Exit early if the dropbox isn't configured to accept this report type.
13245        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13246
13247        boolean bufferWasEmpty;
13248        boolean needsFlush;
13249        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13250        synchronized (sb) {
13251            bufferWasEmpty = sb.length() == 0;
13252            appendDropBoxProcessHeaders(process, processName, sb);
13253            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13254            sb.append("System-App: ").append(isSystemApp).append("\n");
13255            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13256            if (info.violationNumThisLoop != 0) {
13257                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13258            }
13259            if (info.numAnimationsRunning != 0) {
13260                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13261            }
13262            if (info.broadcastIntentAction != null) {
13263                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13264            }
13265            if (info.durationMillis != -1) {
13266                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13267            }
13268            if (info.numInstances != -1) {
13269                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13270            }
13271            if (info.tags != null) {
13272                for (String tag : info.tags) {
13273                    sb.append("Span-Tag: ").append(tag).append("\n");
13274                }
13275            }
13276            sb.append("\n");
13277            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13278                sb.append(info.crashInfo.stackTrace);
13279                sb.append("\n");
13280            }
13281            if (info.message != null) {
13282                sb.append(info.message);
13283                sb.append("\n");
13284            }
13285
13286            // Only buffer up to ~64k.  Various logging bits truncate
13287            // things at 128k.
13288            needsFlush = (sb.length() > 64 * 1024);
13289        }
13290
13291        // Flush immediately if the buffer's grown too large, or this
13292        // is a non-system app.  Non-system apps are isolated with a
13293        // different tag & policy and not batched.
13294        //
13295        // Batching is useful during internal testing with
13296        // StrictMode settings turned up high.  Without batching,
13297        // thousands of separate files could be created on boot.
13298        if (!isSystemApp || needsFlush) {
13299            new Thread("Error dump: " + dropboxTag) {
13300                @Override
13301                public void run() {
13302                    String report;
13303                    synchronized (sb) {
13304                        report = sb.toString();
13305                        sb.delete(0, sb.length());
13306                        sb.trimToSize();
13307                    }
13308                    if (report.length() != 0) {
13309                        dbox.addText(dropboxTag, report);
13310                    }
13311                }
13312            }.start();
13313            return;
13314        }
13315
13316        // System app batching:
13317        if (!bufferWasEmpty) {
13318            // An existing dropbox-writing thread is outstanding, so
13319            // we don't need to start it up.  The existing thread will
13320            // catch the buffer appends we just did.
13321            return;
13322        }
13323
13324        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13325        // (After this point, we shouldn't access AMS internal data structures.)
13326        new Thread("Error dump: " + dropboxTag) {
13327            @Override
13328            public void run() {
13329                // 5 second sleep to let stacks arrive and be batched together
13330                try {
13331                    Thread.sleep(5000);  // 5 seconds
13332                } catch (InterruptedException e) {}
13333
13334                String errorReport;
13335                synchronized (mStrictModeBuffer) {
13336                    errorReport = mStrictModeBuffer.toString();
13337                    if (errorReport.length() == 0) {
13338                        return;
13339                    }
13340                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13341                    mStrictModeBuffer.trimToSize();
13342                }
13343                dbox.addText(dropboxTag, errorReport);
13344            }
13345        }.start();
13346    }
13347
13348    /**
13349     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13350     * @param app object of the crashing app, null for the system server
13351     * @param tag reported by the caller
13352     * @param system whether this wtf is coming from the system
13353     * @param crashInfo describing the context of the error
13354     * @return true if the process should exit immediately (WTF is fatal)
13355     */
13356    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13357            final ApplicationErrorReport.CrashInfo crashInfo) {
13358        final int callingUid = Binder.getCallingUid();
13359        final int callingPid = Binder.getCallingPid();
13360
13361        if (system) {
13362            // If this is coming from the system, we could very well have low-level
13363            // system locks held, so we want to do this all asynchronously.  And we
13364            // never want this to become fatal, so there is that too.
13365            mHandler.post(new Runnable() {
13366                @Override public void run() {
13367                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13368                }
13369            });
13370            return false;
13371        }
13372
13373        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13374                crashInfo);
13375
13376        if (r != null && r.pid != Process.myPid() &&
13377                Settings.Global.getInt(mContext.getContentResolver(),
13378                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13379            mAppErrors.crashApplication(r, crashInfo);
13380            return true;
13381        } else {
13382            return false;
13383        }
13384    }
13385
13386    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13387            final ApplicationErrorReport.CrashInfo crashInfo) {
13388        final ProcessRecord r = findAppProcess(app, "WTF");
13389        final String processName = app == null ? "system_server"
13390                : (r == null ? "unknown" : r.processName);
13391
13392        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13393                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13394
13395        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13396
13397        return r;
13398    }
13399
13400    /**
13401     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13402     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13403     */
13404    private ProcessRecord findAppProcess(IBinder app, String reason) {
13405        if (app == null) {
13406            return null;
13407        }
13408
13409        synchronized (this) {
13410            final int NP = mProcessNames.getMap().size();
13411            for (int ip=0; ip<NP; ip++) {
13412                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13413                final int NA = apps.size();
13414                for (int ia=0; ia<NA; ia++) {
13415                    ProcessRecord p = apps.valueAt(ia);
13416                    if (p.thread != null && p.thread.asBinder() == app) {
13417                        return p;
13418                    }
13419                }
13420            }
13421
13422            Slog.w(TAG, "Can't find mystery application for " + reason
13423                    + " from pid=" + Binder.getCallingPid()
13424                    + " uid=" + Binder.getCallingUid() + ": " + app);
13425            return null;
13426        }
13427    }
13428
13429    /**
13430     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13431     * to append various headers to the dropbox log text.
13432     */
13433    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13434            StringBuilder sb) {
13435        // Watchdog thread ends up invoking this function (with
13436        // a null ProcessRecord) to add the stack file to dropbox.
13437        // Do not acquire a lock on this (am) in such cases, as it
13438        // could cause a potential deadlock, if and when watchdog
13439        // is invoked due to unavailability of lock on am and it
13440        // would prevent watchdog from killing system_server.
13441        if (process == null) {
13442            sb.append("Process: ").append(processName).append("\n");
13443            return;
13444        }
13445        // Note: ProcessRecord 'process' is guarded by the service
13446        // instance.  (notably process.pkgList, which could otherwise change
13447        // concurrently during execution of this method)
13448        synchronized (this) {
13449            sb.append("Process: ").append(processName).append("\n");
13450            int flags = process.info.flags;
13451            IPackageManager pm = AppGlobals.getPackageManager();
13452            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13453            for (int ip=0; ip<process.pkgList.size(); ip++) {
13454                String pkg = process.pkgList.keyAt(ip);
13455                sb.append("Package: ").append(pkg);
13456                try {
13457                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13458                    if (pi != null) {
13459                        sb.append(" v").append(pi.versionCode);
13460                        if (pi.versionName != null) {
13461                            sb.append(" (").append(pi.versionName).append(")");
13462                        }
13463                    }
13464                } catch (RemoteException e) {
13465                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13466                }
13467                sb.append("\n");
13468            }
13469        }
13470    }
13471
13472    private static String processClass(ProcessRecord process) {
13473        if (process == null || process.pid == MY_PID) {
13474            return "system_server";
13475        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13476            return "system_app";
13477        } else {
13478            return "data_app";
13479        }
13480    }
13481
13482    private volatile long mWtfClusterStart;
13483    private volatile int mWtfClusterCount;
13484
13485    /**
13486     * Write a description of an error (crash, WTF, ANR) to the drop box.
13487     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13488     * @param process which caused the error, null means the system server
13489     * @param activity which triggered the error, null if unknown
13490     * @param parent activity related to the error, null if unknown
13491     * @param subject line related to the error, null if absent
13492     * @param report in long form describing the error, null if absent
13493     * @param logFile to include in the report, null if none
13494     * @param crashInfo giving an application stack trace, null if absent
13495     */
13496    public void addErrorToDropBox(String eventType,
13497            ProcessRecord process, String processName, ActivityRecord activity,
13498            ActivityRecord parent, String subject,
13499            final String report, final File logFile,
13500            final ApplicationErrorReport.CrashInfo crashInfo) {
13501        // NOTE -- this must never acquire the ActivityManagerService lock,
13502        // otherwise the watchdog may be prevented from resetting the system.
13503
13504        final String dropboxTag = processClass(process) + "_" + eventType;
13505        final DropBoxManager dbox = (DropBoxManager)
13506                mContext.getSystemService(Context.DROPBOX_SERVICE);
13507
13508        // Exit early if the dropbox isn't configured to accept this report type.
13509        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13510
13511        // Rate-limit how often we're willing to do the heavy lifting below to
13512        // collect and record logs; currently 5 logs per 10 second period.
13513        final long now = SystemClock.elapsedRealtime();
13514        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13515            mWtfClusterStart = now;
13516            mWtfClusterCount = 1;
13517        } else {
13518            if (mWtfClusterCount++ >= 5) return;
13519        }
13520
13521        final StringBuilder sb = new StringBuilder(1024);
13522        appendDropBoxProcessHeaders(process, processName, sb);
13523        if (process != null) {
13524            sb.append("Foreground: ")
13525                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13526                    .append("\n");
13527        }
13528        if (activity != null) {
13529            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13530        }
13531        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13532            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13533        }
13534        if (parent != null && parent != activity) {
13535            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13536        }
13537        if (subject != null) {
13538            sb.append("Subject: ").append(subject).append("\n");
13539        }
13540        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13541        if (Debug.isDebuggerConnected()) {
13542            sb.append("Debugger: Connected\n");
13543        }
13544        sb.append("\n");
13545
13546        // Do the rest in a worker thread to avoid blocking the caller on I/O
13547        // (After this point, we shouldn't access AMS internal data structures.)
13548        Thread worker = new Thread("Error dump: " + dropboxTag) {
13549            @Override
13550            public void run() {
13551                if (report != null) {
13552                    sb.append(report);
13553                }
13554                if (logFile != null) {
13555                    try {
13556                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13557                                    "\n\n[[TRUNCATED]]"));
13558                    } catch (IOException e) {
13559                        Slog.e(TAG, "Error reading " + logFile, e);
13560                    }
13561                }
13562                if (crashInfo != null && crashInfo.stackTrace != null) {
13563                    sb.append(crashInfo.stackTrace);
13564                }
13565
13566                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13567                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13568                if (lines > 0) {
13569                    sb.append("\n");
13570
13571                    // Merge several logcat streams, and take the last N lines
13572                    InputStreamReader input = null;
13573                    try {
13574                        java.lang.Process logcat = new ProcessBuilder(
13575                                "/system/bin/timeout", "-k", "15s", "10s",
13576                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13577                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13578                                        .redirectErrorStream(true).start();
13579
13580                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13581                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13582                        input = new InputStreamReader(logcat.getInputStream());
13583
13584                        int num;
13585                        char[] buf = new char[8192];
13586                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13587                    } catch (IOException e) {
13588                        Slog.e(TAG, "Error running logcat", e);
13589                    } finally {
13590                        if (input != null) try { input.close(); } catch (IOException e) {}
13591                    }
13592                }
13593
13594                dbox.addText(dropboxTag, sb.toString());
13595            }
13596        };
13597
13598        if (process == null) {
13599            // If process is null, we are being called from some internal code
13600            // and may be about to die -- run this synchronously.
13601            worker.run();
13602        } else {
13603            worker.start();
13604        }
13605    }
13606
13607    @Override
13608    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13609        enforceNotIsolatedCaller("getProcessesInErrorState");
13610        // assume our apps are happy - lazy create the list
13611        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13612
13613        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13614                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13615        int userId = UserHandle.getUserId(Binder.getCallingUid());
13616
13617        synchronized (this) {
13618
13619            // iterate across all processes
13620            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13621                ProcessRecord app = mLruProcesses.get(i);
13622                if (!allUsers && app.userId != userId) {
13623                    continue;
13624                }
13625                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13626                    // This one's in trouble, so we'll generate a report for it
13627                    // crashes are higher priority (in case there's a crash *and* an anr)
13628                    ActivityManager.ProcessErrorStateInfo report = null;
13629                    if (app.crashing) {
13630                        report = app.crashingReport;
13631                    } else if (app.notResponding) {
13632                        report = app.notRespondingReport;
13633                    }
13634
13635                    if (report != null) {
13636                        if (errList == null) {
13637                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13638                        }
13639                        errList.add(report);
13640                    } else {
13641                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13642                                " crashing = " + app.crashing +
13643                                " notResponding = " + app.notResponding);
13644                    }
13645                }
13646            }
13647        }
13648
13649        return errList;
13650    }
13651
13652    static int procStateToImportance(int procState, int memAdj,
13653            ActivityManager.RunningAppProcessInfo currApp) {
13654        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13655        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13656            currApp.lru = memAdj;
13657        } else {
13658            currApp.lru = 0;
13659        }
13660        return imp;
13661    }
13662
13663    private void fillInProcMemInfo(ProcessRecord app,
13664            ActivityManager.RunningAppProcessInfo outInfo) {
13665        outInfo.pid = app.pid;
13666        outInfo.uid = app.info.uid;
13667        if (mHeavyWeightProcess == app) {
13668            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13669        }
13670        if (app.persistent) {
13671            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13672        }
13673        if (app.activities.size() > 0) {
13674            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13675        }
13676        outInfo.lastTrimLevel = app.trimMemoryLevel;
13677        int adj = app.curAdj;
13678        int procState = app.curProcState;
13679        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13680        outInfo.importanceReasonCode = app.adjTypeCode;
13681        outInfo.processState = app.curProcState;
13682    }
13683
13684    @Override
13685    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13686        enforceNotIsolatedCaller("getRunningAppProcesses");
13687
13688        final int callingUid = Binder.getCallingUid();
13689
13690        // Lazy instantiation of list
13691        List<ActivityManager.RunningAppProcessInfo> runList = null;
13692        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13693                callingUid) == PackageManager.PERMISSION_GRANTED;
13694        final int userId = UserHandle.getUserId(callingUid);
13695        final boolean allUids = isGetTasksAllowed(
13696                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13697
13698        synchronized (this) {
13699            // Iterate across all processes
13700            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13701                ProcessRecord app = mLruProcesses.get(i);
13702                if ((!allUsers && app.userId != userId)
13703                        || (!allUids && app.uid != callingUid)) {
13704                    continue;
13705                }
13706                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13707                    // Generate process state info for running application
13708                    ActivityManager.RunningAppProcessInfo currApp =
13709                        new ActivityManager.RunningAppProcessInfo(app.processName,
13710                                app.pid, app.getPackageList());
13711                    fillInProcMemInfo(app, currApp);
13712                    if (app.adjSource instanceof ProcessRecord) {
13713                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13714                        currApp.importanceReasonImportance =
13715                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13716                                        app.adjSourceProcState);
13717                    } else if (app.adjSource instanceof ActivityRecord) {
13718                        ActivityRecord r = (ActivityRecord)app.adjSource;
13719                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13720                    }
13721                    if (app.adjTarget instanceof ComponentName) {
13722                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13723                    }
13724                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13725                    //        + " lru=" + currApp.lru);
13726                    if (runList == null) {
13727                        runList = new ArrayList<>();
13728                    }
13729                    runList.add(currApp);
13730                }
13731            }
13732        }
13733        return runList;
13734    }
13735
13736    @Override
13737    public List<ApplicationInfo> getRunningExternalApplications() {
13738        enforceNotIsolatedCaller("getRunningExternalApplications");
13739        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13740        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13741        if (runningApps != null && runningApps.size() > 0) {
13742            Set<String> extList = new HashSet<String>();
13743            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13744                if (app.pkgList != null) {
13745                    for (String pkg : app.pkgList) {
13746                        extList.add(pkg);
13747                    }
13748                }
13749            }
13750            IPackageManager pm = AppGlobals.getPackageManager();
13751            for (String pkg : extList) {
13752                try {
13753                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13754                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13755                        retList.add(info);
13756                    }
13757                } catch (RemoteException e) {
13758                }
13759            }
13760        }
13761        return retList;
13762    }
13763
13764    @Override
13765    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13766        enforceNotIsolatedCaller("getMyMemoryState");
13767        synchronized (this) {
13768            ProcessRecord proc;
13769            synchronized (mPidsSelfLocked) {
13770                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13771            }
13772            fillInProcMemInfo(proc, outInfo);
13773        }
13774    }
13775
13776    @Override
13777    public int getMemoryTrimLevel() {
13778        enforceNotIsolatedCaller("getMyMemoryState");
13779        synchronized (this) {
13780            return mLastMemoryLevel;
13781        }
13782    }
13783
13784    @Override
13785    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13786            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13787        (new ActivityManagerShellCommand(this, false)).exec(
13788                this, in, out, err, args, resultReceiver);
13789    }
13790
13791    @Override
13792    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13793        if (checkCallingPermission(android.Manifest.permission.DUMP)
13794                != PackageManager.PERMISSION_GRANTED) {
13795            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13796                    + Binder.getCallingPid()
13797                    + ", uid=" + Binder.getCallingUid()
13798                    + " without permission "
13799                    + android.Manifest.permission.DUMP);
13800            return;
13801        }
13802
13803        boolean dumpAll = false;
13804        boolean dumpClient = false;
13805        boolean dumpCheckin = false;
13806        boolean dumpCheckinFormat = false;
13807        String dumpPackage = null;
13808
13809        int opti = 0;
13810        while (opti < args.length) {
13811            String opt = args[opti];
13812            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13813                break;
13814            }
13815            opti++;
13816            if ("-a".equals(opt)) {
13817                dumpAll = true;
13818            } else if ("-c".equals(opt)) {
13819                dumpClient = true;
13820            } else if ("-p".equals(opt)) {
13821                if (opti < args.length) {
13822                    dumpPackage = args[opti];
13823                    opti++;
13824                } else {
13825                    pw.println("Error: -p option requires package argument");
13826                    return;
13827                }
13828                dumpClient = true;
13829            } else if ("--checkin".equals(opt)) {
13830                dumpCheckin = dumpCheckinFormat = true;
13831            } else if ("-C".equals(opt)) {
13832                dumpCheckinFormat = true;
13833            } else if ("-h".equals(opt)) {
13834                ActivityManagerShellCommand.dumpHelp(pw, true);
13835                return;
13836            } else {
13837                pw.println("Unknown argument: " + opt + "; use -h for help");
13838            }
13839        }
13840
13841        long origId = Binder.clearCallingIdentity();
13842        boolean more = false;
13843        // Is the caller requesting to dump a particular piece of data?
13844        if (opti < args.length) {
13845            String cmd = args[opti];
13846            opti++;
13847            if ("activities".equals(cmd) || "a".equals(cmd)) {
13848                synchronized (this) {
13849                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13850                }
13851            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13852                synchronized (this) {
13853                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13854                }
13855            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13856                String[] newArgs;
13857                String name;
13858                if (opti >= args.length) {
13859                    name = null;
13860                    newArgs = EMPTY_STRING_ARRAY;
13861                } else {
13862                    dumpPackage = args[opti];
13863                    opti++;
13864                    newArgs = new String[args.length - opti];
13865                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13866                            args.length - opti);
13867                }
13868                synchronized (this) {
13869                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13870                }
13871            } else if ("broadcast-stats".equals(cmd)) {
13872                String[] newArgs;
13873                String name;
13874                if (opti >= args.length) {
13875                    name = null;
13876                    newArgs = EMPTY_STRING_ARRAY;
13877                } else {
13878                    dumpPackage = args[opti];
13879                    opti++;
13880                    newArgs = new String[args.length - opti];
13881                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13882                            args.length - opti);
13883                }
13884                synchronized (this) {
13885                    if (dumpCheckinFormat) {
13886                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13887                                dumpPackage);
13888                    } else {
13889                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13890                    }
13891                }
13892            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13893                String[] newArgs;
13894                String name;
13895                if (opti >= args.length) {
13896                    name = null;
13897                    newArgs = EMPTY_STRING_ARRAY;
13898                } else {
13899                    dumpPackage = args[opti];
13900                    opti++;
13901                    newArgs = new String[args.length - opti];
13902                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13903                            args.length - opti);
13904                }
13905                synchronized (this) {
13906                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13907                }
13908            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13909                String[] newArgs;
13910                String name;
13911                if (opti >= args.length) {
13912                    name = null;
13913                    newArgs = EMPTY_STRING_ARRAY;
13914                } else {
13915                    dumpPackage = args[opti];
13916                    opti++;
13917                    newArgs = new String[args.length - opti];
13918                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13919                            args.length - opti);
13920                }
13921                synchronized (this) {
13922                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13923                }
13924            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13925                synchronized (this) {
13926                    dumpOomLocked(fd, pw, args, opti, true);
13927                }
13928            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13929                synchronized (this) {
13930                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13931                }
13932            } else if ("provider".equals(cmd)) {
13933                String[] newArgs;
13934                String name;
13935                if (opti >= args.length) {
13936                    name = null;
13937                    newArgs = EMPTY_STRING_ARRAY;
13938                } else {
13939                    name = args[opti];
13940                    opti++;
13941                    newArgs = new String[args.length - opti];
13942                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13943                }
13944                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13945                    pw.println("No providers match: " + name);
13946                    pw.println("Use -h for help.");
13947                }
13948            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13949                synchronized (this) {
13950                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13951                }
13952            } else if ("service".equals(cmd)) {
13953                String[] newArgs;
13954                String name;
13955                if (opti >= args.length) {
13956                    name = null;
13957                    newArgs = EMPTY_STRING_ARRAY;
13958                } else {
13959                    name = args[opti];
13960                    opti++;
13961                    newArgs = new String[args.length - opti];
13962                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13963                            args.length - opti);
13964                }
13965                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13966                    pw.println("No services match: " + name);
13967                    pw.println("Use -h for help.");
13968                }
13969            } else if ("package".equals(cmd)) {
13970                String[] newArgs;
13971                if (opti >= args.length) {
13972                    pw.println("package: no package name specified");
13973                    pw.println("Use -h for help.");
13974                } else {
13975                    dumpPackage = args[opti];
13976                    opti++;
13977                    newArgs = new String[args.length - opti];
13978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13979                            args.length - opti);
13980                    args = newArgs;
13981                    opti = 0;
13982                    more = true;
13983                }
13984            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13985                synchronized (this) {
13986                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13987                }
13988            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13989                if (dumpClient) {
13990                    ActiveServices.ServiceDumper dumper;
13991                    synchronized (this) {
13992                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13993                                dumpPackage);
13994                    }
13995                    dumper.dumpWithClient();
13996                } else {
13997                    synchronized (this) {
13998                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13999                                dumpPackage).dumpLocked();
14000                    }
14001                }
14002            } else if ("locks".equals(cmd)) {
14003                LockGuard.dump(fd, pw, args);
14004            } else {
14005                // Dumping a single activity?
14006                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14007                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14008                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14009                    if (res < 0) {
14010                        pw.println("Bad activity command, or no activities match: " + cmd);
14011                        pw.println("Use -h for help.");
14012                    }
14013                }
14014            }
14015            if (!more) {
14016                Binder.restoreCallingIdentity(origId);
14017                return;
14018            }
14019        }
14020
14021        // No piece of data specified, dump everything.
14022        if (dumpCheckinFormat) {
14023            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14024        } else if (dumpClient) {
14025            ActiveServices.ServiceDumper sdumper;
14026            synchronized (this) {
14027                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14028                pw.println();
14029                if (dumpAll) {
14030                    pw.println("-------------------------------------------------------------------------------");
14031                }
14032                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14033                pw.println();
14034                if (dumpAll) {
14035                    pw.println("-------------------------------------------------------------------------------");
14036                }
14037                if (dumpAll || dumpPackage != null) {
14038                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14039                    pw.println();
14040                    if (dumpAll) {
14041                        pw.println("-------------------------------------------------------------------------------");
14042                    }
14043                }
14044                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14045                pw.println();
14046                if (dumpAll) {
14047                    pw.println("-------------------------------------------------------------------------------");
14048                }
14049                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14050                pw.println();
14051                if (dumpAll) {
14052                    pw.println("-------------------------------------------------------------------------------");
14053                }
14054                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14055                        dumpPackage);
14056            }
14057            sdumper.dumpWithClient();
14058            pw.println();
14059            synchronized (this) {
14060                if (dumpAll) {
14061                    pw.println("-------------------------------------------------------------------------------");
14062                }
14063                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14064                pw.println();
14065                if (dumpAll) {
14066                    pw.println("-------------------------------------------------------------------------------");
14067                }
14068                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14069                if (mAssociations.size() > 0) {
14070                    pw.println();
14071                    if (dumpAll) {
14072                        pw.println("-------------------------------------------------------------------------------");
14073                    }
14074                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14075                }
14076                pw.println();
14077                if (dumpAll) {
14078                    pw.println("-------------------------------------------------------------------------------");
14079                }
14080                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14081            }
14082
14083        } else {
14084            synchronized (this) {
14085                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14086                pw.println();
14087                if (dumpAll) {
14088                    pw.println("-------------------------------------------------------------------------------");
14089                }
14090                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14091                pw.println();
14092                if (dumpAll) {
14093                    pw.println("-------------------------------------------------------------------------------");
14094                }
14095                if (dumpAll || dumpPackage != null) {
14096                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14097                    pw.println();
14098                    if (dumpAll) {
14099                        pw.println("-------------------------------------------------------------------------------");
14100                    }
14101                }
14102                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14103                pw.println();
14104                if (dumpAll) {
14105                    pw.println("-------------------------------------------------------------------------------");
14106                }
14107                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14108                pw.println();
14109                if (dumpAll) {
14110                    pw.println("-------------------------------------------------------------------------------");
14111                }
14112                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14113                        .dumpLocked();
14114                pw.println();
14115                if (dumpAll) {
14116                    pw.println("-------------------------------------------------------------------------------");
14117                }
14118                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14119                pw.println();
14120                if (dumpAll) {
14121                    pw.println("-------------------------------------------------------------------------------");
14122                }
14123                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14124                if (mAssociations.size() > 0) {
14125                    pw.println();
14126                    if (dumpAll) {
14127                        pw.println("-------------------------------------------------------------------------------");
14128                    }
14129                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14130                }
14131                pw.println();
14132                if (dumpAll) {
14133                    pw.println("-------------------------------------------------------------------------------");
14134                }
14135                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14136            }
14137        }
14138        Binder.restoreCallingIdentity(origId);
14139    }
14140
14141    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14142            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14143        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14144
14145        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14146                dumpPackage);
14147        boolean needSep = printedAnything;
14148
14149        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14150                dumpPackage, needSep, "  mFocusedActivity: ");
14151        if (printed) {
14152            printedAnything = true;
14153            needSep = false;
14154        }
14155
14156        if (dumpPackage == null) {
14157            if (needSep) {
14158                pw.println();
14159            }
14160            needSep = true;
14161            printedAnything = true;
14162            mStackSupervisor.dump(pw, "  ");
14163        }
14164
14165        if (!printedAnything) {
14166            pw.println("  (nothing)");
14167        }
14168    }
14169
14170    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14171            int opti, boolean dumpAll, String dumpPackage) {
14172        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14173
14174        boolean printedAnything = false;
14175
14176        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14177            boolean printedHeader = false;
14178
14179            final int N = mRecentTasks.size();
14180            for (int i=0; i<N; i++) {
14181                TaskRecord tr = mRecentTasks.get(i);
14182                if (dumpPackage != null) {
14183                    if (tr.realActivity == null ||
14184                            !dumpPackage.equals(tr.realActivity)) {
14185                        continue;
14186                    }
14187                }
14188                if (!printedHeader) {
14189                    pw.println("  Recent tasks:");
14190                    printedHeader = true;
14191                    printedAnything = true;
14192                }
14193                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14194                        pw.println(tr);
14195                if (dumpAll) {
14196                    mRecentTasks.get(i).dump(pw, "    ");
14197                }
14198            }
14199        }
14200
14201        if (!printedAnything) {
14202            pw.println("  (nothing)");
14203        }
14204    }
14205
14206    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14207            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14208        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14209
14210        int dumpUid = 0;
14211        if (dumpPackage != null) {
14212            IPackageManager pm = AppGlobals.getPackageManager();
14213            try {
14214                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14215            } catch (RemoteException e) {
14216            }
14217        }
14218
14219        boolean printedAnything = false;
14220
14221        final long now = SystemClock.uptimeMillis();
14222
14223        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14224            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14225                    = mAssociations.valueAt(i1);
14226            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14227                SparseArray<ArrayMap<String, Association>> sourceUids
14228                        = targetComponents.valueAt(i2);
14229                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14230                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14231                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14232                        Association ass = sourceProcesses.valueAt(i4);
14233                        if (dumpPackage != null) {
14234                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14235                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14236                                continue;
14237                            }
14238                        }
14239                        printedAnything = true;
14240                        pw.print("  ");
14241                        pw.print(ass.mTargetProcess);
14242                        pw.print("/");
14243                        UserHandle.formatUid(pw, ass.mTargetUid);
14244                        pw.print(" <- ");
14245                        pw.print(ass.mSourceProcess);
14246                        pw.print("/");
14247                        UserHandle.formatUid(pw, ass.mSourceUid);
14248                        pw.println();
14249                        pw.print("    via ");
14250                        pw.print(ass.mTargetComponent.flattenToShortString());
14251                        pw.println();
14252                        pw.print("    ");
14253                        long dur = ass.mTime;
14254                        if (ass.mNesting > 0) {
14255                            dur += now - ass.mStartTime;
14256                        }
14257                        TimeUtils.formatDuration(dur, pw);
14258                        pw.print(" (");
14259                        pw.print(ass.mCount);
14260                        pw.print(" times)");
14261                        pw.print("  ");
14262                        for (int i=0; i<ass.mStateTimes.length; i++) {
14263                            long amt = ass.mStateTimes[i];
14264                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14265                                amt += now - ass.mLastStateUptime;
14266                            }
14267                            if (amt != 0) {
14268                                pw.print(" ");
14269                                pw.print(ProcessList.makeProcStateString(
14270                                            i + ActivityManager.MIN_PROCESS_STATE));
14271                                pw.print("=");
14272                                TimeUtils.formatDuration(amt, pw);
14273                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14274                                    pw.print("*");
14275                                }
14276                            }
14277                        }
14278                        pw.println();
14279                        if (ass.mNesting > 0) {
14280                            pw.print("    Currently active: ");
14281                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14282                            pw.println();
14283                        }
14284                    }
14285                }
14286            }
14287
14288        }
14289
14290        if (!printedAnything) {
14291            pw.println("  (nothing)");
14292        }
14293    }
14294
14295    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14296            String header, boolean needSep) {
14297        boolean printed = false;
14298        int whichAppId = -1;
14299        if (dumpPackage != null) {
14300            try {
14301                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14302                        dumpPackage, 0);
14303                whichAppId = UserHandle.getAppId(info.uid);
14304            } catch (NameNotFoundException e) {
14305                e.printStackTrace();
14306            }
14307        }
14308        for (int i=0; i<uids.size(); i++) {
14309            UidRecord uidRec = uids.valueAt(i);
14310            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14311                continue;
14312            }
14313            if (!printed) {
14314                printed = true;
14315                if (needSep) {
14316                    pw.println();
14317                }
14318                pw.print("  ");
14319                pw.println(header);
14320                needSep = true;
14321            }
14322            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14323            pw.print(": "); pw.println(uidRec);
14324        }
14325        return printed;
14326    }
14327
14328    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14329            int opti, boolean dumpAll, String dumpPackage) {
14330        boolean needSep = false;
14331        boolean printedAnything = false;
14332        int numPers = 0;
14333
14334        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14335
14336        if (dumpAll) {
14337            final int NP = mProcessNames.getMap().size();
14338            for (int ip=0; ip<NP; ip++) {
14339                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14340                final int NA = procs.size();
14341                for (int ia=0; ia<NA; ia++) {
14342                    ProcessRecord r = procs.valueAt(ia);
14343                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14344                        continue;
14345                    }
14346                    if (!needSep) {
14347                        pw.println("  All known processes:");
14348                        needSep = true;
14349                        printedAnything = true;
14350                    }
14351                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14352                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14353                        pw.print(" "); pw.println(r);
14354                    r.dump(pw, "    ");
14355                    if (r.persistent) {
14356                        numPers++;
14357                    }
14358                }
14359            }
14360        }
14361
14362        if (mIsolatedProcesses.size() > 0) {
14363            boolean printed = false;
14364            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14365                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14366                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14367                    continue;
14368                }
14369                if (!printed) {
14370                    if (needSep) {
14371                        pw.println();
14372                    }
14373                    pw.println("  Isolated process list (sorted by uid):");
14374                    printedAnything = true;
14375                    printed = true;
14376                    needSep = true;
14377                }
14378                pw.println(String.format("%sIsolated #%2d: %s",
14379                        "    ", i, r.toString()));
14380            }
14381        }
14382
14383        if (mActiveUids.size() > 0) {
14384            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14385                printedAnything = needSep = true;
14386            }
14387        }
14388        if (mValidateUids.size() > 0) {
14389            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14390                printedAnything = needSep = true;
14391            }
14392        }
14393
14394        if (mLruProcesses.size() > 0) {
14395            if (needSep) {
14396                pw.println();
14397            }
14398            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14399                    pw.print(" total, non-act at ");
14400                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14401                    pw.print(", non-svc at ");
14402                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14403                    pw.println("):");
14404            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14405            needSep = true;
14406            printedAnything = true;
14407        }
14408
14409        if (dumpAll || dumpPackage != null) {
14410            synchronized (mPidsSelfLocked) {
14411                boolean printed = false;
14412                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14413                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14414                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14415                        continue;
14416                    }
14417                    if (!printed) {
14418                        if (needSep) pw.println();
14419                        needSep = true;
14420                        pw.println("  PID mappings:");
14421                        printed = true;
14422                        printedAnything = true;
14423                    }
14424                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14425                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14426                }
14427            }
14428        }
14429
14430        if (mForegroundProcesses.size() > 0) {
14431            synchronized (mPidsSelfLocked) {
14432                boolean printed = false;
14433                for (int i=0; i<mForegroundProcesses.size(); i++) {
14434                    ProcessRecord r = mPidsSelfLocked.get(
14435                            mForegroundProcesses.valueAt(i).pid);
14436                    if (dumpPackage != null && (r == null
14437                            || !r.pkgList.containsKey(dumpPackage))) {
14438                        continue;
14439                    }
14440                    if (!printed) {
14441                        if (needSep) pw.println();
14442                        needSep = true;
14443                        pw.println("  Foreground Processes:");
14444                        printed = true;
14445                        printedAnything = true;
14446                    }
14447                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14448                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14449                }
14450            }
14451        }
14452
14453        if (mPersistentStartingProcesses.size() > 0) {
14454            if (needSep) pw.println();
14455            needSep = true;
14456            printedAnything = true;
14457            pw.println("  Persisent processes that are starting:");
14458            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14459                    "Starting Norm", "Restarting PERS", dumpPackage);
14460        }
14461
14462        if (mRemovedProcesses.size() > 0) {
14463            if (needSep) pw.println();
14464            needSep = true;
14465            printedAnything = true;
14466            pw.println("  Processes that are being removed:");
14467            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14468                    "Removed Norm", "Removed PERS", dumpPackage);
14469        }
14470
14471        if (mProcessesOnHold.size() > 0) {
14472            if (needSep) pw.println();
14473            needSep = true;
14474            printedAnything = true;
14475            pw.println("  Processes that are on old until the system is ready:");
14476            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14477                    "OnHold Norm", "OnHold PERS", dumpPackage);
14478        }
14479
14480        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14481
14482        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14483        if (needSep) {
14484            printedAnything = true;
14485        }
14486
14487        if (dumpPackage == null) {
14488            pw.println();
14489            needSep = false;
14490            mUserController.dump(pw, dumpAll);
14491        }
14492        if (mHomeProcess != null && (dumpPackage == null
14493                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14494            if (needSep) {
14495                pw.println();
14496                needSep = false;
14497            }
14498            pw.println("  mHomeProcess: " + mHomeProcess);
14499        }
14500        if (mPreviousProcess != null && (dumpPackage == null
14501                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14502            if (needSep) {
14503                pw.println();
14504                needSep = false;
14505            }
14506            pw.println("  mPreviousProcess: " + mPreviousProcess);
14507        }
14508        if (dumpAll) {
14509            StringBuilder sb = new StringBuilder(128);
14510            sb.append("  mPreviousProcessVisibleTime: ");
14511            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14512            pw.println(sb);
14513        }
14514        if (mHeavyWeightProcess != null && (dumpPackage == null
14515                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14516            if (needSep) {
14517                pw.println();
14518                needSep = false;
14519            }
14520            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14521        }
14522        if (dumpPackage == null) {
14523            pw.println("  mConfiguration: " + mConfiguration);
14524        }
14525        if (dumpAll) {
14526            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14527            if (mCompatModePackages.getPackages().size() > 0) {
14528                boolean printed = false;
14529                for (Map.Entry<String, Integer> entry
14530                        : mCompatModePackages.getPackages().entrySet()) {
14531                    String pkg = entry.getKey();
14532                    int mode = entry.getValue();
14533                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14534                        continue;
14535                    }
14536                    if (!printed) {
14537                        pw.println("  mScreenCompatPackages:");
14538                        printed = true;
14539                    }
14540                    pw.print("    "); pw.print(pkg); pw.print(": ");
14541                            pw.print(mode); pw.println();
14542                }
14543            }
14544        }
14545        if (dumpPackage == null) {
14546            pw.println("  mWakefulness="
14547                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14548            pw.println("  mSleepTokens=" + mSleepTokens);
14549            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14550                    + lockScreenShownToString());
14551            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14552            if (mRunningVoice != null) {
14553                pw.println("  mRunningVoice=" + mRunningVoice);
14554                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14555            }
14556        }
14557        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14558                || mOrigWaitForDebugger) {
14559            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14560                    || dumpPackage.equals(mOrigDebugApp)) {
14561                if (needSep) {
14562                    pw.println();
14563                    needSep = false;
14564                }
14565                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14566                        + " mDebugTransient=" + mDebugTransient
14567                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14568            }
14569        }
14570        if (mCurAppTimeTracker != null) {
14571            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14572        }
14573        if (mMemWatchProcesses.getMap().size() > 0) {
14574            pw.println("  Mem watch processes:");
14575            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14576                    = mMemWatchProcesses.getMap();
14577            for (int i=0; i<procs.size(); i++) {
14578                final String proc = procs.keyAt(i);
14579                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14580                for (int j=0; j<uids.size(); j++) {
14581                    if (needSep) {
14582                        pw.println();
14583                        needSep = false;
14584                    }
14585                    StringBuilder sb = new StringBuilder();
14586                    sb.append("    ").append(proc).append('/');
14587                    UserHandle.formatUid(sb, uids.keyAt(j));
14588                    Pair<Long, String> val = uids.valueAt(j);
14589                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14590                    if (val.second != null) {
14591                        sb.append(", report to ").append(val.second);
14592                    }
14593                    pw.println(sb.toString());
14594                }
14595            }
14596            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14597            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14598            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14599                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14600        }
14601        if (mTrackAllocationApp != null) {
14602            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14603                if (needSep) {
14604                    pw.println();
14605                    needSep = false;
14606                }
14607                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14608            }
14609        }
14610        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14611                || mProfileFd != null) {
14612            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14613                if (needSep) {
14614                    pw.println();
14615                    needSep = false;
14616                }
14617                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14618                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14619                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14620                        + mAutoStopProfiler);
14621                pw.println("  mProfileType=" + mProfileType);
14622            }
14623        }
14624        if (mNativeDebuggingApp != null) {
14625            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14626                if (needSep) {
14627                    pw.println();
14628                    needSep = false;
14629                }
14630                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14631            }
14632        }
14633        if (dumpPackage == null) {
14634            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14635                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14636                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14637            }
14638            if (mController != null) {
14639                pw.println("  mController=" + mController
14640                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14641            }
14642            if (dumpAll) {
14643                pw.println("  Total persistent processes: " + numPers);
14644                pw.println("  mProcessesReady=" + mProcessesReady
14645                        + " mSystemReady=" + mSystemReady
14646                        + " mBooted=" + mBooted
14647                        + " mFactoryTest=" + mFactoryTest);
14648                pw.println("  mBooting=" + mBooting
14649                        + " mCallFinishBooting=" + mCallFinishBooting
14650                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14651                pw.print("  mLastPowerCheckRealtime=");
14652                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14653                        pw.println("");
14654                pw.print("  mLastPowerCheckUptime=");
14655                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14656                        pw.println("");
14657                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14658                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14659                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14660                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14661                        + " (" + mLruProcesses.size() + " total)"
14662                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14663                        + " mNumServiceProcs=" + mNumServiceProcs
14664                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14665                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14666                        + " mLastMemoryLevel=" + mLastMemoryLevel
14667                        + " mLastNumProcesses=" + mLastNumProcesses);
14668                long now = SystemClock.uptimeMillis();
14669                pw.print("  mLastIdleTime=");
14670                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14671                        pw.print(" mLowRamSinceLastIdle=");
14672                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14673                        pw.println();
14674            }
14675        }
14676
14677        if (!printedAnything) {
14678            pw.println("  (nothing)");
14679        }
14680    }
14681
14682    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14683            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14684        if (mProcessesToGc.size() > 0) {
14685            boolean printed = false;
14686            long now = SystemClock.uptimeMillis();
14687            for (int i=0; i<mProcessesToGc.size(); i++) {
14688                ProcessRecord proc = mProcessesToGc.get(i);
14689                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14690                    continue;
14691                }
14692                if (!printed) {
14693                    if (needSep) pw.println();
14694                    needSep = true;
14695                    pw.println("  Processes that are waiting to GC:");
14696                    printed = true;
14697                }
14698                pw.print("    Process "); pw.println(proc);
14699                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14700                        pw.print(", last gced=");
14701                        pw.print(now-proc.lastRequestedGc);
14702                        pw.print(" ms ago, last lowMem=");
14703                        pw.print(now-proc.lastLowMemory);
14704                        pw.println(" ms ago");
14705
14706            }
14707        }
14708        return needSep;
14709    }
14710
14711    void printOomLevel(PrintWriter pw, String name, int adj) {
14712        pw.print("    ");
14713        if (adj >= 0) {
14714            pw.print(' ');
14715            if (adj < 10) pw.print(' ');
14716        } else {
14717            if (adj > -10) pw.print(' ');
14718        }
14719        pw.print(adj);
14720        pw.print(": ");
14721        pw.print(name);
14722        pw.print(" (");
14723        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14724        pw.println(")");
14725    }
14726
14727    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14728            int opti, boolean dumpAll) {
14729        boolean needSep = false;
14730
14731        if (mLruProcesses.size() > 0) {
14732            if (needSep) pw.println();
14733            needSep = true;
14734            pw.println("  OOM levels:");
14735            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14736            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14737            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14738            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14739            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14740            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14741            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14742            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14743            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14744            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14745            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14746            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14747            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14748            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14749
14750            if (needSep) pw.println();
14751            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14752                    pw.print(" total, non-act at ");
14753                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14754                    pw.print(", non-svc at ");
14755                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14756                    pw.println("):");
14757            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14758            needSep = true;
14759        }
14760
14761        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14762
14763        pw.println();
14764        pw.println("  mHomeProcess: " + mHomeProcess);
14765        pw.println("  mPreviousProcess: " + mPreviousProcess);
14766        if (mHeavyWeightProcess != null) {
14767            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14768        }
14769
14770        return true;
14771    }
14772
14773    /**
14774     * There are three ways to call this:
14775     *  - no provider specified: dump all the providers
14776     *  - a flattened component name that matched an existing provider was specified as the
14777     *    first arg: dump that one provider
14778     *  - the first arg isn't the flattened component name of an existing provider:
14779     *    dump all providers whose component contains the first arg as a substring
14780     */
14781    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14782            int opti, boolean dumpAll) {
14783        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14784    }
14785
14786    static class ItemMatcher {
14787        ArrayList<ComponentName> components;
14788        ArrayList<String> strings;
14789        ArrayList<Integer> objects;
14790        boolean all;
14791
14792        ItemMatcher() {
14793            all = true;
14794        }
14795
14796        void build(String name) {
14797            ComponentName componentName = ComponentName.unflattenFromString(name);
14798            if (componentName != null) {
14799                if (components == null) {
14800                    components = new ArrayList<ComponentName>();
14801                }
14802                components.add(componentName);
14803                all = false;
14804            } else {
14805                int objectId = 0;
14806                // Not a '/' separated full component name; maybe an object ID?
14807                try {
14808                    objectId = Integer.parseInt(name, 16);
14809                    if (objects == null) {
14810                        objects = new ArrayList<Integer>();
14811                    }
14812                    objects.add(objectId);
14813                    all = false;
14814                } catch (RuntimeException e) {
14815                    // Not an integer; just do string match.
14816                    if (strings == null) {
14817                        strings = new ArrayList<String>();
14818                    }
14819                    strings.add(name);
14820                    all = false;
14821                }
14822            }
14823        }
14824
14825        int build(String[] args, int opti) {
14826            for (; opti<args.length; opti++) {
14827                String name = args[opti];
14828                if ("--".equals(name)) {
14829                    return opti+1;
14830                }
14831                build(name);
14832            }
14833            return opti;
14834        }
14835
14836        boolean match(Object object, ComponentName comp) {
14837            if (all) {
14838                return true;
14839            }
14840            if (components != null) {
14841                for (int i=0; i<components.size(); i++) {
14842                    if (components.get(i).equals(comp)) {
14843                        return true;
14844                    }
14845                }
14846            }
14847            if (objects != null) {
14848                for (int i=0; i<objects.size(); i++) {
14849                    if (System.identityHashCode(object) == objects.get(i)) {
14850                        return true;
14851                    }
14852                }
14853            }
14854            if (strings != null) {
14855                String flat = comp.flattenToString();
14856                for (int i=0; i<strings.size(); i++) {
14857                    if (flat.contains(strings.get(i))) {
14858                        return true;
14859                    }
14860                }
14861            }
14862            return false;
14863        }
14864    }
14865
14866    /**
14867     * There are three things that cmd can be:
14868     *  - a flattened component name that matches an existing activity
14869     *  - the cmd arg isn't the flattened component name of an existing activity:
14870     *    dump all activity whose component contains the cmd as a substring
14871     *  - A hex number of the ActivityRecord object instance.
14872     */
14873    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14874            int opti, boolean dumpAll) {
14875        ArrayList<ActivityRecord> activities;
14876
14877        synchronized (this) {
14878            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14879        }
14880
14881        if (activities.size() <= 0) {
14882            return false;
14883        }
14884
14885        String[] newArgs = new String[args.length - opti];
14886        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14887
14888        TaskRecord lastTask = null;
14889        boolean needSep = false;
14890        for (int i=activities.size()-1; i>=0; i--) {
14891            ActivityRecord r = activities.get(i);
14892            if (needSep) {
14893                pw.println();
14894            }
14895            needSep = true;
14896            synchronized (this) {
14897                if (lastTask != r.task) {
14898                    lastTask = r.task;
14899                    pw.print("TASK "); pw.print(lastTask.affinity);
14900                            pw.print(" id="); pw.println(lastTask.taskId);
14901                    if (dumpAll) {
14902                        lastTask.dump(pw, "  ");
14903                    }
14904                }
14905            }
14906            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14907        }
14908        return true;
14909    }
14910
14911    /**
14912     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14913     * there is a thread associated with the activity.
14914     */
14915    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14916            final ActivityRecord r, String[] args, boolean dumpAll) {
14917        String innerPrefix = prefix + "  ";
14918        synchronized (this) {
14919            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14920                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14921                    pw.print(" pid=");
14922                    if (r.app != null) pw.println(r.app.pid);
14923                    else pw.println("(not running)");
14924            if (dumpAll) {
14925                r.dump(pw, innerPrefix);
14926            }
14927        }
14928        if (r.app != null && r.app.thread != null) {
14929            // flush anything that is already in the PrintWriter since the thread is going
14930            // to write to the file descriptor directly
14931            pw.flush();
14932            try {
14933                TransferPipe tp = new TransferPipe();
14934                try {
14935                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14936                            r.appToken, innerPrefix, args);
14937                    tp.go(fd);
14938                } finally {
14939                    tp.kill();
14940                }
14941            } catch (IOException e) {
14942                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14943            } catch (RemoteException e) {
14944                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14945            }
14946        }
14947    }
14948
14949    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14950            int opti, boolean dumpAll, String dumpPackage) {
14951        boolean needSep = false;
14952        boolean onlyHistory = false;
14953        boolean printedAnything = false;
14954
14955        if ("history".equals(dumpPackage)) {
14956            if (opti < args.length && "-s".equals(args[opti])) {
14957                dumpAll = false;
14958            }
14959            onlyHistory = true;
14960            dumpPackage = null;
14961        }
14962
14963        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14964        if (!onlyHistory && dumpAll) {
14965            if (mRegisteredReceivers.size() > 0) {
14966                boolean printed = false;
14967                Iterator it = mRegisteredReceivers.values().iterator();
14968                while (it.hasNext()) {
14969                    ReceiverList r = (ReceiverList)it.next();
14970                    if (dumpPackage != null && (r.app == null ||
14971                            !dumpPackage.equals(r.app.info.packageName))) {
14972                        continue;
14973                    }
14974                    if (!printed) {
14975                        pw.println("  Registered Receivers:");
14976                        needSep = true;
14977                        printed = true;
14978                        printedAnything = true;
14979                    }
14980                    pw.print("  * "); pw.println(r);
14981                    r.dump(pw, "    ");
14982                }
14983            }
14984
14985            if (mReceiverResolver.dump(pw, needSep ?
14986                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14987                    "    ", dumpPackage, false, false)) {
14988                needSep = true;
14989                printedAnything = true;
14990            }
14991        }
14992
14993        for (BroadcastQueue q : mBroadcastQueues) {
14994            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14995            printedAnything |= needSep;
14996        }
14997
14998        needSep = true;
14999
15000        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15001            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15002                if (needSep) {
15003                    pw.println();
15004                }
15005                needSep = true;
15006                printedAnything = true;
15007                pw.print("  Sticky broadcasts for user ");
15008                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15009                StringBuilder sb = new StringBuilder(128);
15010                for (Map.Entry<String, ArrayList<Intent>> ent
15011                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15012                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15013                    if (dumpAll) {
15014                        pw.println(":");
15015                        ArrayList<Intent> intents = ent.getValue();
15016                        final int N = intents.size();
15017                        for (int i=0; i<N; i++) {
15018                            sb.setLength(0);
15019                            sb.append("    Intent: ");
15020                            intents.get(i).toShortString(sb, false, true, false, false);
15021                            pw.println(sb.toString());
15022                            Bundle bundle = intents.get(i).getExtras();
15023                            if (bundle != null) {
15024                                pw.print("      ");
15025                                pw.println(bundle.toString());
15026                            }
15027                        }
15028                    } else {
15029                        pw.println("");
15030                    }
15031                }
15032            }
15033        }
15034
15035        if (!onlyHistory && dumpAll) {
15036            pw.println();
15037            for (BroadcastQueue queue : mBroadcastQueues) {
15038                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15039                        + queue.mBroadcastsScheduled);
15040            }
15041            pw.println("  mHandler:");
15042            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15043            needSep = true;
15044            printedAnything = true;
15045        }
15046
15047        if (!printedAnything) {
15048            pw.println("  (nothing)");
15049        }
15050    }
15051
15052    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15053            int opti, boolean dumpAll, String dumpPackage) {
15054        if (mCurBroadcastStats == null) {
15055            return;
15056        }
15057
15058        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15059        final long now = SystemClock.elapsedRealtime();
15060        if (mLastBroadcastStats != null) {
15061            pw.print("  Last stats (from ");
15062            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15063            pw.print(" to ");
15064            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15065            pw.print(", ");
15066            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15067                    - mLastBroadcastStats.mStartUptime, pw);
15068            pw.println(" uptime):");
15069            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15070                pw.println("    (nothing)");
15071            }
15072            pw.println();
15073        }
15074        pw.print("  Current stats (from ");
15075        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15076        pw.print(" to now, ");
15077        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15078                - mCurBroadcastStats.mStartUptime, pw);
15079        pw.println(" uptime):");
15080        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15081            pw.println("    (nothing)");
15082        }
15083    }
15084
15085    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15086            int opti, boolean fullCheckin, String dumpPackage) {
15087        if (mCurBroadcastStats == null) {
15088            return;
15089        }
15090
15091        if (mLastBroadcastStats != null) {
15092            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15093            if (fullCheckin) {
15094                mLastBroadcastStats = null;
15095                return;
15096            }
15097        }
15098        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15099        if (fullCheckin) {
15100            mCurBroadcastStats = null;
15101        }
15102    }
15103
15104    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15105            int opti, boolean dumpAll, String dumpPackage) {
15106        boolean needSep;
15107        boolean printedAnything = false;
15108
15109        ItemMatcher matcher = new ItemMatcher();
15110        matcher.build(args, opti);
15111
15112        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15113
15114        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15115        printedAnything |= needSep;
15116
15117        if (mLaunchingProviders.size() > 0) {
15118            boolean printed = false;
15119            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15120                ContentProviderRecord r = mLaunchingProviders.get(i);
15121                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15122                    continue;
15123                }
15124                if (!printed) {
15125                    if (needSep) pw.println();
15126                    needSep = true;
15127                    pw.println("  Launching content providers:");
15128                    printed = true;
15129                    printedAnything = true;
15130                }
15131                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15132                        pw.println(r);
15133            }
15134        }
15135
15136        if (!printedAnything) {
15137            pw.println("  (nothing)");
15138        }
15139    }
15140
15141    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15142            int opti, boolean dumpAll, String dumpPackage) {
15143        boolean needSep = false;
15144        boolean printedAnything = false;
15145
15146        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15147
15148        if (mGrantedUriPermissions.size() > 0) {
15149            boolean printed = false;
15150            int dumpUid = -2;
15151            if (dumpPackage != null) {
15152                try {
15153                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15154                            MATCH_UNINSTALLED_PACKAGES, 0);
15155                } catch (NameNotFoundException e) {
15156                    dumpUid = -1;
15157                }
15158            }
15159            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15160                int uid = mGrantedUriPermissions.keyAt(i);
15161                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15162                    continue;
15163                }
15164                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15165                if (!printed) {
15166                    if (needSep) pw.println();
15167                    needSep = true;
15168                    pw.println("  Granted Uri Permissions:");
15169                    printed = true;
15170                    printedAnything = true;
15171                }
15172                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15173                for (UriPermission perm : perms.values()) {
15174                    pw.print("    "); pw.println(perm);
15175                    if (dumpAll) {
15176                        perm.dump(pw, "      ");
15177                    }
15178                }
15179            }
15180        }
15181
15182        if (!printedAnything) {
15183            pw.println("  (nothing)");
15184        }
15185    }
15186
15187    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15188            int opti, boolean dumpAll, String dumpPackage) {
15189        boolean printed = false;
15190
15191        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15192
15193        if (mIntentSenderRecords.size() > 0) {
15194            Iterator<WeakReference<PendingIntentRecord>> it
15195                    = mIntentSenderRecords.values().iterator();
15196            while (it.hasNext()) {
15197                WeakReference<PendingIntentRecord> ref = it.next();
15198                PendingIntentRecord rec = ref != null ? ref.get(): null;
15199                if (dumpPackage != null && (rec == null
15200                        || !dumpPackage.equals(rec.key.packageName))) {
15201                    continue;
15202                }
15203                printed = true;
15204                if (rec != null) {
15205                    pw.print("  * "); pw.println(rec);
15206                    if (dumpAll) {
15207                        rec.dump(pw, "    ");
15208                    }
15209                } else {
15210                    pw.print("  * "); pw.println(ref);
15211                }
15212            }
15213        }
15214
15215        if (!printed) {
15216            pw.println("  (nothing)");
15217        }
15218    }
15219
15220    private static final int dumpProcessList(PrintWriter pw,
15221            ActivityManagerService service, List list,
15222            String prefix, String normalLabel, String persistentLabel,
15223            String dumpPackage) {
15224        int numPers = 0;
15225        final int N = list.size()-1;
15226        for (int i=N; i>=0; i--) {
15227            ProcessRecord r = (ProcessRecord)list.get(i);
15228            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15229                continue;
15230            }
15231            pw.println(String.format("%s%s #%2d: %s",
15232                    prefix, (r.persistent ? persistentLabel : normalLabel),
15233                    i, r.toString()));
15234            if (r.persistent) {
15235                numPers++;
15236            }
15237        }
15238        return numPers;
15239    }
15240
15241    private static final boolean dumpProcessOomList(PrintWriter pw,
15242            ActivityManagerService service, List<ProcessRecord> origList,
15243            String prefix, String normalLabel, String persistentLabel,
15244            boolean inclDetails, String dumpPackage) {
15245
15246        ArrayList<Pair<ProcessRecord, Integer>> list
15247                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15248        for (int i=0; i<origList.size(); i++) {
15249            ProcessRecord r = origList.get(i);
15250            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15251                continue;
15252            }
15253            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15254        }
15255
15256        if (list.size() <= 0) {
15257            return false;
15258        }
15259
15260        Comparator<Pair<ProcessRecord, Integer>> comparator
15261                = new Comparator<Pair<ProcessRecord, Integer>>() {
15262            @Override
15263            public int compare(Pair<ProcessRecord, Integer> object1,
15264                    Pair<ProcessRecord, Integer> object2) {
15265                if (object1.first.setAdj != object2.first.setAdj) {
15266                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15267                }
15268                if (object1.first.setProcState != object2.first.setProcState) {
15269                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15270                }
15271                if (object1.second.intValue() != object2.second.intValue()) {
15272                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15273                }
15274                return 0;
15275            }
15276        };
15277
15278        Collections.sort(list, comparator);
15279
15280        final long curRealtime = SystemClock.elapsedRealtime();
15281        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15282        final long curUptime = SystemClock.uptimeMillis();
15283        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15284
15285        for (int i=list.size()-1; i>=0; i--) {
15286            ProcessRecord r = list.get(i).first;
15287            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15288            char schedGroup;
15289            switch (r.setSchedGroup) {
15290                case ProcessList.SCHED_GROUP_BACKGROUND:
15291                    schedGroup = 'B';
15292                    break;
15293                case ProcessList.SCHED_GROUP_DEFAULT:
15294                    schedGroup = 'F';
15295                    break;
15296                case ProcessList.SCHED_GROUP_TOP_APP:
15297                    schedGroup = 'T';
15298                    break;
15299                default:
15300                    schedGroup = '?';
15301                    break;
15302            }
15303            char foreground;
15304            if (r.foregroundActivities) {
15305                foreground = 'A';
15306            } else if (r.foregroundServices) {
15307                foreground = 'S';
15308            } else {
15309                foreground = ' ';
15310            }
15311            String procState = ProcessList.makeProcStateString(r.curProcState);
15312            pw.print(prefix);
15313            pw.print(r.persistent ? persistentLabel : normalLabel);
15314            pw.print(" #");
15315            int num = (origList.size()-1)-list.get(i).second;
15316            if (num < 10) pw.print(' ');
15317            pw.print(num);
15318            pw.print(": ");
15319            pw.print(oomAdj);
15320            pw.print(' ');
15321            pw.print(schedGroup);
15322            pw.print('/');
15323            pw.print(foreground);
15324            pw.print('/');
15325            pw.print(procState);
15326            pw.print(" trm:");
15327            if (r.trimMemoryLevel < 10) pw.print(' ');
15328            pw.print(r.trimMemoryLevel);
15329            pw.print(' ');
15330            pw.print(r.toShortString());
15331            pw.print(" (");
15332            pw.print(r.adjType);
15333            pw.println(')');
15334            if (r.adjSource != null || r.adjTarget != null) {
15335                pw.print(prefix);
15336                pw.print("    ");
15337                if (r.adjTarget instanceof ComponentName) {
15338                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15339                } else if (r.adjTarget != null) {
15340                    pw.print(r.adjTarget.toString());
15341                } else {
15342                    pw.print("{null}");
15343                }
15344                pw.print("<=");
15345                if (r.adjSource instanceof ProcessRecord) {
15346                    pw.print("Proc{");
15347                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15348                    pw.println("}");
15349                } else if (r.adjSource != null) {
15350                    pw.println(r.adjSource.toString());
15351                } else {
15352                    pw.println("{null}");
15353                }
15354            }
15355            if (inclDetails) {
15356                pw.print(prefix);
15357                pw.print("    ");
15358                pw.print("oom: max="); pw.print(r.maxAdj);
15359                pw.print(" curRaw="); pw.print(r.curRawAdj);
15360                pw.print(" setRaw="); pw.print(r.setRawAdj);
15361                pw.print(" cur="); pw.print(r.curAdj);
15362                pw.print(" set="); pw.println(r.setAdj);
15363                pw.print(prefix);
15364                pw.print("    ");
15365                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15366                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15367                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15368                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15369                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15370                pw.println();
15371                pw.print(prefix);
15372                pw.print("    ");
15373                pw.print("cached="); pw.print(r.cached);
15374                pw.print(" empty="); pw.print(r.empty);
15375                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15376
15377                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15378                    if (r.lastWakeTime != 0) {
15379                        long wtime;
15380                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15381                        synchronized (stats) {
15382                            wtime = stats.getProcessWakeTime(r.info.uid,
15383                                    r.pid, curRealtime);
15384                        }
15385                        long timeUsed = wtime - r.lastWakeTime;
15386                        pw.print(prefix);
15387                        pw.print("    ");
15388                        pw.print("keep awake over ");
15389                        TimeUtils.formatDuration(realtimeSince, pw);
15390                        pw.print(" used ");
15391                        TimeUtils.formatDuration(timeUsed, pw);
15392                        pw.print(" (");
15393                        pw.print((timeUsed*100)/realtimeSince);
15394                        pw.println("%)");
15395                    }
15396                    if (r.lastCpuTime != 0) {
15397                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15398                        pw.print(prefix);
15399                        pw.print("    ");
15400                        pw.print("run cpu over ");
15401                        TimeUtils.formatDuration(uptimeSince, pw);
15402                        pw.print(" used ");
15403                        TimeUtils.formatDuration(timeUsed, pw);
15404                        pw.print(" (");
15405                        pw.print((timeUsed*100)/uptimeSince);
15406                        pw.println("%)");
15407                    }
15408                }
15409            }
15410        }
15411        return true;
15412    }
15413
15414    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15415            String[] args) {
15416        ArrayList<ProcessRecord> procs;
15417        synchronized (this) {
15418            if (args != null && args.length > start
15419                    && args[start].charAt(0) != '-') {
15420                procs = new ArrayList<ProcessRecord>();
15421                int pid = -1;
15422                try {
15423                    pid = Integer.parseInt(args[start]);
15424                } catch (NumberFormatException e) {
15425                }
15426                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15427                    ProcessRecord proc = mLruProcesses.get(i);
15428                    if (proc.pid == pid) {
15429                        procs.add(proc);
15430                    } else if (allPkgs && proc.pkgList != null
15431                            && proc.pkgList.containsKey(args[start])) {
15432                        procs.add(proc);
15433                    } else if (proc.processName.equals(args[start])) {
15434                        procs.add(proc);
15435                    }
15436                }
15437                if (procs.size() <= 0) {
15438                    return null;
15439                }
15440            } else {
15441                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15442            }
15443        }
15444        return procs;
15445    }
15446
15447    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15448            PrintWriter pw, String[] args) {
15449        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15450        if (procs == null) {
15451            pw.println("No process found for: " + args[0]);
15452            return;
15453        }
15454
15455        long uptime = SystemClock.uptimeMillis();
15456        long realtime = SystemClock.elapsedRealtime();
15457        pw.println("Applications Graphics Acceleration Info:");
15458        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15459
15460        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15461            ProcessRecord r = procs.get(i);
15462            if (r.thread != null) {
15463                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15464                pw.flush();
15465                try {
15466                    TransferPipe tp = new TransferPipe();
15467                    try {
15468                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15469                        tp.go(fd);
15470                    } finally {
15471                        tp.kill();
15472                    }
15473                } catch (IOException e) {
15474                    pw.println("Failure while dumping the app: " + r);
15475                    pw.flush();
15476                } catch (RemoteException e) {
15477                    pw.println("Got a RemoteException while dumping the app " + r);
15478                    pw.flush();
15479                }
15480            }
15481        }
15482    }
15483
15484    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15485        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15486        if (procs == null) {
15487            pw.println("No process found for: " + args[0]);
15488            return;
15489        }
15490
15491        pw.println("Applications Database Info:");
15492
15493        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15494            ProcessRecord r = procs.get(i);
15495            if (r.thread != null) {
15496                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15497                pw.flush();
15498                try {
15499                    TransferPipe tp = new TransferPipe();
15500                    try {
15501                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15502                        tp.go(fd);
15503                    } finally {
15504                        tp.kill();
15505                    }
15506                } catch (IOException e) {
15507                    pw.println("Failure while dumping the app: " + r);
15508                    pw.flush();
15509                } catch (RemoteException e) {
15510                    pw.println("Got a RemoteException while dumping the app " + r);
15511                    pw.flush();
15512                }
15513            }
15514        }
15515    }
15516
15517    final static class MemItem {
15518        final boolean isProc;
15519        final String label;
15520        final String shortLabel;
15521        final long pss;
15522        final long swapPss;
15523        final int id;
15524        final boolean hasActivities;
15525        ArrayList<MemItem> subitems;
15526
15527        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15528                boolean _hasActivities) {
15529            isProc = true;
15530            label = _label;
15531            shortLabel = _shortLabel;
15532            pss = _pss;
15533            swapPss = _swapPss;
15534            id = _id;
15535            hasActivities = _hasActivities;
15536        }
15537
15538        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15539            isProc = false;
15540            label = _label;
15541            shortLabel = _shortLabel;
15542            pss = _pss;
15543            swapPss = _swapPss;
15544            id = _id;
15545            hasActivities = false;
15546        }
15547    }
15548
15549    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15550            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15551        if (sort && !isCompact) {
15552            Collections.sort(items, new Comparator<MemItem>() {
15553                @Override
15554                public int compare(MemItem lhs, MemItem rhs) {
15555                    if (lhs.pss < rhs.pss) {
15556                        return 1;
15557                    } else if (lhs.pss > rhs.pss) {
15558                        return -1;
15559                    }
15560                    return 0;
15561                }
15562            });
15563        }
15564
15565        for (int i=0; i<items.size(); i++) {
15566            MemItem mi = items.get(i);
15567            if (!isCompact) {
15568                if (dumpSwapPss) {
15569                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15570                            mi.label, stringifyKBSize(mi.swapPss));
15571                } else {
15572                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15573                }
15574            } else if (mi.isProc) {
15575                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15576                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15577                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15578                pw.println(mi.hasActivities ? ",a" : ",e");
15579            } else {
15580                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15581                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15582            }
15583            if (mi.subitems != null) {
15584                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15585                        true, isCompact, dumpSwapPss);
15586            }
15587        }
15588    }
15589
15590    // These are in KB.
15591    static final long[] DUMP_MEM_BUCKETS = new long[] {
15592        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15593        120*1024, 160*1024, 200*1024,
15594        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15595        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15596    };
15597
15598    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15599            boolean stackLike) {
15600        int start = label.lastIndexOf('.');
15601        if (start >= 0) start++;
15602        else start = 0;
15603        int end = label.length();
15604        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15605            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15606                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15607                out.append(bucket);
15608                out.append(stackLike ? "MB." : "MB ");
15609                out.append(label, start, end);
15610                return;
15611            }
15612        }
15613        out.append(memKB/1024);
15614        out.append(stackLike ? "MB." : "MB ");
15615        out.append(label, start, end);
15616    }
15617
15618    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15619            ProcessList.NATIVE_ADJ,
15620            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15621            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15622            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15623            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15624            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15625            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15626    };
15627    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15628            "Native",
15629            "System", "Persistent", "Persistent Service", "Foreground",
15630            "Visible", "Perceptible",
15631            "Heavy Weight", "Backup",
15632            "A Services", "Home",
15633            "Previous", "B Services", "Cached"
15634    };
15635    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15636            "native",
15637            "sys", "pers", "persvc", "fore",
15638            "vis", "percept",
15639            "heavy", "backup",
15640            "servicea", "home",
15641            "prev", "serviceb", "cached"
15642    };
15643
15644    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15645            long realtime, boolean isCheckinRequest, boolean isCompact) {
15646        if (isCompact) {
15647            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15648        }
15649        if (isCheckinRequest || isCompact) {
15650            // short checkin version
15651            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15652        } else {
15653            pw.println("Applications Memory Usage (in Kilobytes):");
15654            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15655        }
15656    }
15657
15658    private static final int KSM_SHARED = 0;
15659    private static final int KSM_SHARING = 1;
15660    private static final int KSM_UNSHARED = 2;
15661    private static final int KSM_VOLATILE = 3;
15662
15663    private final long[] getKsmInfo() {
15664        long[] longOut = new long[4];
15665        final int[] SINGLE_LONG_FORMAT = new int[] {
15666            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15667        };
15668        long[] longTmp = new long[1];
15669        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15670                SINGLE_LONG_FORMAT, null, longTmp, null);
15671        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15672        longTmp[0] = 0;
15673        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15674                SINGLE_LONG_FORMAT, null, longTmp, null);
15675        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15676        longTmp[0] = 0;
15677        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15678                SINGLE_LONG_FORMAT, null, longTmp, null);
15679        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15680        longTmp[0] = 0;
15681        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15682                SINGLE_LONG_FORMAT, null, longTmp, null);
15683        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15684        return longOut;
15685    }
15686
15687    private static String stringifySize(long size, int order) {
15688        Locale locale = Locale.US;
15689        switch (order) {
15690            case 1:
15691                return String.format(locale, "%,13d", size);
15692            case 1024:
15693                return String.format(locale, "%,9dK", size / 1024);
15694            case 1024 * 1024:
15695                return String.format(locale, "%,5dM", size / 1024 / 1024);
15696            case 1024 * 1024 * 1024:
15697                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15698            default:
15699                throw new IllegalArgumentException("Invalid size order");
15700        }
15701    }
15702
15703    private static String stringifyKBSize(long size) {
15704        return stringifySize(size * 1024, 1024);
15705    }
15706
15707    // Update this version number in case you change the 'compact' format
15708    private static final int MEMINFO_COMPACT_VERSION = 1;
15709
15710    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15711            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15712        boolean dumpDetails = false;
15713        boolean dumpFullDetails = false;
15714        boolean dumpDalvik = false;
15715        boolean dumpSummaryOnly = false;
15716        boolean dumpUnreachable = false;
15717        boolean oomOnly = false;
15718        boolean isCompact = false;
15719        boolean localOnly = false;
15720        boolean packages = false;
15721        boolean isCheckinRequest = false;
15722        boolean dumpSwapPss = false;
15723
15724        int opti = 0;
15725        while (opti < args.length) {
15726            String opt = args[opti];
15727            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15728                break;
15729            }
15730            opti++;
15731            if ("-a".equals(opt)) {
15732                dumpDetails = true;
15733                dumpFullDetails = true;
15734                dumpDalvik = true;
15735                dumpSwapPss = true;
15736            } else if ("-d".equals(opt)) {
15737                dumpDalvik = true;
15738            } else if ("-c".equals(opt)) {
15739                isCompact = true;
15740            } else if ("-s".equals(opt)) {
15741                dumpDetails = true;
15742                dumpSummaryOnly = true;
15743            } else if ("-S".equals(opt)) {
15744                dumpSwapPss = true;
15745            } else if ("--unreachable".equals(opt)) {
15746                dumpUnreachable = true;
15747            } else if ("--oom".equals(opt)) {
15748                oomOnly = true;
15749            } else if ("--local".equals(opt)) {
15750                localOnly = true;
15751            } else if ("--package".equals(opt)) {
15752                packages = true;
15753            } else if ("--checkin".equals(opt)) {
15754                isCheckinRequest = true;
15755
15756            } else if ("-h".equals(opt)) {
15757                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15758                pw.println("  -a: include all available information for each process.");
15759                pw.println("  -d: include dalvik details.");
15760                pw.println("  -c: dump in a compact machine-parseable representation.");
15761                pw.println("  -s: dump only summary of application memory usage.");
15762                pw.println("  -S: dump also SwapPss.");
15763                pw.println("  --oom: only show processes organized by oom adj.");
15764                pw.println("  --local: only collect details locally, don't call process.");
15765                pw.println("  --package: interpret process arg as package, dumping all");
15766                pw.println("             processes that have loaded that package.");
15767                pw.println("  --checkin: dump data for a checkin");
15768                pw.println("If [process] is specified it can be the name or ");
15769                pw.println("pid of a specific process to dump.");
15770                return;
15771            } else {
15772                pw.println("Unknown argument: " + opt + "; use -h for help");
15773            }
15774        }
15775
15776        long uptime = SystemClock.uptimeMillis();
15777        long realtime = SystemClock.elapsedRealtime();
15778        final long[] tmpLong = new long[1];
15779
15780        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15781        if (procs == null) {
15782            // No Java processes.  Maybe they want to print a native process.
15783            if (args != null && args.length > opti
15784                    && args[opti].charAt(0) != '-') {
15785                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15786                        = new ArrayList<ProcessCpuTracker.Stats>();
15787                updateCpuStatsNow();
15788                int findPid = -1;
15789                try {
15790                    findPid = Integer.parseInt(args[opti]);
15791                } catch (NumberFormatException e) {
15792                }
15793                synchronized (mProcessCpuTracker) {
15794                    final int N = mProcessCpuTracker.countStats();
15795                    for (int i=0; i<N; i++) {
15796                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15797                        if (st.pid == findPid || (st.baseName != null
15798                                && st.baseName.equals(args[opti]))) {
15799                            nativeProcs.add(st);
15800                        }
15801                    }
15802                }
15803                if (nativeProcs.size() > 0) {
15804                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15805                            isCompact);
15806                    Debug.MemoryInfo mi = null;
15807                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15808                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15809                        final int pid = r.pid;
15810                        if (!isCheckinRequest && dumpDetails) {
15811                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15812                        }
15813                        if (mi == null) {
15814                            mi = new Debug.MemoryInfo();
15815                        }
15816                        if (dumpDetails || (!brief && !oomOnly)) {
15817                            Debug.getMemoryInfo(pid, mi);
15818                        } else {
15819                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15820                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15821                        }
15822                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15823                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15824                        if (isCheckinRequest) {
15825                            pw.println();
15826                        }
15827                    }
15828                    return;
15829                }
15830            }
15831            pw.println("No process found for: " + args[opti]);
15832            return;
15833        }
15834
15835        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15836            dumpDetails = true;
15837        }
15838
15839        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15840
15841        String[] innerArgs = new String[args.length-opti];
15842        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15843
15844        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15845        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15846        long nativePss = 0;
15847        long nativeSwapPss = 0;
15848        long dalvikPss = 0;
15849        long dalvikSwapPss = 0;
15850        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15851                EmptyArray.LONG;
15852        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15853                EmptyArray.LONG;
15854        long otherPss = 0;
15855        long otherSwapPss = 0;
15856        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15857        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15858
15859        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15860        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15861        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15862                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15863
15864        long totalPss = 0;
15865        long totalSwapPss = 0;
15866        long cachedPss = 0;
15867        long cachedSwapPss = 0;
15868        boolean hasSwapPss = false;
15869
15870        Debug.MemoryInfo mi = null;
15871        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15872            final ProcessRecord r = procs.get(i);
15873            final IApplicationThread thread;
15874            final int pid;
15875            final int oomAdj;
15876            final boolean hasActivities;
15877            synchronized (this) {
15878                thread = r.thread;
15879                pid = r.pid;
15880                oomAdj = r.getSetAdjWithServices();
15881                hasActivities = r.activities.size() > 0;
15882            }
15883            if (thread != null) {
15884                if (!isCheckinRequest && dumpDetails) {
15885                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15886                }
15887                if (mi == null) {
15888                    mi = new Debug.MemoryInfo();
15889                }
15890                if (dumpDetails || (!brief && !oomOnly)) {
15891                    Debug.getMemoryInfo(pid, mi);
15892                    hasSwapPss = mi.hasSwappedOutPss;
15893                } else {
15894                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15895                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15896                }
15897                if (dumpDetails) {
15898                    if (localOnly) {
15899                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15900                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15901                        if (isCheckinRequest) {
15902                            pw.println();
15903                        }
15904                    } else {
15905                        try {
15906                            pw.flush();
15907                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15908                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15909                        } catch (RemoteException e) {
15910                            if (!isCheckinRequest) {
15911                                pw.println("Got RemoteException!");
15912                                pw.flush();
15913                            }
15914                        }
15915                    }
15916                }
15917
15918                final long myTotalPss = mi.getTotalPss();
15919                final long myTotalUss = mi.getTotalUss();
15920                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15921
15922                synchronized (this) {
15923                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15924                        // Record this for posterity if the process has been stable.
15925                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15926                    }
15927                }
15928
15929                if (!isCheckinRequest && mi != null) {
15930                    totalPss += myTotalPss;
15931                    totalSwapPss += myTotalSwapPss;
15932                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15933                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15934                            myTotalSwapPss, pid, hasActivities);
15935                    procMems.add(pssItem);
15936                    procMemsMap.put(pid, pssItem);
15937
15938                    nativePss += mi.nativePss;
15939                    nativeSwapPss += mi.nativeSwappedOutPss;
15940                    dalvikPss += mi.dalvikPss;
15941                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15942                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15943                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15944                        dalvikSubitemSwapPss[j] +=
15945                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15946                    }
15947                    otherPss += mi.otherPss;
15948                    otherSwapPss += mi.otherSwappedOutPss;
15949                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15950                        long mem = mi.getOtherPss(j);
15951                        miscPss[j] += mem;
15952                        otherPss -= mem;
15953                        mem = mi.getOtherSwappedOutPss(j);
15954                        miscSwapPss[j] += mem;
15955                        otherSwapPss -= mem;
15956                    }
15957
15958                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15959                        cachedPss += myTotalPss;
15960                        cachedSwapPss += myTotalSwapPss;
15961                    }
15962
15963                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15964                        if (oomIndex == (oomPss.length - 1)
15965                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15966                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15967                            oomPss[oomIndex] += myTotalPss;
15968                            oomSwapPss[oomIndex] += myTotalSwapPss;
15969                            if (oomProcs[oomIndex] == null) {
15970                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15971                            }
15972                            oomProcs[oomIndex].add(pssItem);
15973                            break;
15974                        }
15975                    }
15976                }
15977            }
15978        }
15979
15980        long nativeProcTotalPss = 0;
15981
15982        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15983            // If we are showing aggregations, also look for native processes to
15984            // include so that our aggregations are more accurate.
15985            updateCpuStatsNow();
15986            mi = null;
15987            synchronized (mProcessCpuTracker) {
15988                final int N = mProcessCpuTracker.countStats();
15989                for (int i=0; i<N; i++) {
15990                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15991                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15992                        if (mi == null) {
15993                            mi = new Debug.MemoryInfo();
15994                        }
15995                        if (!brief && !oomOnly) {
15996                            Debug.getMemoryInfo(st.pid, mi);
15997                        } else {
15998                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15999                            mi.nativePrivateDirty = (int)tmpLong[0];
16000                        }
16001
16002                        final long myTotalPss = mi.getTotalPss();
16003                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16004                        totalPss += myTotalPss;
16005                        nativeProcTotalPss += myTotalPss;
16006
16007                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16008                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16009                        procMems.add(pssItem);
16010
16011                        nativePss += mi.nativePss;
16012                        nativeSwapPss += mi.nativeSwappedOutPss;
16013                        dalvikPss += mi.dalvikPss;
16014                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16015                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16016                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16017                            dalvikSubitemSwapPss[j] +=
16018                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16019                        }
16020                        otherPss += mi.otherPss;
16021                        otherSwapPss += mi.otherSwappedOutPss;
16022                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16023                            long mem = mi.getOtherPss(j);
16024                            miscPss[j] += mem;
16025                            otherPss -= mem;
16026                            mem = mi.getOtherSwappedOutPss(j);
16027                            miscSwapPss[j] += mem;
16028                            otherSwapPss -= mem;
16029                        }
16030                        oomPss[0] += myTotalPss;
16031                        oomSwapPss[0] += myTotalSwapPss;
16032                        if (oomProcs[0] == null) {
16033                            oomProcs[0] = new ArrayList<MemItem>();
16034                        }
16035                        oomProcs[0].add(pssItem);
16036                    }
16037                }
16038            }
16039
16040            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16041
16042            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16043            final MemItem dalvikItem =
16044                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16045            if (dalvikSubitemPss.length > 0) {
16046                dalvikItem.subitems = new ArrayList<MemItem>();
16047                for (int j=0; j<dalvikSubitemPss.length; j++) {
16048                    final String name = Debug.MemoryInfo.getOtherLabel(
16049                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16050                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16051                                    dalvikSubitemSwapPss[j], j));
16052                }
16053            }
16054            catMems.add(dalvikItem);
16055            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16056            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16057                String label = Debug.MemoryInfo.getOtherLabel(j);
16058                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16059            }
16060
16061            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16062            for (int j=0; j<oomPss.length; j++) {
16063                if (oomPss[j] != 0) {
16064                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16065                            : DUMP_MEM_OOM_LABEL[j];
16066                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16067                            DUMP_MEM_OOM_ADJ[j]);
16068                    item.subitems = oomProcs[j];
16069                    oomMems.add(item);
16070                }
16071            }
16072
16073            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16074            if (!brief && !oomOnly && !isCompact) {
16075                pw.println();
16076                pw.println("Total PSS by process:");
16077                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16078                pw.println();
16079            }
16080            if (!isCompact) {
16081                pw.println("Total PSS by OOM adjustment:");
16082            }
16083            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16084            if (!brief && !oomOnly) {
16085                PrintWriter out = categoryPw != null ? categoryPw : pw;
16086                if (!isCompact) {
16087                    out.println();
16088                    out.println("Total PSS by category:");
16089                }
16090                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16091            }
16092            if (!isCompact) {
16093                pw.println();
16094            }
16095            MemInfoReader memInfo = new MemInfoReader();
16096            memInfo.readMemInfo();
16097            if (nativeProcTotalPss > 0) {
16098                synchronized (this) {
16099                    final long cachedKb = memInfo.getCachedSizeKb();
16100                    final long freeKb = memInfo.getFreeSizeKb();
16101                    final long zramKb = memInfo.getZramTotalSizeKb();
16102                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16103                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16104                            kernelKb*1024, nativeProcTotalPss*1024);
16105                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16106                            nativeProcTotalPss);
16107                }
16108            }
16109            if (!brief) {
16110                if (!isCompact) {
16111                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16112                    pw.print(" (status ");
16113                    switch (mLastMemoryLevel) {
16114                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16115                            pw.println("normal)");
16116                            break;
16117                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16118                            pw.println("moderate)");
16119                            break;
16120                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16121                            pw.println("low)");
16122                            break;
16123                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16124                            pw.println("critical)");
16125                            break;
16126                        default:
16127                            pw.print(mLastMemoryLevel);
16128                            pw.println(")");
16129                            break;
16130                    }
16131                    pw.print(" Free RAM: ");
16132                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16133                            + memInfo.getFreeSizeKb()));
16134                    pw.print(" (");
16135                    pw.print(stringifyKBSize(cachedPss));
16136                    pw.print(" cached pss + ");
16137                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16138                    pw.print(" cached kernel + ");
16139                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16140                    pw.println(" free)");
16141                } else {
16142                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16143                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16144                            + memInfo.getFreeSizeKb()); pw.print(",");
16145                    pw.println(totalPss - cachedPss);
16146                }
16147            }
16148            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16149                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16150                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16151            if (!isCompact) {
16152                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16153                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16154                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16155                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16156                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16157            } else {
16158                pw.print("lostram,"); pw.println(lostRAM);
16159            }
16160            if (!brief) {
16161                if (memInfo.getZramTotalSizeKb() != 0) {
16162                    if (!isCompact) {
16163                        pw.print("     ZRAM: ");
16164                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16165                                pw.print(" physical used for ");
16166                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16167                                        - memInfo.getSwapFreeSizeKb()));
16168                                pw.print(" in swap (");
16169                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16170                                pw.println(" total swap)");
16171                    } else {
16172                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16173                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16174                                pw.println(memInfo.getSwapFreeSizeKb());
16175                    }
16176                }
16177                final long[] ksm = getKsmInfo();
16178                if (!isCompact) {
16179                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16180                            || ksm[KSM_VOLATILE] != 0) {
16181                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16182                                pw.print(" saved from shared ");
16183                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16184                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16185                                pw.print(" unshared; ");
16186                                pw.print(stringifyKBSize(
16187                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16188                    }
16189                    pw.print("   Tuning: ");
16190                    pw.print(ActivityManager.staticGetMemoryClass());
16191                    pw.print(" (large ");
16192                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16193                    pw.print("), oom ");
16194                    pw.print(stringifySize(
16195                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16196                    pw.print(", restore limit ");
16197                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16198                    if (ActivityManager.isLowRamDeviceStatic()) {
16199                        pw.print(" (low-ram)");
16200                    }
16201                    if (ActivityManager.isHighEndGfx()) {
16202                        pw.print(" (high-end-gfx)");
16203                    }
16204                    pw.println();
16205                } else {
16206                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16207                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16208                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16209                    pw.print("tuning,");
16210                    pw.print(ActivityManager.staticGetMemoryClass());
16211                    pw.print(',');
16212                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16213                    pw.print(',');
16214                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16215                    if (ActivityManager.isLowRamDeviceStatic()) {
16216                        pw.print(",low-ram");
16217                    }
16218                    if (ActivityManager.isHighEndGfx()) {
16219                        pw.print(",high-end-gfx");
16220                    }
16221                    pw.println();
16222                }
16223            }
16224        }
16225    }
16226
16227    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16228            long memtrack, String name) {
16229        sb.append("  ");
16230        sb.append(ProcessList.makeOomAdjString(oomAdj));
16231        sb.append(' ');
16232        sb.append(ProcessList.makeProcStateString(procState));
16233        sb.append(' ');
16234        ProcessList.appendRamKb(sb, pss);
16235        sb.append(": ");
16236        sb.append(name);
16237        if (memtrack > 0) {
16238            sb.append(" (");
16239            sb.append(stringifyKBSize(memtrack));
16240            sb.append(" memtrack)");
16241        }
16242    }
16243
16244    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16245        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16246        sb.append(" (pid ");
16247        sb.append(mi.pid);
16248        sb.append(") ");
16249        sb.append(mi.adjType);
16250        sb.append('\n');
16251        if (mi.adjReason != null) {
16252            sb.append("                      ");
16253            sb.append(mi.adjReason);
16254            sb.append('\n');
16255        }
16256    }
16257
16258    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16259        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16260        for (int i=0, N=memInfos.size(); i<N; i++) {
16261            ProcessMemInfo mi = memInfos.get(i);
16262            infoMap.put(mi.pid, mi);
16263        }
16264        updateCpuStatsNow();
16265        long[] memtrackTmp = new long[1];
16266        synchronized (mProcessCpuTracker) {
16267            final int N = mProcessCpuTracker.countStats();
16268            for (int i=0; i<N; i++) {
16269                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16270                if (st.vsize > 0) {
16271                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16272                    if (pss > 0) {
16273                        if (infoMap.indexOfKey(st.pid) < 0) {
16274                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16275                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16276                            mi.pss = pss;
16277                            mi.memtrack = memtrackTmp[0];
16278                            memInfos.add(mi);
16279                        }
16280                    }
16281                }
16282            }
16283        }
16284
16285        long totalPss = 0;
16286        long totalMemtrack = 0;
16287        for (int i=0, N=memInfos.size(); i<N; i++) {
16288            ProcessMemInfo mi = memInfos.get(i);
16289            if (mi.pss == 0) {
16290                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16291                mi.memtrack = memtrackTmp[0];
16292            }
16293            totalPss += mi.pss;
16294            totalMemtrack += mi.memtrack;
16295        }
16296        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16297            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16298                if (lhs.oomAdj != rhs.oomAdj) {
16299                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16300                }
16301                if (lhs.pss != rhs.pss) {
16302                    return lhs.pss < rhs.pss ? 1 : -1;
16303                }
16304                return 0;
16305            }
16306        });
16307
16308        StringBuilder tag = new StringBuilder(128);
16309        StringBuilder stack = new StringBuilder(128);
16310        tag.append("Low on memory -- ");
16311        appendMemBucket(tag, totalPss, "total", false);
16312        appendMemBucket(stack, totalPss, "total", true);
16313
16314        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16315        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16316        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16317
16318        boolean firstLine = true;
16319        int lastOomAdj = Integer.MIN_VALUE;
16320        long extraNativeRam = 0;
16321        long extraNativeMemtrack = 0;
16322        long cachedPss = 0;
16323        for (int i=0, N=memInfos.size(); i<N; i++) {
16324            ProcessMemInfo mi = memInfos.get(i);
16325
16326            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16327                cachedPss += mi.pss;
16328            }
16329
16330            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16331                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16332                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16333                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16334                if (lastOomAdj != mi.oomAdj) {
16335                    lastOomAdj = mi.oomAdj;
16336                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16337                        tag.append(" / ");
16338                    }
16339                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16340                        if (firstLine) {
16341                            stack.append(":");
16342                            firstLine = false;
16343                        }
16344                        stack.append("\n\t at ");
16345                    } else {
16346                        stack.append("$");
16347                    }
16348                } else {
16349                    tag.append(" ");
16350                    stack.append("$");
16351                }
16352                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16353                    appendMemBucket(tag, mi.pss, mi.name, false);
16354                }
16355                appendMemBucket(stack, mi.pss, mi.name, true);
16356                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16357                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16358                    stack.append("(");
16359                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16360                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16361                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16362                            stack.append(":");
16363                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16364                        }
16365                    }
16366                    stack.append(")");
16367                }
16368            }
16369
16370            appendMemInfo(fullNativeBuilder, mi);
16371            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16372                // The short form only has native processes that are >= 512K.
16373                if (mi.pss >= 512) {
16374                    appendMemInfo(shortNativeBuilder, mi);
16375                } else {
16376                    extraNativeRam += mi.pss;
16377                    extraNativeMemtrack += mi.memtrack;
16378                }
16379            } else {
16380                // Short form has all other details, but if we have collected RAM
16381                // from smaller native processes let's dump a summary of that.
16382                if (extraNativeRam > 0) {
16383                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16384                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16385                    shortNativeBuilder.append('\n');
16386                    extraNativeRam = 0;
16387                }
16388                appendMemInfo(fullJavaBuilder, mi);
16389            }
16390        }
16391
16392        fullJavaBuilder.append("           ");
16393        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16394        fullJavaBuilder.append(": TOTAL");
16395        if (totalMemtrack > 0) {
16396            fullJavaBuilder.append(" (");
16397            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16398            fullJavaBuilder.append(" memtrack)");
16399        } else {
16400        }
16401        fullJavaBuilder.append("\n");
16402
16403        MemInfoReader memInfo = new MemInfoReader();
16404        memInfo.readMemInfo();
16405        final long[] infos = memInfo.getRawInfo();
16406
16407        StringBuilder memInfoBuilder = new StringBuilder(1024);
16408        Debug.getMemInfo(infos);
16409        memInfoBuilder.append("  MemInfo: ");
16410        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16411        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16412        memInfoBuilder.append(stringifyKBSize(
16413                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16414        memInfoBuilder.append(stringifyKBSize(
16415                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16416        memInfoBuilder.append(stringifyKBSize(
16417                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16418        memInfoBuilder.append("           ");
16419        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16420        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16421        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16422        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16423        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16424            memInfoBuilder.append("  ZRAM: ");
16425            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16426            memInfoBuilder.append(" RAM, ");
16427            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16428            memInfoBuilder.append(" swap total, ");
16429            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16430            memInfoBuilder.append(" swap free\n");
16431        }
16432        final long[] ksm = getKsmInfo();
16433        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16434                || ksm[KSM_VOLATILE] != 0) {
16435            memInfoBuilder.append("  KSM: ");
16436            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16437            memInfoBuilder.append(" saved from shared ");
16438            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16439            memInfoBuilder.append("\n       ");
16440            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16441            memInfoBuilder.append(" unshared; ");
16442            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16443            memInfoBuilder.append(" volatile\n");
16444        }
16445        memInfoBuilder.append("  Free RAM: ");
16446        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16447                + memInfo.getFreeSizeKb()));
16448        memInfoBuilder.append("\n");
16449        memInfoBuilder.append("  Used RAM: ");
16450        memInfoBuilder.append(stringifyKBSize(
16451                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16452        memInfoBuilder.append("\n");
16453        memInfoBuilder.append("  Lost RAM: ");
16454        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16455                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16456                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16457        memInfoBuilder.append("\n");
16458        Slog.i(TAG, "Low on memory:");
16459        Slog.i(TAG, shortNativeBuilder.toString());
16460        Slog.i(TAG, fullJavaBuilder.toString());
16461        Slog.i(TAG, memInfoBuilder.toString());
16462
16463        StringBuilder dropBuilder = new StringBuilder(1024);
16464        /*
16465        StringWriter oomSw = new StringWriter();
16466        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16467        StringWriter catSw = new StringWriter();
16468        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16469        String[] emptyArgs = new String[] { };
16470        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16471        oomPw.flush();
16472        String oomString = oomSw.toString();
16473        */
16474        dropBuilder.append("Low on memory:");
16475        dropBuilder.append(stack);
16476        dropBuilder.append('\n');
16477        dropBuilder.append(fullNativeBuilder);
16478        dropBuilder.append(fullJavaBuilder);
16479        dropBuilder.append('\n');
16480        dropBuilder.append(memInfoBuilder);
16481        dropBuilder.append('\n');
16482        /*
16483        dropBuilder.append(oomString);
16484        dropBuilder.append('\n');
16485        */
16486        StringWriter catSw = new StringWriter();
16487        synchronized (ActivityManagerService.this) {
16488            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16489            String[] emptyArgs = new String[] { };
16490            catPw.println();
16491            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16492            catPw.println();
16493            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16494                    false, null).dumpLocked();
16495            catPw.println();
16496            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16497            catPw.flush();
16498        }
16499        dropBuilder.append(catSw.toString());
16500        addErrorToDropBox("lowmem", null, "system_server", null,
16501                null, tag.toString(), dropBuilder.toString(), null, null);
16502        //Slog.i(TAG, "Sent to dropbox:");
16503        //Slog.i(TAG, dropBuilder.toString());
16504        synchronized (ActivityManagerService.this) {
16505            long now = SystemClock.uptimeMillis();
16506            if (mLastMemUsageReportTime < now) {
16507                mLastMemUsageReportTime = now;
16508            }
16509        }
16510    }
16511
16512    /**
16513     * Searches array of arguments for the specified string
16514     * @param args array of argument strings
16515     * @param value value to search for
16516     * @return true if the value is contained in the array
16517     */
16518    private static boolean scanArgs(String[] args, String value) {
16519        if (args != null) {
16520            for (String arg : args) {
16521                if (value.equals(arg)) {
16522                    return true;
16523                }
16524            }
16525        }
16526        return false;
16527    }
16528
16529    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16530            ContentProviderRecord cpr, boolean always) {
16531        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16532
16533        if (!inLaunching || always) {
16534            synchronized (cpr) {
16535                cpr.launchingApp = null;
16536                cpr.notifyAll();
16537            }
16538            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16539            String names[] = cpr.info.authority.split(";");
16540            for (int j = 0; j < names.length; j++) {
16541                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16542            }
16543        }
16544
16545        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16546            ContentProviderConnection conn = cpr.connections.get(i);
16547            if (conn.waiting) {
16548                // If this connection is waiting for the provider, then we don't
16549                // need to mess with its process unless we are always removing
16550                // or for some reason the provider is not currently launching.
16551                if (inLaunching && !always) {
16552                    continue;
16553                }
16554            }
16555            ProcessRecord capp = conn.client;
16556            conn.dead = true;
16557            if (conn.stableCount > 0) {
16558                if (!capp.persistent && capp.thread != null
16559                        && capp.pid != 0
16560                        && capp.pid != MY_PID) {
16561                    capp.kill("depends on provider "
16562                            + cpr.name.flattenToShortString()
16563                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16564                }
16565            } else if (capp.thread != null && conn.provider.provider != null) {
16566                try {
16567                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16568                } catch (RemoteException e) {
16569                }
16570                // In the protocol here, we don't expect the client to correctly
16571                // clean up this connection, we'll just remove it.
16572                cpr.connections.remove(i);
16573                if (conn.client.conProviders.remove(conn)) {
16574                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16575                }
16576            }
16577        }
16578
16579        if (inLaunching && always) {
16580            mLaunchingProviders.remove(cpr);
16581        }
16582        return inLaunching;
16583    }
16584
16585    /**
16586     * Main code for cleaning up a process when it has gone away.  This is
16587     * called both as a result of the process dying, or directly when stopping
16588     * a process when running in single process mode.
16589     *
16590     * @return Returns true if the given process has been restarted, so the
16591     * app that was passed in must remain on the process lists.
16592     */
16593    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16594            boolean restarting, boolean allowRestart, int index) {
16595        if (index >= 0) {
16596            removeLruProcessLocked(app);
16597            ProcessList.remove(app.pid);
16598        }
16599
16600        mProcessesToGc.remove(app);
16601        mPendingPssProcesses.remove(app);
16602
16603        // Dismiss any open dialogs.
16604        if (app.crashDialog != null && !app.forceCrashReport) {
16605            app.crashDialog.dismiss();
16606            app.crashDialog = null;
16607        }
16608        if (app.anrDialog != null) {
16609            app.anrDialog.dismiss();
16610            app.anrDialog = null;
16611        }
16612        if (app.waitDialog != null) {
16613            app.waitDialog.dismiss();
16614            app.waitDialog = null;
16615        }
16616
16617        app.crashing = false;
16618        app.notResponding = false;
16619
16620        app.resetPackageList(mProcessStats);
16621        app.unlinkDeathRecipient();
16622        app.makeInactive(mProcessStats);
16623        app.waitingToKill = null;
16624        app.forcingToForeground = null;
16625        updateProcessForegroundLocked(app, false, false);
16626        app.foregroundActivities = false;
16627        app.hasShownUi = false;
16628        app.treatLikeActivity = false;
16629        app.hasAboveClient = false;
16630        app.hasClientActivities = false;
16631
16632        mServices.killServicesLocked(app, allowRestart);
16633
16634        boolean restart = false;
16635
16636        // Remove published content providers.
16637        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16638            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16639            final boolean always = app.bad || !allowRestart;
16640            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16641            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16642                // We left the provider in the launching list, need to
16643                // restart it.
16644                restart = true;
16645            }
16646
16647            cpr.provider = null;
16648            cpr.proc = null;
16649        }
16650        app.pubProviders.clear();
16651
16652        // Take care of any launching providers waiting for this process.
16653        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16654            restart = true;
16655        }
16656
16657        // Unregister from connected content providers.
16658        if (!app.conProviders.isEmpty()) {
16659            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16660                ContentProviderConnection conn = app.conProviders.get(i);
16661                conn.provider.connections.remove(conn);
16662                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16663                        conn.provider.name);
16664            }
16665            app.conProviders.clear();
16666        }
16667
16668        // At this point there may be remaining entries in mLaunchingProviders
16669        // where we were the only one waiting, so they are no longer of use.
16670        // Look for these and clean up if found.
16671        // XXX Commented out for now.  Trying to figure out a way to reproduce
16672        // the actual situation to identify what is actually going on.
16673        if (false) {
16674            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16675                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16676                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16677                    synchronized (cpr) {
16678                        cpr.launchingApp = null;
16679                        cpr.notifyAll();
16680                    }
16681                }
16682            }
16683        }
16684
16685        skipCurrentReceiverLocked(app);
16686
16687        // Unregister any receivers.
16688        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16689            removeReceiverLocked(app.receivers.valueAt(i));
16690        }
16691        app.receivers.clear();
16692
16693        // If the app is undergoing backup, tell the backup manager about it
16694        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16695            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16696                    + mBackupTarget.appInfo + " died during backup");
16697            try {
16698                IBackupManager bm = IBackupManager.Stub.asInterface(
16699                        ServiceManager.getService(Context.BACKUP_SERVICE));
16700                bm.agentDisconnected(app.info.packageName);
16701            } catch (RemoteException e) {
16702                // can't happen; backup manager is local
16703            }
16704        }
16705
16706        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16707            ProcessChangeItem item = mPendingProcessChanges.get(i);
16708            if (item.pid == app.pid) {
16709                mPendingProcessChanges.remove(i);
16710                mAvailProcessChanges.add(item);
16711            }
16712        }
16713        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16714                null).sendToTarget();
16715
16716        // If the caller is restarting this app, then leave it in its
16717        // current lists and let the caller take care of it.
16718        if (restarting) {
16719            return false;
16720        }
16721
16722        if (!app.persistent || app.isolated) {
16723            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16724                    "Removing non-persistent process during cleanup: " + app);
16725            removeProcessNameLocked(app.processName, app.uid);
16726            if (mHeavyWeightProcess == app) {
16727                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16728                        mHeavyWeightProcess.userId, 0));
16729                mHeavyWeightProcess = null;
16730            }
16731        } else if (!app.removed) {
16732            // This app is persistent, so we need to keep its record around.
16733            // If it is not already on the pending app list, add it there
16734            // and start a new process for it.
16735            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16736                mPersistentStartingProcesses.add(app);
16737                restart = true;
16738            }
16739        }
16740        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16741                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16742        mProcessesOnHold.remove(app);
16743
16744        if (app == mHomeProcess) {
16745            mHomeProcess = null;
16746        }
16747        if (app == mPreviousProcess) {
16748            mPreviousProcess = null;
16749        }
16750
16751        if (restart && !app.isolated) {
16752            // We have components that still need to be running in the
16753            // process, so re-launch it.
16754            if (index < 0) {
16755                ProcessList.remove(app.pid);
16756            }
16757            addProcessNameLocked(app);
16758            startProcessLocked(app, "restart", app.processName);
16759            return true;
16760        } else if (app.pid > 0 && app.pid != MY_PID) {
16761            // Goodbye!
16762            boolean removed;
16763            synchronized (mPidsSelfLocked) {
16764                mPidsSelfLocked.remove(app.pid);
16765                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16766            }
16767            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16768            if (app.isolated) {
16769                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16770            }
16771            app.setPid(0);
16772        }
16773        return false;
16774    }
16775
16776    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16777        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16778            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16779            if (cpr.launchingApp == app) {
16780                return true;
16781            }
16782        }
16783        return false;
16784    }
16785
16786    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16787        // Look through the content providers we are waiting to have launched,
16788        // and if any run in this process then either schedule a restart of
16789        // the process or kill the client waiting for it if this process has
16790        // gone bad.
16791        boolean restart = false;
16792        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16793            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16794            if (cpr.launchingApp == app) {
16795                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16796                    restart = true;
16797                } else {
16798                    removeDyingProviderLocked(app, cpr, true);
16799                }
16800            }
16801        }
16802        return restart;
16803    }
16804
16805    // =========================================================
16806    // SERVICES
16807    // =========================================================
16808
16809    @Override
16810    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16811            int flags) {
16812        enforceNotIsolatedCaller("getServices");
16813        synchronized (this) {
16814            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16815        }
16816    }
16817
16818    @Override
16819    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16820        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16821        synchronized (this) {
16822            return mServices.getRunningServiceControlPanelLocked(name);
16823        }
16824    }
16825
16826    @Override
16827    public ComponentName startService(IApplicationThread caller, Intent service,
16828            String resolvedType, String callingPackage, int userId)
16829            throws TransactionTooLargeException {
16830        enforceNotIsolatedCaller("startService");
16831        // Refuse possible leaked file descriptors
16832        if (service != null && service.hasFileDescriptors() == true) {
16833            throw new IllegalArgumentException("File descriptors passed in Intent");
16834        }
16835
16836        if (callingPackage == null) {
16837            throw new IllegalArgumentException("callingPackage cannot be null");
16838        }
16839
16840        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16841                "startService: " + service + " type=" + resolvedType);
16842        synchronized(this) {
16843            final int callingPid = Binder.getCallingPid();
16844            final int callingUid = Binder.getCallingUid();
16845            final long origId = Binder.clearCallingIdentity();
16846            ComponentName res = mServices.startServiceLocked(caller, service,
16847                    resolvedType, callingPid, callingUid, callingPackage, userId);
16848            Binder.restoreCallingIdentity(origId);
16849            return res;
16850        }
16851    }
16852
16853    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16854            String callingPackage, int userId)
16855            throws TransactionTooLargeException {
16856        synchronized(this) {
16857            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16858                    "startServiceInPackage: " + service + " type=" + resolvedType);
16859            final long origId = Binder.clearCallingIdentity();
16860            ComponentName res = mServices.startServiceLocked(null, service,
16861                    resolvedType, -1, uid, callingPackage, userId);
16862            Binder.restoreCallingIdentity(origId);
16863            return res;
16864        }
16865    }
16866
16867    @Override
16868    public int stopService(IApplicationThread caller, Intent service,
16869            String resolvedType, int userId) {
16870        enforceNotIsolatedCaller("stopService");
16871        // Refuse possible leaked file descriptors
16872        if (service != null && service.hasFileDescriptors() == true) {
16873            throw new IllegalArgumentException("File descriptors passed in Intent");
16874        }
16875
16876        synchronized(this) {
16877            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16878        }
16879    }
16880
16881    @Override
16882    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16883        enforceNotIsolatedCaller("peekService");
16884        // Refuse possible leaked file descriptors
16885        if (service != null && service.hasFileDescriptors() == true) {
16886            throw new IllegalArgumentException("File descriptors passed in Intent");
16887        }
16888
16889        if (callingPackage == null) {
16890            throw new IllegalArgumentException("callingPackage cannot be null");
16891        }
16892
16893        synchronized(this) {
16894            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16895        }
16896    }
16897
16898    @Override
16899    public boolean stopServiceToken(ComponentName className, IBinder token,
16900            int startId) {
16901        synchronized(this) {
16902            return mServices.stopServiceTokenLocked(className, token, startId);
16903        }
16904    }
16905
16906    @Override
16907    public void setServiceForeground(ComponentName className, IBinder token,
16908            int id, Notification notification, int flags) {
16909        synchronized(this) {
16910            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16911        }
16912    }
16913
16914    @Override
16915    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16916            boolean requireFull, String name, String callerPackage) {
16917        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16918                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16919    }
16920
16921    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16922            String className, int flags) {
16923        boolean result = false;
16924        // For apps that don't have pre-defined UIDs, check for permission
16925        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16926            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16927                if (ActivityManager.checkUidPermission(
16928                        INTERACT_ACROSS_USERS,
16929                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16930                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16931                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16932                            + " requests FLAG_SINGLE_USER, but app does not hold "
16933                            + INTERACT_ACROSS_USERS;
16934                    Slog.w(TAG, msg);
16935                    throw new SecurityException(msg);
16936                }
16937                // Permission passed
16938                result = true;
16939            }
16940        } else if ("system".equals(componentProcessName)) {
16941            result = true;
16942        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16943            // Phone app and persistent apps are allowed to export singleuser providers.
16944            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16945                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16946        }
16947        if (DEBUG_MU) Slog.v(TAG_MU,
16948                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16949                + Integer.toHexString(flags) + ") = " + result);
16950        return result;
16951    }
16952
16953    /**
16954     * Checks to see if the caller is in the same app as the singleton
16955     * component, or the component is in a special app. It allows special apps
16956     * to export singleton components but prevents exporting singleton
16957     * components for regular apps.
16958     */
16959    boolean isValidSingletonCall(int callingUid, int componentUid) {
16960        int componentAppId = UserHandle.getAppId(componentUid);
16961        return UserHandle.isSameApp(callingUid, componentUid)
16962                || componentAppId == Process.SYSTEM_UID
16963                || componentAppId == Process.PHONE_UID
16964                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16965                        == PackageManager.PERMISSION_GRANTED;
16966    }
16967
16968    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16969            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16970            int userId) throws TransactionTooLargeException {
16971        enforceNotIsolatedCaller("bindService");
16972
16973        // Refuse possible leaked file descriptors
16974        if (service != null && service.hasFileDescriptors() == true) {
16975            throw new IllegalArgumentException("File descriptors passed in Intent");
16976        }
16977
16978        if (callingPackage == null) {
16979            throw new IllegalArgumentException("callingPackage cannot be null");
16980        }
16981
16982        synchronized(this) {
16983            return mServices.bindServiceLocked(caller, token, service,
16984                    resolvedType, connection, flags, callingPackage, userId);
16985        }
16986    }
16987
16988    public boolean unbindService(IServiceConnection connection) {
16989        synchronized (this) {
16990            return mServices.unbindServiceLocked(connection);
16991        }
16992    }
16993
16994    public void publishService(IBinder token, Intent intent, IBinder service) {
16995        // Refuse possible leaked file descriptors
16996        if (intent != null && intent.hasFileDescriptors() == true) {
16997            throw new IllegalArgumentException("File descriptors passed in Intent");
16998        }
16999
17000        synchronized(this) {
17001            if (!(token instanceof ServiceRecord)) {
17002                throw new IllegalArgumentException("Invalid service token");
17003            }
17004            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17005        }
17006    }
17007
17008    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17009        // Refuse possible leaked file descriptors
17010        if (intent != null && intent.hasFileDescriptors() == true) {
17011            throw new IllegalArgumentException("File descriptors passed in Intent");
17012        }
17013
17014        synchronized(this) {
17015            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17016        }
17017    }
17018
17019    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17020        synchronized(this) {
17021            if (!(token instanceof ServiceRecord)) {
17022                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17023                throw new IllegalArgumentException("Invalid service token");
17024            }
17025            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17026        }
17027    }
17028
17029    // =========================================================
17030    // BACKUP AND RESTORE
17031    // =========================================================
17032
17033    // Cause the target app to be launched if necessary and its backup agent
17034    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17035    // activity manager to announce its creation.
17036    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17037        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17038                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17039        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17040
17041        synchronized(this) {
17042            // !!! TODO: currently no check here that we're already bound
17043            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17044            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17045            synchronized (stats) {
17046                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17047            }
17048
17049            // Backup agent is now in use, its package can't be stopped.
17050            try {
17051                AppGlobals.getPackageManager().setPackageStoppedState(
17052                        app.packageName, false, UserHandle.getUserId(app.uid));
17053            } catch (RemoteException e) {
17054            } catch (IllegalArgumentException e) {
17055                Slog.w(TAG, "Failed trying to unstop package "
17056                        + app.packageName + ": " + e);
17057            }
17058
17059            BackupRecord r = new BackupRecord(ss, app, backupMode);
17060            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17061                    ? new ComponentName(app.packageName, app.backupAgentName)
17062                    : new ComponentName("android", "FullBackupAgent");
17063            // startProcessLocked() returns existing proc's record if it's already running
17064            ProcessRecord proc = startProcessLocked(app.processName, app,
17065                    false, 0, "backup", hostingName, false, false, false);
17066            if (proc == null) {
17067                Slog.e(TAG, "Unable to start backup agent process " + r);
17068                return false;
17069            }
17070
17071            // If the app is a regular app (uid >= 10000) and not the system server or phone
17072            // process, etc, then mark it as being in full backup so that certain calls to the
17073            // process can be blocked. This is not reset to false anywhere because we kill the
17074            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17075            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17076                proc.inFullBackup = true;
17077            }
17078            r.app = proc;
17079            mBackupTarget = r;
17080            mBackupAppName = app.packageName;
17081
17082            // Try not to kill the process during backup
17083            updateOomAdjLocked(proc);
17084
17085            // If the process is already attached, schedule the creation of the backup agent now.
17086            // If it is not yet live, this will be done when it attaches to the framework.
17087            if (proc.thread != null) {
17088                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17089                try {
17090                    proc.thread.scheduleCreateBackupAgent(app,
17091                            compatibilityInfoForPackageLocked(app), backupMode);
17092                } catch (RemoteException e) {
17093                    // Will time out on the backup manager side
17094                }
17095            } else {
17096                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17097            }
17098            // Invariants: at this point, the target app process exists and the application
17099            // is either already running or in the process of coming up.  mBackupTarget and
17100            // mBackupAppName describe the app, so that when it binds back to the AM we
17101            // know that it's scheduled for a backup-agent operation.
17102        }
17103
17104        return true;
17105    }
17106
17107    @Override
17108    public void clearPendingBackup() {
17109        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17110        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17111
17112        synchronized (this) {
17113            mBackupTarget = null;
17114            mBackupAppName = null;
17115        }
17116    }
17117
17118    // A backup agent has just come up
17119    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17120        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17121                + " = " + agent);
17122
17123        synchronized(this) {
17124            if (!agentPackageName.equals(mBackupAppName)) {
17125                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17126                return;
17127            }
17128        }
17129
17130        long oldIdent = Binder.clearCallingIdentity();
17131        try {
17132            IBackupManager bm = IBackupManager.Stub.asInterface(
17133                    ServiceManager.getService(Context.BACKUP_SERVICE));
17134            bm.agentConnected(agentPackageName, agent);
17135        } catch (RemoteException e) {
17136            // can't happen; the backup manager service is local
17137        } catch (Exception e) {
17138            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17139            e.printStackTrace();
17140        } finally {
17141            Binder.restoreCallingIdentity(oldIdent);
17142        }
17143    }
17144
17145    // done with this agent
17146    public void unbindBackupAgent(ApplicationInfo appInfo) {
17147        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17148        if (appInfo == null) {
17149            Slog.w(TAG, "unbind backup agent for null app");
17150            return;
17151        }
17152
17153        synchronized(this) {
17154            try {
17155                if (mBackupAppName == null) {
17156                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17157                    return;
17158                }
17159
17160                if (!mBackupAppName.equals(appInfo.packageName)) {
17161                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17162                    return;
17163                }
17164
17165                // Not backing this app up any more; reset its OOM adjustment
17166                final ProcessRecord proc = mBackupTarget.app;
17167                updateOomAdjLocked(proc);
17168
17169                // If the app crashed during backup, 'thread' will be null here
17170                if (proc.thread != null) {
17171                    try {
17172                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17173                                compatibilityInfoForPackageLocked(appInfo));
17174                    } catch (Exception e) {
17175                        Slog.e(TAG, "Exception when unbinding backup agent:");
17176                        e.printStackTrace();
17177                    }
17178                }
17179            } finally {
17180                mBackupTarget = null;
17181                mBackupAppName = null;
17182            }
17183        }
17184    }
17185    // =========================================================
17186    // BROADCASTS
17187    // =========================================================
17188
17189    boolean isPendingBroadcastProcessLocked(int pid) {
17190        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17191                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17192    }
17193
17194    void skipPendingBroadcastLocked(int pid) {
17195            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17196            for (BroadcastQueue queue : mBroadcastQueues) {
17197                queue.skipPendingBroadcastLocked(pid);
17198            }
17199    }
17200
17201    // The app just attached; send any pending broadcasts that it should receive
17202    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17203        boolean didSomething = false;
17204        for (BroadcastQueue queue : mBroadcastQueues) {
17205            didSomething |= queue.sendPendingBroadcastsLocked(app);
17206        }
17207        return didSomething;
17208    }
17209
17210    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17211            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17212        enforceNotIsolatedCaller("registerReceiver");
17213        ArrayList<Intent> stickyIntents = null;
17214        ProcessRecord callerApp = null;
17215        int callingUid;
17216        int callingPid;
17217        synchronized(this) {
17218            if (caller != null) {
17219                callerApp = getRecordForAppLocked(caller);
17220                if (callerApp == null) {
17221                    throw new SecurityException(
17222                            "Unable to find app for caller " + caller
17223                            + " (pid=" + Binder.getCallingPid()
17224                            + ") when registering receiver " + receiver);
17225                }
17226                if (callerApp.info.uid != Process.SYSTEM_UID &&
17227                        !callerApp.pkgList.containsKey(callerPackage) &&
17228                        !"android".equals(callerPackage)) {
17229                    throw new SecurityException("Given caller package " + callerPackage
17230                            + " is not running in process " + callerApp);
17231                }
17232                callingUid = callerApp.info.uid;
17233                callingPid = callerApp.pid;
17234            } else {
17235                callerPackage = null;
17236                callingUid = Binder.getCallingUid();
17237                callingPid = Binder.getCallingPid();
17238            }
17239
17240            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17241                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17242
17243            Iterator<String> actions = filter.actionsIterator();
17244            if (actions == null) {
17245                ArrayList<String> noAction = new ArrayList<String>(1);
17246                noAction.add(null);
17247                actions = noAction.iterator();
17248            }
17249
17250            // Collect stickies of users
17251            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17252            while (actions.hasNext()) {
17253                String action = actions.next();
17254                for (int id : userIds) {
17255                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17256                    if (stickies != null) {
17257                        ArrayList<Intent> intents = stickies.get(action);
17258                        if (intents != null) {
17259                            if (stickyIntents == null) {
17260                                stickyIntents = new ArrayList<Intent>();
17261                            }
17262                            stickyIntents.addAll(intents);
17263                        }
17264                    }
17265                }
17266            }
17267        }
17268
17269        ArrayList<Intent> allSticky = null;
17270        if (stickyIntents != null) {
17271            final ContentResolver resolver = mContext.getContentResolver();
17272            // Look for any matching sticky broadcasts...
17273            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17274                Intent intent = stickyIntents.get(i);
17275                // If intent has scheme "content", it will need to acccess
17276                // provider that needs to lock mProviderMap in ActivityThread
17277                // and also it may need to wait application response, so we
17278                // cannot lock ActivityManagerService here.
17279                if (filter.match(resolver, intent, true, TAG) >= 0) {
17280                    if (allSticky == null) {
17281                        allSticky = new ArrayList<Intent>();
17282                    }
17283                    allSticky.add(intent);
17284                }
17285            }
17286        }
17287
17288        // The first sticky in the list is returned directly back to the client.
17289        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17290        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17291        if (receiver == null) {
17292            return sticky;
17293        }
17294
17295        synchronized (this) {
17296            if (callerApp != null && (callerApp.thread == null
17297                    || callerApp.thread.asBinder() != caller.asBinder())) {
17298                // Original caller already died
17299                return null;
17300            }
17301            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17302            if (rl == null) {
17303                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17304                        userId, receiver);
17305                if (rl.app != null) {
17306                    rl.app.receivers.add(rl);
17307                } else {
17308                    try {
17309                        receiver.asBinder().linkToDeath(rl, 0);
17310                    } catch (RemoteException e) {
17311                        return sticky;
17312                    }
17313                    rl.linkedToDeath = true;
17314                }
17315                mRegisteredReceivers.put(receiver.asBinder(), rl);
17316            } else if (rl.uid != callingUid) {
17317                throw new IllegalArgumentException(
17318                        "Receiver requested to register for uid " + callingUid
17319                        + " was previously registered for uid " + rl.uid);
17320            } else if (rl.pid != callingPid) {
17321                throw new IllegalArgumentException(
17322                        "Receiver requested to register for pid " + callingPid
17323                        + " was previously registered for pid " + rl.pid);
17324            } else if (rl.userId != userId) {
17325                throw new IllegalArgumentException(
17326                        "Receiver requested to register for user " + userId
17327                        + " was previously registered for user " + rl.userId);
17328            }
17329            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17330                    permission, callingUid, userId);
17331            rl.add(bf);
17332            if (!bf.debugCheck()) {
17333                Slog.w(TAG, "==> For Dynamic broadcast");
17334            }
17335            mReceiverResolver.addFilter(bf);
17336
17337            // Enqueue broadcasts for all existing stickies that match
17338            // this filter.
17339            if (allSticky != null) {
17340                ArrayList receivers = new ArrayList();
17341                receivers.add(bf);
17342
17343                final int stickyCount = allSticky.size();
17344                for (int i = 0; i < stickyCount; i++) {
17345                    Intent intent = allSticky.get(i);
17346                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17347                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17348                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17349                            null, 0, null, null, false, true, true, -1);
17350                    queue.enqueueParallelBroadcastLocked(r);
17351                    queue.scheduleBroadcastsLocked();
17352                }
17353            }
17354
17355            return sticky;
17356        }
17357    }
17358
17359    public void unregisterReceiver(IIntentReceiver receiver) {
17360        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17361
17362        final long origId = Binder.clearCallingIdentity();
17363        try {
17364            boolean doTrim = false;
17365
17366            synchronized(this) {
17367                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17368                if (rl != null) {
17369                    final BroadcastRecord r = rl.curBroadcast;
17370                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17371                        final boolean doNext = r.queue.finishReceiverLocked(
17372                                r, r.resultCode, r.resultData, r.resultExtras,
17373                                r.resultAbort, false);
17374                        if (doNext) {
17375                            doTrim = true;
17376                            r.queue.processNextBroadcast(false);
17377                        }
17378                    }
17379
17380                    if (rl.app != null) {
17381                        rl.app.receivers.remove(rl);
17382                    }
17383                    removeReceiverLocked(rl);
17384                    if (rl.linkedToDeath) {
17385                        rl.linkedToDeath = false;
17386                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17387                    }
17388                }
17389            }
17390
17391            // If we actually concluded any broadcasts, we might now be able
17392            // to trim the recipients' apps from our working set
17393            if (doTrim) {
17394                trimApplications();
17395                return;
17396            }
17397
17398        } finally {
17399            Binder.restoreCallingIdentity(origId);
17400        }
17401    }
17402
17403    void removeReceiverLocked(ReceiverList rl) {
17404        mRegisteredReceivers.remove(rl.receiver.asBinder());
17405        for (int i = rl.size() - 1; i >= 0; i--) {
17406            mReceiverResolver.removeFilter(rl.get(i));
17407        }
17408    }
17409
17410    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17411        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17412            ProcessRecord r = mLruProcesses.get(i);
17413            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17414                try {
17415                    r.thread.dispatchPackageBroadcast(cmd, packages);
17416                } catch (RemoteException ex) {
17417                }
17418            }
17419        }
17420    }
17421
17422    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17423            int callingUid, int[] users) {
17424        // TODO: come back and remove this assumption to triage all broadcasts
17425        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17426
17427        List<ResolveInfo> receivers = null;
17428        try {
17429            HashSet<ComponentName> singleUserReceivers = null;
17430            boolean scannedFirstReceivers = false;
17431            for (int user : users) {
17432                // Skip users that have Shell restrictions, with exception of always permitted
17433                // Shell broadcasts
17434                if (callingUid == Process.SHELL_UID
17435                        && mUserController.hasUserRestriction(
17436                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17437                        && !isPermittedShellBroadcast(intent)) {
17438                    continue;
17439                }
17440                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17441                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17442                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17443                    // If this is not the system user, we need to check for
17444                    // any receivers that should be filtered out.
17445                    for (int i=0; i<newReceivers.size(); i++) {
17446                        ResolveInfo ri = newReceivers.get(i);
17447                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17448                            newReceivers.remove(i);
17449                            i--;
17450                        }
17451                    }
17452                }
17453                if (newReceivers != null && newReceivers.size() == 0) {
17454                    newReceivers = null;
17455                }
17456                if (receivers == null) {
17457                    receivers = newReceivers;
17458                } else if (newReceivers != null) {
17459                    // We need to concatenate the additional receivers
17460                    // found with what we have do far.  This would be easy,
17461                    // but we also need to de-dup any receivers that are
17462                    // singleUser.
17463                    if (!scannedFirstReceivers) {
17464                        // Collect any single user receivers we had already retrieved.
17465                        scannedFirstReceivers = true;
17466                        for (int i=0; i<receivers.size(); i++) {
17467                            ResolveInfo ri = receivers.get(i);
17468                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17469                                ComponentName cn = new ComponentName(
17470                                        ri.activityInfo.packageName, ri.activityInfo.name);
17471                                if (singleUserReceivers == null) {
17472                                    singleUserReceivers = new HashSet<ComponentName>();
17473                                }
17474                                singleUserReceivers.add(cn);
17475                            }
17476                        }
17477                    }
17478                    // Add the new results to the existing results, tracking
17479                    // and de-dupping single user receivers.
17480                    for (int i=0; i<newReceivers.size(); i++) {
17481                        ResolveInfo ri = newReceivers.get(i);
17482                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17483                            ComponentName cn = new ComponentName(
17484                                    ri.activityInfo.packageName, ri.activityInfo.name);
17485                            if (singleUserReceivers == null) {
17486                                singleUserReceivers = new HashSet<ComponentName>();
17487                            }
17488                            if (!singleUserReceivers.contains(cn)) {
17489                                singleUserReceivers.add(cn);
17490                                receivers.add(ri);
17491                            }
17492                        } else {
17493                            receivers.add(ri);
17494                        }
17495                    }
17496                }
17497            }
17498        } catch (RemoteException ex) {
17499            // pm is in same process, this will never happen.
17500        }
17501        return receivers;
17502    }
17503
17504    private boolean isPermittedShellBroadcast(Intent intent) {
17505        // remote bugreport should always be allowed to be taken
17506        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17507    }
17508
17509    final int broadcastIntentLocked(ProcessRecord callerApp,
17510            String callerPackage, Intent intent, String resolvedType,
17511            IIntentReceiver resultTo, int resultCode, String resultData,
17512            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17513            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17514        intent = new Intent(intent);
17515
17516        // By default broadcasts do not go to stopped apps.
17517        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17518
17519        // If we have not finished booting, don't allow this to launch new processes.
17520        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17521            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17522        }
17523
17524        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17525                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17526                + " ordered=" + ordered + " userid=" + userId);
17527        if ((resultTo != null) && !ordered) {
17528            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17529        }
17530
17531        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17532                ALLOW_NON_FULL, "broadcast", callerPackage);
17533
17534        // Make sure that the user who is receiving this broadcast is running.
17535        // If not, we will just skip it. Make an exception for shutdown broadcasts
17536        // and upgrade steps.
17537
17538        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17539            if ((callingUid != Process.SYSTEM_UID
17540                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17541                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17542                Slog.w(TAG, "Skipping broadcast of " + intent
17543                        + ": user " + userId + " is stopped");
17544                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17545            }
17546        }
17547
17548        BroadcastOptions brOptions = null;
17549        if (bOptions != null) {
17550            brOptions = new BroadcastOptions(bOptions);
17551            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17552                // See if the caller is allowed to do this.  Note we are checking against
17553                // the actual real caller (not whoever provided the operation as say a
17554                // PendingIntent), because that who is actually supplied the arguments.
17555                if (checkComponentPermission(
17556                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17557                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17558                        != PackageManager.PERMISSION_GRANTED) {
17559                    String msg = "Permission Denial: " + intent.getAction()
17560                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17561                            + ", uid=" + callingUid + ")"
17562                            + " requires "
17563                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17564                    Slog.w(TAG, msg);
17565                    throw new SecurityException(msg);
17566                }
17567            }
17568        }
17569
17570        // Verify that protected broadcasts are only being sent by system code,
17571        // and that system code is only sending protected broadcasts.
17572        final String action = intent.getAction();
17573        final boolean isProtectedBroadcast;
17574        try {
17575            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17576        } catch (RemoteException e) {
17577            Slog.w(TAG, "Remote exception", e);
17578            return ActivityManager.BROADCAST_SUCCESS;
17579        }
17580
17581        final boolean isCallerSystem;
17582        switch (UserHandle.getAppId(callingUid)) {
17583            case Process.ROOT_UID:
17584            case Process.SYSTEM_UID:
17585            case Process.PHONE_UID:
17586            case Process.BLUETOOTH_UID:
17587            case Process.NFC_UID:
17588                isCallerSystem = true;
17589                break;
17590            default:
17591                isCallerSystem = (callerApp != null) && callerApp.persistent;
17592                break;
17593        }
17594
17595        if (isCallerSystem) {
17596            if (isProtectedBroadcast
17597                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17598                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17599                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17600                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17601                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17602                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17603                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17604                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17605                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17606                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17607                // Broadcast is either protected, or it's a public action that
17608                // we've relaxed, so it's fine for system internals to send.
17609            } else {
17610                // The vast majority of broadcasts sent from system internals
17611                // should be protected to avoid security holes, so yell loudly
17612                // to ensure we examine these cases.
17613                if (callerApp != null) {
17614                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17615                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17616                            new Throwable());
17617                } else {
17618                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17619                            + " from system uid " + UserHandle.formatUid(callingUid)
17620                            + " pkg " + callerPackage,
17621                            new Throwable());
17622                }
17623            }
17624
17625        } else {
17626            if (isProtectedBroadcast) {
17627                String msg = "Permission Denial: not allowed to send broadcast "
17628                        + action + " from pid="
17629                        + callingPid + ", uid=" + callingUid;
17630                Slog.w(TAG, msg);
17631                throw new SecurityException(msg);
17632
17633            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17634                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17635                // Special case for compatibility: we don't want apps to send this,
17636                // but historically it has not been protected and apps may be using it
17637                // to poke their own app widget.  So, instead of making it protected,
17638                // just limit it to the caller.
17639                if (callerPackage == null) {
17640                    String msg = "Permission Denial: not allowed to send broadcast "
17641                            + action + " from unknown caller.";
17642                    Slog.w(TAG, msg);
17643                    throw new SecurityException(msg);
17644                } else if (intent.getComponent() != null) {
17645                    // They are good enough to send to an explicit component...  verify
17646                    // it is being sent to the calling app.
17647                    if (!intent.getComponent().getPackageName().equals(
17648                            callerPackage)) {
17649                        String msg = "Permission Denial: not allowed to send broadcast "
17650                                + action + " to "
17651                                + intent.getComponent().getPackageName() + " from "
17652                                + callerPackage;
17653                        Slog.w(TAG, msg);
17654                        throw new SecurityException(msg);
17655                    }
17656                } else {
17657                    // Limit broadcast to their own package.
17658                    intent.setPackage(callerPackage);
17659                }
17660            }
17661        }
17662
17663        if (action != null) {
17664            switch (action) {
17665                case Intent.ACTION_UID_REMOVED:
17666                case Intent.ACTION_PACKAGE_REMOVED:
17667                case Intent.ACTION_PACKAGE_CHANGED:
17668                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17669                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17670                case Intent.ACTION_PACKAGES_SUSPENDED:
17671                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17672                    // Handle special intents: if this broadcast is from the package
17673                    // manager about a package being removed, we need to remove all of
17674                    // its activities from the history stack.
17675                    if (checkComponentPermission(
17676                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17677                            callingPid, callingUid, -1, true)
17678                            != PackageManager.PERMISSION_GRANTED) {
17679                        String msg = "Permission Denial: " + intent.getAction()
17680                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17681                                + ", uid=" + callingUid + ")"
17682                                + " requires "
17683                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17684                        Slog.w(TAG, msg);
17685                        throw new SecurityException(msg);
17686                    }
17687                    switch (action) {
17688                        case Intent.ACTION_UID_REMOVED:
17689                            final Bundle intentExtras = intent.getExtras();
17690                            final int uid = intentExtras != null
17691                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17692                            if (uid >= 0) {
17693                                mBatteryStatsService.removeUid(uid);
17694                                mAppOpsService.uidRemoved(uid);
17695                            }
17696                            break;
17697                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17698                            // If resources are unavailable just force stop all those packages
17699                            // and flush the attribute cache as well.
17700                            String list[] =
17701                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17702                            if (list != null && list.length > 0) {
17703                                for (int i = 0; i < list.length; i++) {
17704                                    forceStopPackageLocked(list[i], -1, false, true, true,
17705                                            false, false, userId, "storage unmount");
17706                                }
17707                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17708                                sendPackageBroadcastLocked(
17709                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17710                                        userId);
17711                            }
17712                            break;
17713                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17714                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17715                            break;
17716                        case Intent.ACTION_PACKAGE_REMOVED:
17717                        case Intent.ACTION_PACKAGE_CHANGED:
17718                            Uri data = intent.getData();
17719                            String ssp;
17720                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17721                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17722                                final boolean replacing =
17723                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17724                                final boolean killProcess =
17725                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17726                                final boolean fullUninstall = removed && !replacing;
17727                                if (removed) {
17728                                    if (killProcess) {
17729                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17730                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17731                                                false, true, true, false, fullUninstall, userId,
17732                                                removed ? "pkg removed" : "pkg changed");
17733                                    }
17734                                    final int cmd = killProcess
17735                                            ? IApplicationThread.PACKAGE_REMOVED
17736                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17737                                    sendPackageBroadcastLocked(cmd,
17738                                            new String[] {ssp}, userId);
17739                                    if (fullUninstall) {
17740                                        mAppOpsService.packageRemoved(
17741                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17742
17743                                        // Remove all permissions granted from/to this package
17744                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17745
17746                                        removeTasksByPackageNameLocked(ssp, userId);
17747                                        mBatteryStatsService.notePackageUninstalled(ssp);
17748                                    }
17749                                } else {
17750                                    if (killProcess) {
17751                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17752                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17753                                                userId, ProcessList.INVALID_ADJ,
17754                                                false, true, true, false, "change " + ssp);
17755                                    }
17756                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17757                                            intent.getStringArrayExtra(
17758                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17759                                }
17760                            }
17761                            break;
17762                        case Intent.ACTION_PACKAGES_SUSPENDED:
17763                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17764                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17765                                    intent.getAction());
17766                            final String[] packageNames = intent.getStringArrayExtra(
17767                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17768                            final int userHandle = intent.getIntExtra(
17769                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17770
17771                            synchronized(ActivityManagerService.this) {
17772                                mRecentTasks.onPackagesSuspendedChanged(
17773                                        packageNames, suspended, userHandle);
17774                            }
17775                            break;
17776                    }
17777                    break;
17778                case Intent.ACTION_PACKAGE_REPLACED:
17779                {
17780                    final Uri data = intent.getData();
17781                    final String ssp;
17782                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17783                        final ApplicationInfo aInfo =
17784                                getPackageManagerInternalLocked().getApplicationInfo(
17785                                        ssp,
17786                                        userId);
17787                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17788                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17789                                new String[] {ssp}, userId);
17790                    }
17791                    break;
17792                }
17793                case Intent.ACTION_PACKAGE_ADDED:
17794                {
17795                    // Special case for adding a package: by default turn on compatibility mode.
17796                    Uri data = intent.getData();
17797                    String ssp;
17798                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17799                        final boolean replacing =
17800                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17801                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17802
17803                        try {
17804                            ApplicationInfo ai = AppGlobals.getPackageManager().
17805                                    getApplicationInfo(ssp, 0, 0);
17806                            mBatteryStatsService.notePackageInstalled(ssp,
17807                                    ai != null ? ai.versionCode : 0);
17808                        } catch (RemoteException e) {
17809                        }
17810                    }
17811                    break;
17812                }
17813                case Intent.ACTION_TIMEZONE_CHANGED:
17814                    // If this is the time zone changed action, queue up a message that will reset
17815                    // the timezone of all currently running processes. This message will get
17816                    // queued up before the broadcast happens.
17817                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17818                    break;
17819                case Intent.ACTION_TIME_CHANGED:
17820                    // If the user set the time, let all running processes know.
17821                    final int is24Hour =
17822                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17823                                    : 0;
17824                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17825                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17826                    synchronized (stats) {
17827                        stats.noteCurrentTimeChangedLocked();
17828                    }
17829                    break;
17830                case Intent.ACTION_CLEAR_DNS_CACHE:
17831                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17832                    break;
17833                case Proxy.PROXY_CHANGE_ACTION:
17834                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17835                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17836                    break;
17837                case android.hardware.Camera.ACTION_NEW_PICTURE:
17838                case android.hardware.Camera.ACTION_NEW_VIDEO:
17839                    // These broadcasts are no longer allowed by the system, since they can
17840                    // cause significant thrashing at a crictical point (using the camera).
17841                    // Apps should use JobScehduler to monitor for media provider changes.
17842                    Slog.w(TAG, action + " no longer allowed; dropping from "
17843                            + UserHandle.formatUid(callingUid));
17844                    // Lie; we don't want to crash the app.
17845                    return ActivityManager.BROADCAST_SUCCESS;
17846            }
17847        }
17848
17849        // Add to the sticky list if requested.
17850        if (sticky) {
17851            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17852                    callingPid, callingUid)
17853                    != PackageManager.PERMISSION_GRANTED) {
17854                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17855                        + callingPid + ", uid=" + callingUid
17856                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17857                Slog.w(TAG, msg);
17858                throw new SecurityException(msg);
17859            }
17860            if (requiredPermissions != null && requiredPermissions.length > 0) {
17861                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17862                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17863                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17864            }
17865            if (intent.getComponent() != null) {
17866                throw new SecurityException(
17867                        "Sticky broadcasts can't target a specific component");
17868            }
17869            // We use userId directly here, since the "all" target is maintained
17870            // as a separate set of sticky broadcasts.
17871            if (userId != UserHandle.USER_ALL) {
17872                // But first, if this is not a broadcast to all users, then
17873                // make sure it doesn't conflict with an existing broadcast to
17874                // all users.
17875                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17876                        UserHandle.USER_ALL);
17877                if (stickies != null) {
17878                    ArrayList<Intent> list = stickies.get(intent.getAction());
17879                    if (list != null) {
17880                        int N = list.size();
17881                        int i;
17882                        for (i=0; i<N; i++) {
17883                            if (intent.filterEquals(list.get(i))) {
17884                                throw new IllegalArgumentException(
17885                                        "Sticky broadcast " + intent + " for user "
17886                                        + userId + " conflicts with existing global broadcast");
17887                            }
17888                        }
17889                    }
17890                }
17891            }
17892            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17893            if (stickies == null) {
17894                stickies = new ArrayMap<>();
17895                mStickyBroadcasts.put(userId, stickies);
17896            }
17897            ArrayList<Intent> list = stickies.get(intent.getAction());
17898            if (list == null) {
17899                list = new ArrayList<>();
17900                stickies.put(intent.getAction(), list);
17901            }
17902            final int stickiesCount = list.size();
17903            int i;
17904            for (i = 0; i < stickiesCount; i++) {
17905                if (intent.filterEquals(list.get(i))) {
17906                    // This sticky already exists, replace it.
17907                    list.set(i, new Intent(intent));
17908                    break;
17909                }
17910            }
17911            if (i >= stickiesCount) {
17912                list.add(new Intent(intent));
17913            }
17914        }
17915
17916        int[] users;
17917        if (userId == UserHandle.USER_ALL) {
17918            // Caller wants broadcast to go to all started users.
17919            users = mUserController.getStartedUserArrayLocked();
17920        } else {
17921            // Caller wants broadcast to go to one specific user.
17922            users = new int[] {userId};
17923        }
17924
17925        // Figure out who all will receive this broadcast.
17926        List receivers = null;
17927        List<BroadcastFilter> registeredReceivers = null;
17928        // Need to resolve the intent to interested receivers...
17929        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17930                 == 0) {
17931            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17932        }
17933        if (intent.getComponent() == null) {
17934            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17935                // Query one target user at a time, excluding shell-restricted users
17936                for (int i = 0; i < users.length; i++) {
17937                    if (mUserController.hasUserRestriction(
17938                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17939                        continue;
17940                    }
17941                    List<BroadcastFilter> registeredReceiversForUser =
17942                            mReceiverResolver.queryIntent(intent,
17943                                    resolvedType, false, users[i]);
17944                    if (registeredReceivers == null) {
17945                        registeredReceivers = registeredReceiversForUser;
17946                    } else if (registeredReceiversForUser != null) {
17947                        registeredReceivers.addAll(registeredReceiversForUser);
17948                    }
17949                }
17950            } else {
17951                registeredReceivers = mReceiverResolver.queryIntent(intent,
17952                        resolvedType, false, userId);
17953            }
17954        }
17955
17956        final boolean replacePending =
17957                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17958
17959        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17960                + " replacePending=" + replacePending);
17961
17962        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17963        if (!ordered && NR > 0) {
17964            // If we are not serializing this broadcast, then send the
17965            // registered receivers separately so they don't wait for the
17966            // components to be launched.
17967            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17968            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17969                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17970                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17971                    resultExtras, ordered, sticky, false, userId);
17972            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17973            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17974            if (!replaced) {
17975                queue.enqueueParallelBroadcastLocked(r);
17976                queue.scheduleBroadcastsLocked();
17977            }
17978            registeredReceivers = null;
17979            NR = 0;
17980        }
17981
17982        // Merge into one list.
17983        int ir = 0;
17984        if (receivers != null) {
17985            // A special case for PACKAGE_ADDED: do not allow the package
17986            // being added to see this broadcast.  This prevents them from
17987            // using this as a back door to get run as soon as they are
17988            // installed.  Maybe in the future we want to have a special install
17989            // broadcast or such for apps, but we'd like to deliberately make
17990            // this decision.
17991            String skipPackages[] = null;
17992            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17993                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17994                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17995                Uri data = intent.getData();
17996                if (data != null) {
17997                    String pkgName = data.getSchemeSpecificPart();
17998                    if (pkgName != null) {
17999                        skipPackages = new String[] { pkgName };
18000                    }
18001                }
18002            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18003                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18004            }
18005            if (skipPackages != null && (skipPackages.length > 0)) {
18006                for (String skipPackage : skipPackages) {
18007                    if (skipPackage != null) {
18008                        int NT = receivers.size();
18009                        for (int it=0; it<NT; it++) {
18010                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18011                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18012                                receivers.remove(it);
18013                                it--;
18014                                NT--;
18015                            }
18016                        }
18017                    }
18018                }
18019            }
18020
18021            int NT = receivers != null ? receivers.size() : 0;
18022            int it = 0;
18023            ResolveInfo curt = null;
18024            BroadcastFilter curr = null;
18025            while (it < NT && ir < NR) {
18026                if (curt == null) {
18027                    curt = (ResolveInfo)receivers.get(it);
18028                }
18029                if (curr == null) {
18030                    curr = registeredReceivers.get(ir);
18031                }
18032                if (curr.getPriority() >= curt.priority) {
18033                    // Insert this broadcast record into the final list.
18034                    receivers.add(it, curr);
18035                    ir++;
18036                    curr = null;
18037                    it++;
18038                    NT++;
18039                } else {
18040                    // Skip to the next ResolveInfo in the final list.
18041                    it++;
18042                    curt = null;
18043                }
18044            }
18045        }
18046        while (ir < NR) {
18047            if (receivers == null) {
18048                receivers = new ArrayList();
18049            }
18050            receivers.add(registeredReceivers.get(ir));
18051            ir++;
18052        }
18053
18054        if ((receivers != null && receivers.size() > 0)
18055                || resultTo != null) {
18056            BroadcastQueue queue = broadcastQueueForIntent(intent);
18057            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18058                    callerPackage, callingPid, callingUid, resolvedType,
18059                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18060                    resultData, resultExtras, ordered, sticky, false, userId);
18061
18062            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18063                    + ": prev had " + queue.mOrderedBroadcasts.size());
18064            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18065                    "Enqueueing broadcast " + r.intent.getAction());
18066
18067            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18068            if (!replaced) {
18069                queue.enqueueOrderedBroadcastLocked(r);
18070                queue.scheduleBroadcastsLocked();
18071            }
18072        } else {
18073            // There was nobody interested in the broadcast, but we still want to record
18074            // that it happened.
18075            if (intent.getComponent() == null && intent.getPackage() == null
18076                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18077                // This was an implicit broadcast... let's record it for posterity.
18078                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18079            }
18080        }
18081
18082        return ActivityManager.BROADCAST_SUCCESS;
18083    }
18084
18085    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18086            int skipCount, long dispatchTime) {
18087        final long now = SystemClock.elapsedRealtime();
18088        if (mCurBroadcastStats == null ||
18089                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18090            mLastBroadcastStats = mCurBroadcastStats;
18091            if (mLastBroadcastStats != null) {
18092                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18093                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18094            }
18095            mCurBroadcastStats = new BroadcastStats();
18096        }
18097        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18098    }
18099
18100    final Intent verifyBroadcastLocked(Intent intent) {
18101        // Refuse possible leaked file descriptors
18102        if (intent != null && intent.hasFileDescriptors() == true) {
18103            throw new IllegalArgumentException("File descriptors passed in Intent");
18104        }
18105
18106        int flags = intent.getFlags();
18107
18108        if (!mProcessesReady) {
18109            // if the caller really truly claims to know what they're doing, go
18110            // ahead and allow the broadcast without launching any receivers
18111            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18112                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18113            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18114                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18115                        + " before boot completion");
18116                throw new IllegalStateException("Cannot broadcast before boot completed");
18117            }
18118        }
18119
18120        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18121            throw new IllegalArgumentException(
18122                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18123        }
18124
18125        return intent;
18126    }
18127
18128    public final int broadcastIntent(IApplicationThread caller,
18129            Intent intent, String resolvedType, IIntentReceiver resultTo,
18130            int resultCode, String resultData, Bundle resultExtras,
18131            String[] requiredPermissions, int appOp, Bundle bOptions,
18132            boolean serialized, boolean sticky, int userId) {
18133        enforceNotIsolatedCaller("broadcastIntent");
18134        synchronized(this) {
18135            intent = verifyBroadcastLocked(intent);
18136
18137            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18138            final int callingPid = Binder.getCallingPid();
18139            final int callingUid = Binder.getCallingUid();
18140            final long origId = Binder.clearCallingIdentity();
18141            int res = broadcastIntentLocked(callerApp,
18142                    callerApp != null ? callerApp.info.packageName : null,
18143                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18144                    requiredPermissions, appOp, bOptions, serialized, sticky,
18145                    callingPid, callingUid, userId);
18146            Binder.restoreCallingIdentity(origId);
18147            return res;
18148        }
18149    }
18150
18151
18152    int broadcastIntentInPackage(String packageName, int uid,
18153            Intent intent, String resolvedType, IIntentReceiver resultTo,
18154            int resultCode, String resultData, Bundle resultExtras,
18155            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18156            int userId) {
18157        synchronized(this) {
18158            intent = verifyBroadcastLocked(intent);
18159
18160            final long origId = Binder.clearCallingIdentity();
18161            String[] requiredPermissions = requiredPermission == null ? null
18162                    : new String[] {requiredPermission};
18163            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18164                    resultTo, resultCode, resultData, resultExtras,
18165                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18166                    sticky, -1, uid, userId);
18167            Binder.restoreCallingIdentity(origId);
18168            return res;
18169        }
18170    }
18171
18172    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18173        // Refuse possible leaked file descriptors
18174        if (intent != null && intent.hasFileDescriptors() == true) {
18175            throw new IllegalArgumentException("File descriptors passed in Intent");
18176        }
18177
18178        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18179                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18180
18181        synchronized(this) {
18182            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18183                    != PackageManager.PERMISSION_GRANTED) {
18184                String msg = "Permission Denial: unbroadcastIntent() from pid="
18185                        + Binder.getCallingPid()
18186                        + ", uid=" + Binder.getCallingUid()
18187                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18188                Slog.w(TAG, msg);
18189                throw new SecurityException(msg);
18190            }
18191            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18192            if (stickies != null) {
18193                ArrayList<Intent> list = stickies.get(intent.getAction());
18194                if (list != null) {
18195                    int N = list.size();
18196                    int i;
18197                    for (i=0; i<N; i++) {
18198                        if (intent.filterEquals(list.get(i))) {
18199                            list.remove(i);
18200                            break;
18201                        }
18202                    }
18203                    if (list.size() <= 0) {
18204                        stickies.remove(intent.getAction());
18205                    }
18206                }
18207                if (stickies.size() <= 0) {
18208                    mStickyBroadcasts.remove(userId);
18209                }
18210            }
18211        }
18212    }
18213
18214    void backgroundServicesFinishedLocked(int userId) {
18215        for (BroadcastQueue queue : mBroadcastQueues) {
18216            queue.backgroundServicesFinishedLocked(userId);
18217        }
18218    }
18219
18220    public void finishReceiver(IBinder who, int resultCode, String resultData,
18221            Bundle resultExtras, boolean resultAbort, int flags) {
18222        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18223
18224        // Refuse possible leaked file descriptors
18225        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18226            throw new IllegalArgumentException("File descriptors passed in Bundle");
18227        }
18228
18229        final long origId = Binder.clearCallingIdentity();
18230        try {
18231            boolean doNext = false;
18232            BroadcastRecord r;
18233
18234            synchronized(this) {
18235                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18236                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18237                r = queue.getMatchingOrderedReceiver(who);
18238                if (r != null) {
18239                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18240                        resultData, resultExtras, resultAbort, true);
18241                }
18242            }
18243
18244            if (doNext) {
18245                r.queue.processNextBroadcast(false);
18246            }
18247            trimApplications();
18248        } finally {
18249            Binder.restoreCallingIdentity(origId);
18250        }
18251    }
18252
18253    // =========================================================
18254    // INSTRUMENTATION
18255    // =========================================================
18256
18257    public boolean startInstrumentation(ComponentName className,
18258            String profileFile, int flags, Bundle arguments,
18259            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18260            int userId, String abiOverride) {
18261        enforceNotIsolatedCaller("startInstrumentation");
18262        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18263                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18264        // Refuse possible leaked file descriptors
18265        if (arguments != null && arguments.hasFileDescriptors()) {
18266            throw new IllegalArgumentException("File descriptors passed in Bundle");
18267        }
18268
18269        synchronized(this) {
18270            InstrumentationInfo ii = null;
18271            ApplicationInfo ai = null;
18272            try {
18273                ii = mContext.getPackageManager().getInstrumentationInfo(
18274                    className, STOCK_PM_FLAGS);
18275                ai = AppGlobals.getPackageManager().getApplicationInfo(
18276                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18277            } catch (PackageManager.NameNotFoundException e) {
18278            } catch (RemoteException e) {
18279            }
18280            if (ii == null) {
18281                reportStartInstrumentationFailureLocked(watcher, className,
18282                        "Unable to find instrumentation info for: " + className);
18283                return false;
18284            }
18285            if (ai == null) {
18286                reportStartInstrumentationFailureLocked(watcher, className,
18287                        "Unable to find instrumentation target package: " + ii.targetPackage);
18288                return false;
18289            }
18290            if (!ai.hasCode()) {
18291                reportStartInstrumentationFailureLocked(watcher, className,
18292                        "Instrumentation target has no code: " + ii.targetPackage);
18293                return false;
18294            }
18295
18296            int match = mContext.getPackageManager().checkSignatures(
18297                    ii.targetPackage, ii.packageName);
18298            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18299                String msg = "Permission Denial: starting instrumentation "
18300                        + className + " from pid="
18301                        + Binder.getCallingPid()
18302                        + ", uid=" + Binder.getCallingPid()
18303                        + " not allowed because package " + ii.packageName
18304                        + " does not have a signature matching the target "
18305                        + ii.targetPackage;
18306                reportStartInstrumentationFailureLocked(watcher, className, msg);
18307                throw new SecurityException(msg);
18308            }
18309
18310            final long origId = Binder.clearCallingIdentity();
18311            // Instrumentation can kill and relaunch even persistent processes
18312            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18313                    "start instr");
18314            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18315            app.instrumentationClass = className;
18316            app.instrumentationInfo = ai;
18317            app.instrumentationProfileFile = profileFile;
18318            app.instrumentationArguments = arguments;
18319            app.instrumentationWatcher = watcher;
18320            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18321            app.instrumentationResultClass = className;
18322            Binder.restoreCallingIdentity(origId);
18323        }
18324
18325        return true;
18326    }
18327
18328    /**
18329     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18330     * error to the logs, but if somebody is watching, send the report there too.  This enables
18331     * the "am" command to report errors with more information.
18332     *
18333     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18334     * @param cn The component name of the instrumentation.
18335     * @param report The error report.
18336     */
18337    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18338            ComponentName cn, String report) {
18339        Slog.w(TAG, report);
18340        if (watcher != null) {
18341            Bundle results = new Bundle();
18342            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18343            results.putString("Error", report);
18344            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18345        }
18346    }
18347
18348    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18349        if (app.instrumentationWatcher != null) {
18350            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18351                    app.instrumentationClass, resultCode, results);
18352        }
18353
18354        // Can't call out of the system process with a lock held, so post a message.
18355        if (app.instrumentationUiAutomationConnection != null) {
18356            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18357                    app.instrumentationUiAutomationConnection).sendToTarget();
18358        }
18359
18360        app.instrumentationWatcher = null;
18361        app.instrumentationUiAutomationConnection = null;
18362        app.instrumentationClass = null;
18363        app.instrumentationInfo = null;
18364        app.instrumentationProfileFile = null;
18365        app.instrumentationArguments = null;
18366
18367        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18368                "finished inst");
18369    }
18370
18371    public void finishInstrumentation(IApplicationThread target,
18372            int resultCode, Bundle results) {
18373        int userId = UserHandle.getCallingUserId();
18374        // Refuse possible leaked file descriptors
18375        if (results != null && results.hasFileDescriptors()) {
18376            throw new IllegalArgumentException("File descriptors passed in Intent");
18377        }
18378
18379        synchronized(this) {
18380            ProcessRecord app = getRecordForAppLocked(target);
18381            if (app == null) {
18382                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18383                return;
18384            }
18385            final long origId = Binder.clearCallingIdentity();
18386            finishInstrumentationLocked(app, resultCode, results);
18387            Binder.restoreCallingIdentity(origId);
18388        }
18389    }
18390
18391    // =========================================================
18392    // CONFIGURATION
18393    // =========================================================
18394
18395    public ConfigurationInfo getDeviceConfigurationInfo() {
18396        ConfigurationInfo config = new ConfigurationInfo();
18397        synchronized (this) {
18398            config.reqTouchScreen = mConfiguration.touchscreen;
18399            config.reqKeyboardType = mConfiguration.keyboard;
18400            config.reqNavigation = mConfiguration.navigation;
18401            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18402                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18403                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18404            }
18405            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18406                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18407                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18408            }
18409            config.reqGlEsVersion = GL_ES_VERSION;
18410        }
18411        return config;
18412    }
18413
18414    ActivityStack getFocusedStack() {
18415        return mStackSupervisor.getFocusedStack();
18416    }
18417
18418    @Override
18419    public int getFocusedStackId() throws RemoteException {
18420        ActivityStack focusedStack = getFocusedStack();
18421        if (focusedStack != null) {
18422            return focusedStack.getStackId();
18423        }
18424        return -1;
18425    }
18426
18427    public Configuration getConfiguration() {
18428        Configuration ci;
18429        synchronized(this) {
18430            ci = new Configuration(mConfiguration);
18431            ci.userSetLocale = false;
18432        }
18433        return ci;
18434    }
18435
18436    @Override
18437    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18438        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18439        synchronized (this) {
18440            mSuppressResizeConfigChanges = suppress;
18441        }
18442    }
18443
18444    @Override
18445    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18446        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18447        if (fromStackId == HOME_STACK_ID) {
18448            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18449        }
18450        synchronized (this) {
18451            final long origId = Binder.clearCallingIdentity();
18452            try {
18453                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18454            } finally {
18455                Binder.restoreCallingIdentity(origId);
18456            }
18457        }
18458    }
18459
18460    @Override
18461    public void updatePersistentConfiguration(Configuration values) {
18462        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18463                "updateConfiguration()");
18464        enforceWriteSettingsPermission("updateConfiguration()");
18465        if (values == null) {
18466            throw new NullPointerException("Configuration must not be null");
18467        }
18468
18469        int userId = UserHandle.getCallingUserId();
18470
18471        synchronized(this) {
18472            final long origId = Binder.clearCallingIdentity();
18473            updateConfigurationLocked(values, null, false, true, userId);
18474            Binder.restoreCallingIdentity(origId);
18475        }
18476    }
18477
18478    private void updateFontScaleIfNeeded() {
18479        final int currentUserId;
18480        synchronized(this) {
18481            currentUserId = mUserController.getCurrentUserIdLocked();
18482        }
18483        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18484                FONT_SCALE, 1.0f, currentUserId);
18485        if (mConfiguration.fontScale != scaleFactor) {
18486            final Configuration configuration = mWindowManager.computeNewConfiguration();
18487            configuration.fontScale = scaleFactor;
18488            updatePersistentConfiguration(configuration);
18489        }
18490    }
18491
18492    private void enforceWriteSettingsPermission(String func) {
18493        int uid = Binder.getCallingUid();
18494        if (uid == Process.ROOT_UID) {
18495            return;
18496        }
18497
18498        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18499                Settings.getPackageNameForUid(mContext, uid), false)) {
18500            return;
18501        }
18502
18503        String msg = "Permission Denial: " + func + " from pid="
18504                + Binder.getCallingPid()
18505                + ", uid=" + uid
18506                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18507        Slog.w(TAG, msg);
18508        throw new SecurityException(msg);
18509    }
18510
18511    public void updateConfiguration(Configuration values) {
18512        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18513                "updateConfiguration()");
18514
18515        synchronized(this) {
18516            if (values == null && mWindowManager != null) {
18517                // sentinel: fetch the current configuration from the window manager
18518                values = mWindowManager.computeNewConfiguration();
18519            }
18520
18521            if (mWindowManager != null) {
18522                mProcessList.applyDisplaySize(mWindowManager);
18523            }
18524
18525            final long origId = Binder.clearCallingIdentity();
18526            if (values != null) {
18527                Settings.System.clearConfiguration(values);
18528            }
18529            updateConfigurationLocked(values, null, false);
18530            Binder.restoreCallingIdentity(origId);
18531        }
18532    }
18533
18534    void updateUserConfigurationLocked() {
18535        Configuration configuration = new Configuration(mConfiguration);
18536        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18537                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18538        updateConfigurationLocked(configuration, null, false);
18539    }
18540
18541    boolean updateConfigurationLocked(Configuration values,
18542            ActivityRecord starting, boolean initLocale) {
18543        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18544        return updateConfigurationLocked(values, starting, initLocale, false,
18545                UserHandle.USER_NULL);
18546    }
18547
18548    // To cache the list of supported system locales
18549    private String[] mSupportedSystemLocales = null;
18550
18551    /**
18552     * Do either or both things: (1) change the current configuration, and (2)
18553     * make sure the given activity is running with the (now) current
18554     * configuration.  Returns true if the activity has been left running, or
18555     * false if <var>starting</var> is being destroyed to match the new
18556     * configuration.
18557     *
18558     * @param userId is only used when persistent parameter is set to true to persist configuration
18559     *               for that particular user
18560     */
18561    private boolean updateConfigurationLocked(Configuration values,
18562            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18563        int changes = 0;
18564
18565        if (mWindowManager != null) {
18566            mWindowManager.deferSurfaceLayout();
18567        }
18568        if (values != null) {
18569            Configuration newConfig = new Configuration(mConfiguration);
18570            changes = newConfig.updateFrom(values);
18571            if (changes != 0) {
18572                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18573                        "Updating configuration to: " + values);
18574
18575                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18576
18577                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18578                    final LocaleList locales = values.getLocales();
18579                    int bestLocaleIndex = 0;
18580                    if (locales.size() > 1) {
18581                        if (mSupportedSystemLocales == null) {
18582                            mSupportedSystemLocales =
18583                                    Resources.getSystem().getAssets().getLocales();
18584                        }
18585                        bestLocaleIndex = Math.max(0,
18586                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18587                    }
18588                    SystemProperties.set("persist.sys.locale",
18589                            locales.get(bestLocaleIndex).toLanguageTag());
18590                    LocaleList.setDefault(locales, bestLocaleIndex);
18591                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18592                            locales.get(bestLocaleIndex)));
18593                }
18594
18595                mConfigurationSeq++;
18596                if (mConfigurationSeq <= 0) {
18597                    mConfigurationSeq = 1;
18598                }
18599                newConfig.seq = mConfigurationSeq;
18600                mConfiguration = newConfig;
18601                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18602                mUsageStatsService.reportConfigurationChange(newConfig,
18603                        mUserController.getCurrentUserIdLocked());
18604                //mUsageStatsService.noteStartConfig(newConfig);
18605
18606                final Configuration configCopy = new Configuration(mConfiguration);
18607
18608                // TODO: If our config changes, should we auto dismiss any currently
18609                // showing dialogs?
18610                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18611
18612                AttributeCache ac = AttributeCache.instance();
18613                if (ac != null) {
18614                    ac.updateConfiguration(configCopy);
18615                }
18616
18617                // Make sure all resources in our process are updated
18618                // right now, so that anyone who is going to retrieve
18619                // resource values after we return will be sure to get
18620                // the new ones.  This is especially important during
18621                // boot, where the first config change needs to guarantee
18622                // all resources have that config before following boot
18623                // code is executed.
18624                mSystemThread.applyConfigurationToResources(configCopy);
18625
18626                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18627                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18628                    msg.obj = new Configuration(configCopy);
18629                    msg.arg1 = userId;
18630                    mHandler.sendMessage(msg);
18631                }
18632
18633                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18634                if (isDensityChange) {
18635                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18636                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18637                }
18638
18639                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18640                    ProcessRecord app = mLruProcesses.get(i);
18641                    try {
18642                        if (app.thread != null) {
18643                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18644                                    + app.processName + " new config " + mConfiguration);
18645                            app.thread.scheduleConfigurationChanged(configCopy);
18646                        }
18647                    } catch (Exception e) {
18648                    }
18649                }
18650                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18651                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18652                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18653                        | Intent.FLAG_RECEIVER_FOREGROUND);
18654                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18655                        null, AppOpsManager.OP_NONE, null, false, false,
18656                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18657                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18658                    // Tell the shortcut manager that the system locale changed.  It needs to know
18659                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18660                    // we "push" from here, rather than having the service listen to the broadcast.
18661                    final ShortcutServiceInternal shortcutService =
18662                            LocalServices.getService(ShortcutServiceInternal.class);
18663                    if (shortcutService != null) {
18664                        shortcutService.onSystemLocaleChangedNoLock();
18665                    }
18666
18667                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18668                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18669                    if (!mProcessesReady) {
18670                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18671                    }
18672                    broadcastIntentLocked(null, null, intent,
18673                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18674                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18675                }
18676            }
18677            // Update the configuration with WM first and check if any of the stacks need to be
18678            // resized due to the configuration change. If so, resize the stacks now and do any
18679            // relaunches if necessary. This way we don't need to relaunch again below in
18680            // ensureActivityConfigurationLocked().
18681            if (mWindowManager != null) {
18682                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18683                if (resizedStacks != null) {
18684                    for (int stackId : resizedStacks) {
18685                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18686                        mStackSupervisor.resizeStackLocked(
18687                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18688                    }
18689                }
18690            }
18691        }
18692
18693        boolean kept = true;
18694        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18695        // mainStack is null during startup.
18696        if (mainStack != null) {
18697            if (changes != 0 && starting == null) {
18698                // If the configuration changed, and the caller is not already
18699                // in the process of starting an activity, then find the top
18700                // activity to check if its configuration needs to change.
18701                starting = mainStack.topRunningActivityLocked();
18702            }
18703
18704            if (starting != null) {
18705                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18706                // And we need to make sure at this point that all other activities
18707                // are made visible with the correct configuration.
18708                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18709                        !PRESERVE_WINDOWS);
18710            }
18711        }
18712        if (mWindowManager != null) {
18713            mWindowManager.continueSurfaceLayout();
18714        }
18715        return kept;
18716    }
18717
18718    /**
18719     * Decide based on the configuration whether we should shouw the ANR,
18720     * crash, etc dialogs.  The idea is that if there is no affordence to
18721     * press the on-screen buttons, or the user experience would be more
18722     * greatly impacted than the crash itself, we shouldn't show the dialog.
18723     *
18724     * A thought: SystemUI might also want to get told about this, the Power
18725     * dialog / global actions also might want different behaviors.
18726     */
18727    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18728        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18729                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18730                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18731        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18732        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18733                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18734        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18735    }
18736
18737    @Override
18738    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18739        synchronized (this) {
18740            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18741            if (srec != null) {
18742                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18743            }
18744        }
18745        return false;
18746    }
18747
18748    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18749            Intent resultData) {
18750
18751        synchronized (this) {
18752            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18753            if (r != null) {
18754                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18755            }
18756            return false;
18757        }
18758    }
18759
18760    public int getLaunchedFromUid(IBinder activityToken) {
18761        ActivityRecord srec;
18762        synchronized (this) {
18763            srec = ActivityRecord.forTokenLocked(activityToken);
18764        }
18765        if (srec == null) {
18766            return -1;
18767        }
18768        return srec.launchedFromUid;
18769    }
18770
18771    public String getLaunchedFromPackage(IBinder activityToken) {
18772        ActivityRecord srec;
18773        synchronized (this) {
18774            srec = ActivityRecord.forTokenLocked(activityToken);
18775        }
18776        if (srec == null) {
18777            return null;
18778        }
18779        return srec.launchedFromPackage;
18780    }
18781
18782    // =========================================================
18783    // LIFETIME MANAGEMENT
18784    // =========================================================
18785
18786    // Returns which broadcast queue the app is the current [or imminent] receiver
18787    // on, or 'null' if the app is not an active broadcast recipient.
18788    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18789        BroadcastRecord r = app.curReceiver;
18790        if (r != null) {
18791            return r.queue;
18792        }
18793
18794        // It's not the current receiver, but it might be starting up to become one
18795        synchronized (this) {
18796            for (BroadcastQueue queue : mBroadcastQueues) {
18797                r = queue.mPendingBroadcast;
18798                if (r != null && r.curApp == app) {
18799                    // found it; report which queue it's in
18800                    return queue;
18801                }
18802            }
18803        }
18804
18805        return null;
18806    }
18807
18808    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18809            int targetUid, ComponentName targetComponent, String targetProcess) {
18810        if (!mTrackingAssociations) {
18811            return null;
18812        }
18813        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18814                = mAssociations.get(targetUid);
18815        if (components == null) {
18816            components = new ArrayMap<>();
18817            mAssociations.put(targetUid, components);
18818        }
18819        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18820        if (sourceUids == null) {
18821            sourceUids = new SparseArray<>();
18822            components.put(targetComponent, sourceUids);
18823        }
18824        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18825        if (sourceProcesses == null) {
18826            sourceProcesses = new ArrayMap<>();
18827            sourceUids.put(sourceUid, sourceProcesses);
18828        }
18829        Association ass = sourceProcesses.get(sourceProcess);
18830        if (ass == null) {
18831            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18832                    targetProcess);
18833            sourceProcesses.put(sourceProcess, ass);
18834        }
18835        ass.mCount++;
18836        ass.mNesting++;
18837        if (ass.mNesting == 1) {
18838            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18839            ass.mLastState = sourceState;
18840        }
18841        return ass;
18842    }
18843
18844    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18845            ComponentName targetComponent) {
18846        if (!mTrackingAssociations) {
18847            return;
18848        }
18849        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18850                = mAssociations.get(targetUid);
18851        if (components == null) {
18852            return;
18853        }
18854        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18855        if (sourceUids == null) {
18856            return;
18857        }
18858        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18859        if (sourceProcesses == null) {
18860            return;
18861        }
18862        Association ass = sourceProcesses.get(sourceProcess);
18863        if (ass == null || ass.mNesting <= 0) {
18864            return;
18865        }
18866        ass.mNesting--;
18867        if (ass.mNesting == 0) {
18868            long uptime = SystemClock.uptimeMillis();
18869            ass.mTime += uptime - ass.mStartTime;
18870            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18871                    += uptime - ass.mLastStateUptime;
18872            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18873        }
18874    }
18875
18876    private void noteUidProcessState(final int uid, final int state) {
18877        mBatteryStatsService.noteUidProcessState(uid, state);
18878        if (mTrackingAssociations) {
18879            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18880                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18881                        = mAssociations.valueAt(i1);
18882                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18883                    SparseArray<ArrayMap<String, Association>> sourceUids
18884                            = targetComponents.valueAt(i2);
18885                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18886                    if (sourceProcesses != null) {
18887                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18888                            Association ass = sourceProcesses.valueAt(i4);
18889                            if (ass.mNesting >= 1) {
18890                                // currently associated
18891                                long uptime = SystemClock.uptimeMillis();
18892                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18893                                        += uptime - ass.mLastStateUptime;
18894                                ass.mLastState = state;
18895                                ass.mLastStateUptime = uptime;
18896                            }
18897                        }
18898                    }
18899                }
18900            }
18901        }
18902    }
18903
18904    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18905            boolean doingAll, long now) {
18906        if (mAdjSeq == app.adjSeq) {
18907            // This adjustment has already been computed.
18908            return app.curRawAdj;
18909        }
18910
18911        if (app.thread == null) {
18912            app.adjSeq = mAdjSeq;
18913            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18914            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18915            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18916        }
18917
18918        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18919        app.adjSource = null;
18920        app.adjTarget = null;
18921        app.empty = false;
18922        app.cached = false;
18923
18924        final int activitiesSize = app.activities.size();
18925
18926        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18927            // The max adjustment doesn't allow this app to be anything
18928            // below foreground, so it is not worth doing work for it.
18929            app.adjType = "fixed";
18930            app.adjSeq = mAdjSeq;
18931            app.curRawAdj = app.maxAdj;
18932            app.foregroundActivities = false;
18933            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18934            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18935            // System processes can do UI, and when they do we want to have
18936            // them trim their memory after the user leaves the UI.  To
18937            // facilitate this, here we need to determine whether or not it
18938            // is currently showing UI.
18939            app.systemNoUi = true;
18940            if (app == TOP_APP) {
18941                app.systemNoUi = false;
18942                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18943                app.adjType = "pers-top-activity";
18944            } else if (activitiesSize > 0) {
18945                for (int j = 0; j < activitiesSize; j++) {
18946                    final ActivityRecord r = app.activities.get(j);
18947                    if (r.visible) {
18948                        app.systemNoUi = false;
18949                    }
18950                }
18951            }
18952            if (!app.systemNoUi) {
18953                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18954            }
18955            return (app.curAdj=app.maxAdj);
18956        }
18957
18958        app.systemNoUi = false;
18959
18960        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18961
18962        // Determine the importance of the process, starting with most
18963        // important to least, and assign an appropriate OOM adjustment.
18964        int adj;
18965        int schedGroup;
18966        int procState;
18967        boolean foregroundActivities = false;
18968        BroadcastQueue queue;
18969        if (app == TOP_APP) {
18970            // The last app on the list is the foreground app.
18971            adj = ProcessList.FOREGROUND_APP_ADJ;
18972            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18973            app.adjType = "top-activity";
18974            foregroundActivities = true;
18975            procState = PROCESS_STATE_CUR_TOP;
18976        } else if (app.instrumentationClass != null) {
18977            // Don't want to kill running instrumentation.
18978            adj = ProcessList.FOREGROUND_APP_ADJ;
18979            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18980            app.adjType = "instrumentation";
18981            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18982        } else if ((queue = isReceivingBroadcast(app)) != null) {
18983            // An app that is currently receiving a broadcast also
18984            // counts as being in the foreground for OOM killer purposes.
18985            // It's placed in a sched group based on the nature of the
18986            // broadcast as reflected by which queue it's active in.
18987            adj = ProcessList.FOREGROUND_APP_ADJ;
18988            schedGroup = (queue == mFgBroadcastQueue)
18989                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18990            app.adjType = "broadcast";
18991            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18992        } else if (app.executingServices.size() > 0) {
18993            // An app that is currently executing a service callback also
18994            // counts as being in the foreground.
18995            adj = ProcessList.FOREGROUND_APP_ADJ;
18996            schedGroup = app.execServicesFg ?
18997                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18998            app.adjType = "exec-service";
18999            procState = ActivityManager.PROCESS_STATE_SERVICE;
19000            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19001        } else {
19002            // As far as we know the process is empty.  We may change our mind later.
19003            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19004            // At this point we don't actually know the adjustment.  Use the cached adj
19005            // value that the caller wants us to.
19006            adj = cachedAdj;
19007            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19008            app.cached = true;
19009            app.empty = true;
19010            app.adjType = "cch-empty";
19011        }
19012
19013        // Examine all activities if not already foreground.
19014        if (!foregroundActivities && activitiesSize > 0) {
19015            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19016            for (int j = 0; j < activitiesSize; j++) {
19017                final ActivityRecord r = app.activities.get(j);
19018                if (r.app != app) {
19019                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19020                            + " instead of expected " + app);
19021                    if (r.app == null || (r.app.uid == app.uid)) {
19022                        // Only fix things up when they look sane
19023                        r.app = app;
19024                    } else {
19025                        continue;
19026                    }
19027                }
19028                if (r.visible) {
19029                    // App has a visible activity; only upgrade adjustment.
19030                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19031                        adj = ProcessList.VISIBLE_APP_ADJ;
19032                        app.adjType = "visible";
19033                    }
19034                    if (procState > PROCESS_STATE_CUR_TOP) {
19035                        procState = PROCESS_STATE_CUR_TOP;
19036                    }
19037                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19038                    app.cached = false;
19039                    app.empty = false;
19040                    foregroundActivities = true;
19041                    if (r.task != null && minLayer > 0) {
19042                        final int layer = r.task.mLayerRank;
19043                        if (layer >= 0 && minLayer > layer) {
19044                            minLayer = layer;
19045                        }
19046                    }
19047                    break;
19048                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19049                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19050                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19051                        app.adjType = "pausing";
19052                    }
19053                    if (procState > PROCESS_STATE_CUR_TOP) {
19054                        procState = PROCESS_STATE_CUR_TOP;
19055                    }
19056                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19057                    app.cached = false;
19058                    app.empty = false;
19059                    foregroundActivities = true;
19060                } else if (r.state == ActivityState.STOPPING) {
19061                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19062                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19063                        app.adjType = "stopping";
19064                    }
19065                    // For the process state, we will at this point consider the
19066                    // process to be cached.  It will be cached either as an activity
19067                    // or empty depending on whether the activity is finishing.  We do
19068                    // this so that we can treat the process as cached for purposes of
19069                    // memory trimming (determing current memory level, trim command to
19070                    // send to process) since there can be an arbitrary number of stopping
19071                    // processes and they should soon all go into the cached state.
19072                    if (!r.finishing) {
19073                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19074                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19075                        }
19076                    }
19077                    app.cached = false;
19078                    app.empty = false;
19079                    foregroundActivities = true;
19080                } else {
19081                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19082                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19083                        app.adjType = "cch-act";
19084                    }
19085                }
19086            }
19087            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19088                adj += minLayer;
19089            }
19090        }
19091
19092        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19093                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19094            if (app.foregroundServices) {
19095                // The user is aware of this app, so make it visible.
19096                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19097                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19098                app.cached = false;
19099                app.adjType = "fg-service";
19100                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19101            } else if (app.forcingToForeground != null) {
19102                // The user is aware of this app, so make it visible.
19103                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19104                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19105                app.cached = false;
19106                app.adjType = "force-fg";
19107                app.adjSource = app.forcingToForeground;
19108                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19109            }
19110        }
19111
19112        if (app == mHeavyWeightProcess) {
19113            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19114                // We don't want to kill the current heavy-weight process.
19115                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19116                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19117                app.cached = false;
19118                app.adjType = "heavy";
19119            }
19120            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19121                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19122            }
19123        }
19124
19125        if (app == mHomeProcess) {
19126            if (adj > ProcessList.HOME_APP_ADJ) {
19127                // This process is hosting what we currently consider to be the
19128                // home app, so we don't want to let it go into the background.
19129                adj = ProcessList.HOME_APP_ADJ;
19130                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19131                app.cached = false;
19132                app.adjType = "home";
19133            }
19134            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19135                procState = ActivityManager.PROCESS_STATE_HOME;
19136            }
19137        }
19138
19139        if (app == mPreviousProcess && app.activities.size() > 0) {
19140            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19141                // This was the previous process that showed UI to the user.
19142                // We want to try to keep it around more aggressively, to give
19143                // a good experience around switching between two apps.
19144                adj = ProcessList.PREVIOUS_APP_ADJ;
19145                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19146                app.cached = false;
19147                app.adjType = "previous";
19148            }
19149            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19150                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19151            }
19152        }
19153
19154        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19155                + " reason=" + app.adjType);
19156
19157        // By default, we use the computed adjustment.  It may be changed if
19158        // there are applications dependent on our services or providers, but
19159        // this gives us a baseline and makes sure we don't get into an
19160        // infinite recursion.
19161        app.adjSeq = mAdjSeq;
19162        app.curRawAdj = adj;
19163        app.hasStartedServices = false;
19164
19165        if (mBackupTarget != null && app == mBackupTarget.app) {
19166            // If possible we want to avoid killing apps while they're being backed up
19167            if (adj > ProcessList.BACKUP_APP_ADJ) {
19168                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19169                adj = ProcessList.BACKUP_APP_ADJ;
19170                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19171                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19172                }
19173                app.adjType = "backup";
19174                app.cached = false;
19175            }
19176            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19177                procState = ActivityManager.PROCESS_STATE_BACKUP;
19178            }
19179        }
19180
19181        boolean mayBeTop = false;
19182
19183        for (int is = app.services.size()-1;
19184                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19185                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19186                        || procState > ActivityManager.PROCESS_STATE_TOP);
19187                is--) {
19188            ServiceRecord s = app.services.valueAt(is);
19189            if (s.startRequested) {
19190                app.hasStartedServices = true;
19191                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19192                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19193                }
19194                if (app.hasShownUi && app != mHomeProcess) {
19195                    // If this process has shown some UI, let it immediately
19196                    // go to the LRU list because it may be pretty heavy with
19197                    // UI stuff.  We'll tag it with a label just to help
19198                    // debug and understand what is going on.
19199                    if (adj > ProcessList.SERVICE_ADJ) {
19200                        app.adjType = "cch-started-ui-services";
19201                    }
19202                } else {
19203                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19204                        // This service has seen some activity within
19205                        // recent memory, so we will keep its process ahead
19206                        // of the background processes.
19207                        if (adj > ProcessList.SERVICE_ADJ) {
19208                            adj = ProcessList.SERVICE_ADJ;
19209                            app.adjType = "started-services";
19210                            app.cached = false;
19211                        }
19212                    }
19213                    // If we have let the service slide into the background
19214                    // state, still have some text describing what it is doing
19215                    // even though the service no longer has an impact.
19216                    if (adj > ProcessList.SERVICE_ADJ) {
19217                        app.adjType = "cch-started-services";
19218                    }
19219                }
19220            }
19221
19222            app.whitelistManager = false;
19223
19224            for (int conni = s.connections.size()-1;
19225                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19226                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19227                            || procState > ActivityManager.PROCESS_STATE_TOP);
19228                    conni--) {
19229                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19230                for (int i = 0;
19231                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19232                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19233                                || procState > ActivityManager.PROCESS_STATE_TOP);
19234                        i++) {
19235                    // XXX should compute this based on the max of
19236                    // all connected clients.
19237                    ConnectionRecord cr = clist.get(i);
19238                    if (cr.binding.client == app) {
19239                        // Binding to ourself is not interesting.
19240                        continue;
19241                    }
19242                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19243                        app.whitelistManager = true;
19244                    }
19245
19246                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19247                        ProcessRecord client = cr.binding.client;
19248                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19249                                TOP_APP, doingAll, now);
19250                        int clientProcState = client.curProcState;
19251                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19252                            // If the other app is cached for any reason, for purposes here
19253                            // we are going to consider it empty.  The specific cached state
19254                            // doesn't propagate except under certain conditions.
19255                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19256                        }
19257                        String adjType = null;
19258                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19259                            // Not doing bind OOM management, so treat
19260                            // this guy more like a started service.
19261                            if (app.hasShownUi && app != mHomeProcess) {
19262                                // If this process has shown some UI, let it immediately
19263                                // go to the LRU list because it may be pretty heavy with
19264                                // UI stuff.  We'll tag it with a label just to help
19265                                // debug and understand what is going on.
19266                                if (adj > clientAdj) {
19267                                    adjType = "cch-bound-ui-services";
19268                                }
19269                                app.cached = false;
19270                                clientAdj = adj;
19271                                clientProcState = procState;
19272                            } else {
19273                                if (now >= (s.lastActivity
19274                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19275                                    // This service has not seen activity within
19276                                    // recent memory, so allow it to drop to the
19277                                    // LRU list if there is no other reason to keep
19278                                    // it around.  We'll also tag it with a label just
19279                                    // to help debug and undertand what is going on.
19280                                    if (adj > clientAdj) {
19281                                        adjType = "cch-bound-services";
19282                                    }
19283                                    clientAdj = adj;
19284                                }
19285                            }
19286                        }
19287                        if (adj > clientAdj) {
19288                            // If this process has recently shown UI, and
19289                            // the process that is binding to it is less
19290                            // important than being visible, then we don't
19291                            // care about the binding as much as we care
19292                            // about letting this process get into the LRU
19293                            // list to be killed and restarted if needed for
19294                            // memory.
19295                            if (app.hasShownUi && app != mHomeProcess
19296                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19297                                adjType = "cch-bound-ui-services";
19298                            } else {
19299                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19300                                        |Context.BIND_IMPORTANT)) != 0) {
19301                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19302                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19303                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19304                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19305                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19306                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19307                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19308                                    adj = clientAdj;
19309                                } else {
19310                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19311                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19312                                    }
19313                                }
19314                                if (!client.cached) {
19315                                    app.cached = false;
19316                                }
19317                                adjType = "service";
19318                            }
19319                        }
19320                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19321                            // This will treat important bound services identically to
19322                            // the top app, which may behave differently than generic
19323                            // foreground work.
19324                            if (client.curSchedGroup > schedGroup) {
19325                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19326                                    schedGroup = client.curSchedGroup;
19327                                } else {
19328                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19329                                }
19330                            }
19331                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19332                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19333                                    // Special handling of clients who are in the top state.
19334                                    // We *may* want to consider this process to be in the
19335                                    // top state as well, but only if there is not another
19336                                    // reason for it to be running.  Being on the top is a
19337                                    // special state, meaning you are specifically running
19338                                    // for the current top app.  If the process is already
19339                                    // running in the background for some other reason, it
19340                                    // is more important to continue considering it to be
19341                                    // in the background state.
19342                                    mayBeTop = true;
19343                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19344                                } else {
19345                                    // Special handling for above-top states (persistent
19346                                    // processes).  These should not bring the current process
19347                                    // into the top state, since they are not on top.  Instead
19348                                    // give them the best state after that.
19349                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19350                                        clientProcState =
19351                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19352                                    } else if (mWakefulness
19353                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19354                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19355                                                    != 0) {
19356                                        clientProcState =
19357                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19358                                    } else {
19359                                        clientProcState =
19360                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19361                                    }
19362                                }
19363                            }
19364                        } else {
19365                            if (clientProcState <
19366                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19367                                clientProcState =
19368                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19369                            }
19370                        }
19371                        if (procState > clientProcState) {
19372                            procState = clientProcState;
19373                        }
19374                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19375                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19376                            app.pendingUiClean = true;
19377                        }
19378                        if (adjType != null) {
19379                            app.adjType = adjType;
19380                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19381                                    .REASON_SERVICE_IN_USE;
19382                            app.adjSource = cr.binding.client;
19383                            app.adjSourceProcState = clientProcState;
19384                            app.adjTarget = s.name;
19385                        }
19386                    }
19387                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19388                        app.treatLikeActivity = true;
19389                    }
19390                    final ActivityRecord a = cr.activity;
19391                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19392                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19393                            (a.visible || a.state == ActivityState.RESUMED ||
19394                             a.state == ActivityState.PAUSING)) {
19395                            adj = ProcessList.FOREGROUND_APP_ADJ;
19396                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19397                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19398                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19399                                } else {
19400                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19401                                }
19402                            }
19403                            app.cached = false;
19404                            app.adjType = "service";
19405                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19406                                    .REASON_SERVICE_IN_USE;
19407                            app.adjSource = a;
19408                            app.adjSourceProcState = procState;
19409                            app.adjTarget = s.name;
19410                        }
19411                    }
19412                }
19413            }
19414        }
19415
19416        for (int provi = app.pubProviders.size()-1;
19417                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19418                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19419                        || procState > ActivityManager.PROCESS_STATE_TOP);
19420                provi--) {
19421            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19422            for (int i = cpr.connections.size()-1;
19423                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19424                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19425                            || procState > ActivityManager.PROCESS_STATE_TOP);
19426                    i--) {
19427                ContentProviderConnection conn = cpr.connections.get(i);
19428                ProcessRecord client = conn.client;
19429                if (client == app) {
19430                    // Being our own client is not interesting.
19431                    continue;
19432                }
19433                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19434                int clientProcState = client.curProcState;
19435                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19436                    // If the other app is cached for any reason, for purposes here
19437                    // we are going to consider it empty.
19438                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19439                }
19440                if (adj > clientAdj) {
19441                    if (app.hasShownUi && app != mHomeProcess
19442                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19443                        app.adjType = "cch-ui-provider";
19444                    } else {
19445                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19446                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19447                        app.adjType = "provider";
19448                    }
19449                    app.cached &= client.cached;
19450                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19451                            .REASON_PROVIDER_IN_USE;
19452                    app.adjSource = client;
19453                    app.adjSourceProcState = clientProcState;
19454                    app.adjTarget = cpr.name;
19455                }
19456                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19457                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19458                        // Special handling of clients who are in the top state.
19459                        // We *may* want to consider this process to be in the
19460                        // top state as well, but only if there is not another
19461                        // reason for it to be running.  Being on the top is a
19462                        // special state, meaning you are specifically running
19463                        // for the current top app.  If the process is already
19464                        // running in the background for some other reason, it
19465                        // is more important to continue considering it to be
19466                        // in the background state.
19467                        mayBeTop = true;
19468                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19469                    } else {
19470                        // Special handling for above-top states (persistent
19471                        // processes).  These should not bring the current process
19472                        // into the top state, since they are not on top.  Instead
19473                        // give them the best state after that.
19474                        clientProcState =
19475                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19476                    }
19477                }
19478                if (procState > clientProcState) {
19479                    procState = clientProcState;
19480                }
19481                if (client.curSchedGroup > schedGroup) {
19482                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19483                }
19484            }
19485            // If the provider has external (non-framework) process
19486            // dependencies, ensure that its adjustment is at least
19487            // FOREGROUND_APP_ADJ.
19488            if (cpr.hasExternalProcessHandles()) {
19489                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19490                    adj = ProcessList.FOREGROUND_APP_ADJ;
19491                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19492                    app.cached = false;
19493                    app.adjType = "provider";
19494                    app.adjTarget = cpr.name;
19495                }
19496                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19497                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19498                }
19499            }
19500        }
19501
19502        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19503            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19504                adj = ProcessList.PREVIOUS_APP_ADJ;
19505                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19506                app.cached = false;
19507                app.adjType = "provider";
19508            }
19509            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19510                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19511            }
19512        }
19513
19514        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19515            // A client of one of our services or providers is in the top state.  We
19516            // *may* want to be in the top state, but not if we are already running in
19517            // the background for some other reason.  For the decision here, we are going
19518            // to pick out a few specific states that we want to remain in when a client
19519            // is top (states that tend to be longer-term) and otherwise allow it to go
19520            // to the top state.
19521            switch (procState) {
19522                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19523                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19524                case ActivityManager.PROCESS_STATE_SERVICE:
19525                    // These all are longer-term states, so pull them up to the top
19526                    // of the background states, but not all the way to the top state.
19527                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19528                    break;
19529                default:
19530                    // Otherwise, top is a better choice, so take it.
19531                    procState = ActivityManager.PROCESS_STATE_TOP;
19532                    break;
19533            }
19534        }
19535
19536        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19537            if (app.hasClientActivities) {
19538                // This is a cached process, but with client activities.  Mark it so.
19539                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19540                app.adjType = "cch-client-act";
19541            } else if (app.treatLikeActivity) {
19542                // This is a cached process, but somebody wants us to treat it like it has
19543                // an activity, okay!
19544                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19545                app.adjType = "cch-as-act";
19546            }
19547        }
19548
19549        if (adj == ProcessList.SERVICE_ADJ) {
19550            if (doingAll) {
19551                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19552                mNewNumServiceProcs++;
19553                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19554                if (!app.serviceb) {
19555                    // This service isn't far enough down on the LRU list to
19556                    // normally be a B service, but if we are low on RAM and it
19557                    // is large we want to force it down since we would prefer to
19558                    // keep launcher over it.
19559                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19560                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19561                        app.serviceHighRam = true;
19562                        app.serviceb = true;
19563                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19564                    } else {
19565                        mNewNumAServiceProcs++;
19566                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19567                    }
19568                } else {
19569                    app.serviceHighRam = false;
19570                }
19571            }
19572            if (app.serviceb) {
19573                adj = ProcessList.SERVICE_B_ADJ;
19574            }
19575        }
19576
19577        app.curRawAdj = adj;
19578
19579        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19580        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19581        if (adj > app.maxAdj) {
19582            adj = app.maxAdj;
19583            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19584                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19585            }
19586        }
19587
19588        // Do final modification to adj.  Everything we do between here and applying
19589        // the final setAdj must be done in this function, because we will also use
19590        // it when computing the final cached adj later.  Note that we don't need to
19591        // worry about this for max adj above, since max adj will always be used to
19592        // keep it out of the cached vaues.
19593        app.curAdj = app.modifyRawOomAdj(adj);
19594        app.curSchedGroup = schedGroup;
19595        app.curProcState = procState;
19596        app.foregroundActivities = foregroundActivities;
19597
19598        return app.curRawAdj;
19599    }
19600
19601    /**
19602     * Record new PSS sample for a process.
19603     */
19604    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19605            long now) {
19606        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19607                swapPss * 1024);
19608        proc.lastPssTime = now;
19609        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19610        if (DEBUG_PSS) Slog.d(TAG_PSS,
19611                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19612                + " state=" + ProcessList.makeProcStateString(procState));
19613        if (proc.initialIdlePss == 0) {
19614            proc.initialIdlePss = pss;
19615        }
19616        proc.lastPss = pss;
19617        proc.lastSwapPss = swapPss;
19618        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19619            proc.lastCachedPss = pss;
19620            proc.lastCachedSwapPss = swapPss;
19621        }
19622
19623        final SparseArray<Pair<Long, String>> watchUids
19624                = mMemWatchProcesses.getMap().get(proc.processName);
19625        Long check = null;
19626        if (watchUids != null) {
19627            Pair<Long, String> val = watchUids.get(proc.uid);
19628            if (val == null) {
19629                val = watchUids.get(0);
19630            }
19631            if (val != null) {
19632                check = val.first;
19633            }
19634        }
19635        if (check != null) {
19636            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19637                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19638                if (!isDebuggable) {
19639                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19640                        isDebuggable = true;
19641                    }
19642                }
19643                if (isDebuggable) {
19644                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19645                    final ProcessRecord myProc = proc;
19646                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19647                    mMemWatchDumpProcName = proc.processName;
19648                    mMemWatchDumpFile = heapdumpFile.toString();
19649                    mMemWatchDumpPid = proc.pid;
19650                    mMemWatchDumpUid = proc.uid;
19651                    BackgroundThread.getHandler().post(new Runnable() {
19652                        @Override
19653                        public void run() {
19654                            revokeUriPermission(ActivityThread.currentActivityThread()
19655                                            .getApplicationThread(),
19656                                    DumpHeapActivity.JAVA_URI,
19657                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19658                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19659                                    UserHandle.myUserId());
19660                            ParcelFileDescriptor fd = null;
19661                            try {
19662                                heapdumpFile.delete();
19663                                fd = ParcelFileDescriptor.open(heapdumpFile,
19664                                        ParcelFileDescriptor.MODE_CREATE |
19665                                                ParcelFileDescriptor.MODE_TRUNCATE |
19666                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19667                                                ParcelFileDescriptor.MODE_APPEND);
19668                                IApplicationThread thread = myProc.thread;
19669                                if (thread != null) {
19670                                    try {
19671                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19672                                                "Requesting dump heap from "
19673                                                + myProc + " to " + heapdumpFile);
19674                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19675                                    } catch (RemoteException e) {
19676                                    }
19677                                }
19678                            } catch (FileNotFoundException e) {
19679                                e.printStackTrace();
19680                            } finally {
19681                                if (fd != null) {
19682                                    try {
19683                                        fd.close();
19684                                    } catch (IOException e) {
19685                                    }
19686                                }
19687                            }
19688                        }
19689                    });
19690                } else {
19691                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19692                            + ", but debugging not enabled");
19693                }
19694            }
19695        }
19696    }
19697
19698    /**
19699     * Schedule PSS collection of a process.
19700     */
19701    void requestPssLocked(ProcessRecord proc, int procState) {
19702        if (mPendingPssProcesses.contains(proc)) {
19703            return;
19704        }
19705        if (mPendingPssProcesses.size() == 0) {
19706            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19707        }
19708        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19709        proc.pssProcState = procState;
19710        mPendingPssProcesses.add(proc);
19711    }
19712
19713    /**
19714     * Schedule PSS collection of all processes.
19715     */
19716    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19717        if (!always) {
19718            if (now < (mLastFullPssTime +
19719                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19720                return;
19721            }
19722        }
19723        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19724        mLastFullPssTime = now;
19725        mFullPssPending = true;
19726        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19727        mPendingPssProcesses.clear();
19728        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19729            ProcessRecord app = mLruProcesses.get(i);
19730            if (app.thread == null
19731                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19732                continue;
19733            }
19734            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19735                app.pssProcState = app.setProcState;
19736                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19737                        mTestPssMode, isSleeping(), now);
19738                mPendingPssProcesses.add(app);
19739            }
19740        }
19741        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19742    }
19743
19744    public void setTestPssMode(boolean enabled) {
19745        synchronized (this) {
19746            mTestPssMode = enabled;
19747            if (enabled) {
19748                // Whenever we enable the mode, we want to take a snapshot all of current
19749                // process mem use.
19750                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19751            }
19752        }
19753    }
19754
19755    /**
19756     * Ask a given process to GC right now.
19757     */
19758    final void performAppGcLocked(ProcessRecord app) {
19759        try {
19760            app.lastRequestedGc = SystemClock.uptimeMillis();
19761            if (app.thread != null) {
19762                if (app.reportLowMemory) {
19763                    app.reportLowMemory = false;
19764                    app.thread.scheduleLowMemory();
19765                } else {
19766                    app.thread.processInBackground();
19767                }
19768            }
19769        } catch (Exception e) {
19770            // whatever.
19771        }
19772    }
19773
19774    /**
19775     * Returns true if things are idle enough to perform GCs.
19776     */
19777    private final boolean canGcNowLocked() {
19778        boolean processingBroadcasts = false;
19779        for (BroadcastQueue q : mBroadcastQueues) {
19780            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19781                processingBroadcasts = true;
19782            }
19783        }
19784        return !processingBroadcasts
19785                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19786    }
19787
19788    /**
19789     * Perform GCs on all processes that are waiting for it, but only
19790     * if things are idle.
19791     */
19792    final void performAppGcsLocked() {
19793        final int N = mProcessesToGc.size();
19794        if (N <= 0) {
19795            return;
19796        }
19797        if (canGcNowLocked()) {
19798            while (mProcessesToGc.size() > 0) {
19799                ProcessRecord proc = mProcessesToGc.remove(0);
19800                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19801                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19802                            <= SystemClock.uptimeMillis()) {
19803                        // To avoid spamming the system, we will GC processes one
19804                        // at a time, waiting a few seconds between each.
19805                        performAppGcLocked(proc);
19806                        scheduleAppGcsLocked();
19807                        return;
19808                    } else {
19809                        // It hasn't been long enough since we last GCed this
19810                        // process...  put it in the list to wait for its time.
19811                        addProcessToGcListLocked(proc);
19812                        break;
19813                    }
19814                }
19815            }
19816
19817            scheduleAppGcsLocked();
19818        }
19819    }
19820
19821    /**
19822     * If all looks good, perform GCs on all processes waiting for them.
19823     */
19824    final void performAppGcsIfAppropriateLocked() {
19825        if (canGcNowLocked()) {
19826            performAppGcsLocked();
19827            return;
19828        }
19829        // Still not idle, wait some more.
19830        scheduleAppGcsLocked();
19831    }
19832
19833    /**
19834     * Schedule the execution of all pending app GCs.
19835     */
19836    final void scheduleAppGcsLocked() {
19837        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19838
19839        if (mProcessesToGc.size() > 0) {
19840            // Schedule a GC for the time to the next process.
19841            ProcessRecord proc = mProcessesToGc.get(0);
19842            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19843
19844            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19845            long now = SystemClock.uptimeMillis();
19846            if (when < (now+GC_TIMEOUT)) {
19847                when = now + GC_TIMEOUT;
19848            }
19849            mHandler.sendMessageAtTime(msg, when);
19850        }
19851    }
19852
19853    /**
19854     * Add a process to the array of processes waiting to be GCed.  Keeps the
19855     * list in sorted order by the last GC time.  The process can't already be
19856     * on the list.
19857     */
19858    final void addProcessToGcListLocked(ProcessRecord proc) {
19859        boolean added = false;
19860        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19861            if (mProcessesToGc.get(i).lastRequestedGc <
19862                    proc.lastRequestedGc) {
19863                added = true;
19864                mProcessesToGc.add(i+1, proc);
19865                break;
19866            }
19867        }
19868        if (!added) {
19869            mProcessesToGc.add(0, proc);
19870        }
19871    }
19872
19873    /**
19874     * Set up to ask a process to GC itself.  This will either do it
19875     * immediately, or put it on the list of processes to gc the next
19876     * time things are idle.
19877     */
19878    final void scheduleAppGcLocked(ProcessRecord app) {
19879        long now = SystemClock.uptimeMillis();
19880        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19881            return;
19882        }
19883        if (!mProcessesToGc.contains(app)) {
19884            addProcessToGcListLocked(app);
19885            scheduleAppGcsLocked();
19886        }
19887    }
19888
19889    final void checkExcessivePowerUsageLocked(boolean doKills) {
19890        updateCpuStatsNow();
19891
19892        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19893        boolean doWakeKills = doKills;
19894        boolean doCpuKills = doKills;
19895        if (mLastPowerCheckRealtime == 0) {
19896            doWakeKills = false;
19897        }
19898        if (mLastPowerCheckUptime == 0) {
19899            doCpuKills = false;
19900        }
19901        if (stats.isScreenOn()) {
19902            doWakeKills = false;
19903        }
19904        final long curRealtime = SystemClock.elapsedRealtime();
19905        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19906        final long curUptime = SystemClock.uptimeMillis();
19907        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19908        mLastPowerCheckRealtime = curRealtime;
19909        mLastPowerCheckUptime = curUptime;
19910        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19911            doWakeKills = false;
19912        }
19913        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19914            doCpuKills = false;
19915        }
19916        int i = mLruProcesses.size();
19917        while (i > 0) {
19918            i--;
19919            ProcessRecord app = mLruProcesses.get(i);
19920            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19921                long wtime;
19922                synchronized (stats) {
19923                    wtime = stats.getProcessWakeTime(app.info.uid,
19924                            app.pid, curRealtime);
19925                }
19926                long wtimeUsed = wtime - app.lastWakeTime;
19927                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19928                if (DEBUG_POWER) {
19929                    StringBuilder sb = new StringBuilder(128);
19930                    sb.append("Wake for ");
19931                    app.toShortString(sb);
19932                    sb.append(": over ");
19933                    TimeUtils.formatDuration(realtimeSince, sb);
19934                    sb.append(" used ");
19935                    TimeUtils.formatDuration(wtimeUsed, sb);
19936                    sb.append(" (");
19937                    sb.append((wtimeUsed*100)/realtimeSince);
19938                    sb.append("%)");
19939                    Slog.i(TAG_POWER, sb.toString());
19940                    sb.setLength(0);
19941                    sb.append("CPU for ");
19942                    app.toShortString(sb);
19943                    sb.append(": over ");
19944                    TimeUtils.formatDuration(uptimeSince, sb);
19945                    sb.append(" used ");
19946                    TimeUtils.formatDuration(cputimeUsed, sb);
19947                    sb.append(" (");
19948                    sb.append((cputimeUsed*100)/uptimeSince);
19949                    sb.append("%)");
19950                    Slog.i(TAG_POWER, sb.toString());
19951                }
19952                // If a process has held a wake lock for more
19953                // than 50% of the time during this period,
19954                // that sounds bad.  Kill!
19955                if (doWakeKills && realtimeSince > 0
19956                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19957                    synchronized (stats) {
19958                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19959                                realtimeSince, wtimeUsed);
19960                    }
19961                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19962                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19963                } else if (doCpuKills && uptimeSince > 0
19964                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19965                    synchronized (stats) {
19966                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19967                                uptimeSince, cputimeUsed);
19968                    }
19969                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19970                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19971                } else {
19972                    app.lastWakeTime = wtime;
19973                    app.lastCpuTime = app.curCpuTime;
19974                }
19975            }
19976        }
19977    }
19978
19979    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19980            long nowElapsed) {
19981        boolean success = true;
19982
19983        if (app.curRawAdj != app.setRawAdj) {
19984            app.setRawAdj = app.curRawAdj;
19985        }
19986
19987        int changes = 0;
19988
19989        if (app.curAdj != app.setAdj) {
19990            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19991            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19992                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19993                    + app.adjType);
19994            app.setAdj = app.curAdj;
19995        }
19996
19997        if (app.setSchedGroup != app.curSchedGroup) {
19998            app.setSchedGroup = app.curSchedGroup;
19999            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20000                    "Setting sched group of " + app.processName
20001                    + " to " + app.curSchedGroup);
20002            if (app.waitingToKill != null && app.curReceiver == null
20003                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20004                app.kill(app.waitingToKill, true);
20005                success = false;
20006            } else {
20007                int processGroup;
20008                switch (app.curSchedGroup) {
20009                    case ProcessList.SCHED_GROUP_BACKGROUND:
20010                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20011                        break;
20012                    case ProcessList.SCHED_GROUP_TOP_APP:
20013                        processGroup = Process.THREAD_GROUP_TOP_APP;
20014                        break;
20015                    default:
20016                        processGroup = Process.THREAD_GROUP_DEFAULT;
20017                        break;
20018                }
20019                if (true) {
20020                    long oldId = Binder.clearCallingIdentity();
20021                    try {
20022                        Process.setProcessGroup(app.pid, processGroup);
20023                    } catch (Exception e) {
20024                        Slog.w(TAG, "Failed setting process group of " + app.pid
20025                                + " to " + app.curSchedGroup);
20026                        e.printStackTrace();
20027                    } finally {
20028                        Binder.restoreCallingIdentity(oldId);
20029                    }
20030                } else {
20031                    if (app.thread != null) {
20032                        try {
20033                            app.thread.setSchedulingGroup(processGroup);
20034                        } catch (RemoteException e) {
20035                        }
20036                    }
20037                }
20038            }
20039        }
20040        if (app.repForegroundActivities != app.foregroundActivities) {
20041            app.repForegroundActivities = app.foregroundActivities;
20042            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20043        }
20044        if (app.repProcState != app.curProcState) {
20045            app.repProcState = app.curProcState;
20046            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20047            if (app.thread != null) {
20048                try {
20049                    if (false) {
20050                        //RuntimeException h = new RuntimeException("here");
20051                        Slog.i(TAG, "Sending new process state " + app.repProcState
20052                                + " to " + app /*, h*/);
20053                    }
20054                    app.thread.setProcessState(app.repProcState);
20055                } catch (RemoteException e) {
20056                }
20057            }
20058        }
20059        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20060                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20061            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20062                // Experimental code to more aggressively collect pss while
20063                // running test...  the problem is that this tends to collect
20064                // the data right when a process is transitioning between process
20065                // states, which well tend to give noisy data.
20066                long start = SystemClock.uptimeMillis();
20067                long pss = Debug.getPss(app.pid, mTmpLong, null);
20068                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20069                mPendingPssProcesses.remove(app);
20070                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20071                        + " to " + app.curProcState + ": "
20072                        + (SystemClock.uptimeMillis()-start) + "ms");
20073            }
20074            app.lastStateTime = now;
20075            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20076                    mTestPssMode, isSleeping(), now);
20077            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20078                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20079                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20080                    + (app.nextPssTime-now) + ": " + app);
20081        } else {
20082            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20083                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20084                    mTestPssMode)))) {
20085                requestPssLocked(app, app.setProcState);
20086                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20087                        mTestPssMode, isSleeping(), now);
20088            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20089                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20090        }
20091        if (app.setProcState != app.curProcState) {
20092            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20093                    "Proc state change of " + app.processName
20094                            + " to " + app.curProcState);
20095            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20096            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20097            if (setImportant && !curImportant) {
20098                // This app is no longer something we consider important enough to allow to
20099                // use arbitrary amounts of battery power.  Note
20100                // its current wake lock time to later know to kill it if
20101                // it is not behaving well.
20102                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20103                synchronized (stats) {
20104                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20105                            app.pid, nowElapsed);
20106                }
20107                app.lastCpuTime = app.curCpuTime;
20108
20109            }
20110            // Inform UsageStats of important process state change
20111            // Must be called before updating setProcState
20112            maybeUpdateUsageStatsLocked(app, nowElapsed);
20113
20114            app.setProcState = app.curProcState;
20115            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20116                app.notCachedSinceIdle = false;
20117            }
20118            if (!doingAll) {
20119                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20120            } else {
20121                app.procStateChanged = true;
20122            }
20123        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20124                > USAGE_STATS_INTERACTION_INTERVAL) {
20125            // For apps that sit around for a long time in the interactive state, we need
20126            // to report this at least once a day so they don't go idle.
20127            maybeUpdateUsageStatsLocked(app, nowElapsed);
20128        }
20129
20130        if (changes != 0) {
20131            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20132                    "Changes in " + app + ": " + changes);
20133            int i = mPendingProcessChanges.size()-1;
20134            ProcessChangeItem item = null;
20135            while (i >= 0) {
20136                item = mPendingProcessChanges.get(i);
20137                if (item.pid == app.pid) {
20138                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20139                            "Re-using existing item: " + item);
20140                    break;
20141                }
20142                i--;
20143            }
20144            if (i < 0) {
20145                // No existing item in pending changes; need a new one.
20146                final int NA = mAvailProcessChanges.size();
20147                if (NA > 0) {
20148                    item = mAvailProcessChanges.remove(NA-1);
20149                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20150                            "Retrieving available item: " + item);
20151                } else {
20152                    item = new ProcessChangeItem();
20153                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20154                            "Allocating new item: " + item);
20155                }
20156                item.changes = 0;
20157                item.pid = app.pid;
20158                item.uid = app.info.uid;
20159                if (mPendingProcessChanges.size() == 0) {
20160                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20161                            "*** Enqueueing dispatch processes changed!");
20162                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20163                }
20164                mPendingProcessChanges.add(item);
20165            }
20166            item.changes |= changes;
20167            item.processState = app.repProcState;
20168            item.foregroundActivities = app.repForegroundActivities;
20169            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20170                    "Item " + Integer.toHexString(System.identityHashCode(item))
20171                    + " " + app.toShortString() + ": changes=" + item.changes
20172                    + " procState=" + item.processState
20173                    + " foreground=" + item.foregroundActivities
20174                    + " type=" + app.adjType + " source=" + app.adjSource
20175                    + " target=" + app.adjTarget);
20176        }
20177
20178        return success;
20179    }
20180
20181    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20182        final UidRecord.ChangeItem pendingChange;
20183        if (uidRec == null || uidRec.pendingChange == null) {
20184            if (mPendingUidChanges.size() == 0) {
20185                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20186                        "*** Enqueueing dispatch uid changed!");
20187                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20188            }
20189            final int NA = mAvailUidChanges.size();
20190            if (NA > 0) {
20191                pendingChange = mAvailUidChanges.remove(NA-1);
20192                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20193                        "Retrieving available item: " + pendingChange);
20194            } else {
20195                pendingChange = new UidRecord.ChangeItem();
20196                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20197                        "Allocating new item: " + pendingChange);
20198            }
20199            if (uidRec != null) {
20200                uidRec.pendingChange = pendingChange;
20201                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20202                    // If this uid is going away, and we haven't yet reported it is gone,
20203                    // then do so now.
20204                    change = UidRecord.CHANGE_GONE_IDLE;
20205                }
20206            } else if (uid < 0) {
20207                throw new IllegalArgumentException("No UidRecord or uid");
20208            }
20209            pendingChange.uidRecord = uidRec;
20210            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20211            mPendingUidChanges.add(pendingChange);
20212        } else {
20213            pendingChange = uidRec.pendingChange;
20214            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20215                change = UidRecord.CHANGE_GONE_IDLE;
20216            }
20217        }
20218        pendingChange.change = change;
20219        pendingChange.processState = uidRec != null
20220                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20221    }
20222
20223    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20224            String authority) {
20225        if (app == null) return;
20226        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20227            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20228            if (userState == null) return;
20229            final long now = SystemClock.elapsedRealtime();
20230            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20231            if (lastReported == null || lastReported < now - 60 * 1000L) {
20232                mUsageStatsService.reportContentProviderUsage(
20233                        authority, providerPkgName, app.userId);
20234                userState.mProviderLastReportedFg.put(authority, now);
20235            }
20236        }
20237    }
20238
20239    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20240        if (DEBUG_USAGE_STATS) {
20241            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20242                    + "] state changes: old = " + app.setProcState + ", new = "
20243                    + app.curProcState);
20244        }
20245        if (mUsageStatsService == null) {
20246            return;
20247        }
20248        boolean isInteraction;
20249        // To avoid some abuse patterns, we are going to be careful about what we consider
20250        // to be an app interaction.  Being the top activity doesn't count while the display
20251        // is sleeping, nor do short foreground services.
20252        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20253            isInteraction = true;
20254            app.fgInteractionTime = 0;
20255        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20256            if (app.fgInteractionTime == 0) {
20257                app.fgInteractionTime = nowElapsed;
20258                isInteraction = false;
20259            } else {
20260                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20261            }
20262        } else {
20263            isInteraction = app.curProcState
20264                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20265            app.fgInteractionTime = 0;
20266        }
20267        if (isInteraction && (!app.reportedInteraction
20268                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20269            app.interactionEventTime = nowElapsed;
20270            String[] packages = app.getPackageList();
20271            if (packages != null) {
20272                for (int i = 0; i < packages.length; i++) {
20273                    mUsageStatsService.reportEvent(packages[i], app.userId,
20274                            UsageEvents.Event.SYSTEM_INTERACTION);
20275                }
20276            }
20277        }
20278        app.reportedInteraction = isInteraction;
20279        if (!isInteraction) {
20280            app.interactionEventTime = 0;
20281        }
20282    }
20283
20284    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20285        if (proc.thread != null) {
20286            if (proc.baseProcessTracker != null) {
20287                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20288            }
20289        }
20290    }
20291
20292    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20293            ProcessRecord TOP_APP, boolean doingAll, long now) {
20294        if (app.thread == null) {
20295            return false;
20296        }
20297
20298        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20299
20300        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20301    }
20302
20303    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20304            boolean oomAdj) {
20305        if (isForeground != proc.foregroundServices) {
20306            proc.foregroundServices = isForeground;
20307            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20308                    proc.info.uid);
20309            if (isForeground) {
20310                if (curProcs == null) {
20311                    curProcs = new ArrayList<ProcessRecord>();
20312                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20313                }
20314                if (!curProcs.contains(proc)) {
20315                    curProcs.add(proc);
20316                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20317                            proc.info.packageName, proc.info.uid);
20318                }
20319            } else {
20320                if (curProcs != null) {
20321                    if (curProcs.remove(proc)) {
20322                        mBatteryStatsService.noteEvent(
20323                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20324                                proc.info.packageName, proc.info.uid);
20325                        if (curProcs.size() <= 0) {
20326                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20327                        }
20328                    }
20329                }
20330            }
20331            if (oomAdj) {
20332                updateOomAdjLocked();
20333            }
20334        }
20335    }
20336
20337    private final ActivityRecord resumedAppLocked() {
20338        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20339        String pkg;
20340        int uid;
20341        if (act != null) {
20342            pkg = act.packageName;
20343            uid = act.info.applicationInfo.uid;
20344        } else {
20345            pkg = null;
20346            uid = -1;
20347        }
20348        // Has the UID or resumed package name changed?
20349        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20350                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20351            if (mCurResumedPackage != null) {
20352                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20353                        mCurResumedPackage, mCurResumedUid);
20354            }
20355            mCurResumedPackage = pkg;
20356            mCurResumedUid = uid;
20357            if (mCurResumedPackage != null) {
20358                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20359                        mCurResumedPackage, mCurResumedUid);
20360            }
20361        }
20362        return act;
20363    }
20364
20365    final boolean updateOomAdjLocked(ProcessRecord app) {
20366        final ActivityRecord TOP_ACT = resumedAppLocked();
20367        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20368        final boolean wasCached = app.cached;
20369
20370        mAdjSeq++;
20371
20372        // This is the desired cached adjusment we want to tell it to use.
20373        // If our app is currently cached, we know it, and that is it.  Otherwise,
20374        // we don't know it yet, and it needs to now be cached we will then
20375        // need to do a complete oom adj.
20376        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20377                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20378        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20379                SystemClock.uptimeMillis());
20380        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20381            // Changed to/from cached state, so apps after it in the LRU
20382            // list may also be changed.
20383            updateOomAdjLocked();
20384        }
20385        return success;
20386    }
20387
20388    final void updateOomAdjLocked() {
20389        final ActivityRecord TOP_ACT = resumedAppLocked();
20390        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20391        final long now = SystemClock.uptimeMillis();
20392        final long nowElapsed = SystemClock.elapsedRealtime();
20393        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20394        final int N = mLruProcesses.size();
20395
20396        if (false) {
20397            RuntimeException e = new RuntimeException();
20398            e.fillInStackTrace();
20399            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20400        }
20401
20402        // Reset state in all uid records.
20403        for (int i=mActiveUids.size()-1; i>=0; i--) {
20404            final UidRecord uidRec = mActiveUids.valueAt(i);
20405            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20406                    "Starting update of " + uidRec);
20407            uidRec.reset();
20408        }
20409
20410        mStackSupervisor.rankTaskLayersIfNeeded();
20411
20412        mAdjSeq++;
20413        mNewNumServiceProcs = 0;
20414        mNewNumAServiceProcs = 0;
20415
20416        final int emptyProcessLimit;
20417        final int cachedProcessLimit;
20418        if (mProcessLimit <= 0) {
20419            emptyProcessLimit = cachedProcessLimit = 0;
20420        } else if (mProcessLimit == 1) {
20421            emptyProcessLimit = 1;
20422            cachedProcessLimit = 0;
20423        } else {
20424            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20425            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20426        }
20427
20428        // Let's determine how many processes we have running vs.
20429        // how many slots we have for background processes; we may want
20430        // to put multiple processes in a slot of there are enough of
20431        // them.
20432        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20433                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20434        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20435        if (numEmptyProcs > cachedProcessLimit) {
20436            // If there are more empty processes than our limit on cached
20437            // processes, then use the cached process limit for the factor.
20438            // This ensures that the really old empty processes get pushed
20439            // down to the bottom, so if we are running low on memory we will
20440            // have a better chance at keeping around more cached processes
20441            // instead of a gazillion empty processes.
20442            numEmptyProcs = cachedProcessLimit;
20443        }
20444        int emptyFactor = numEmptyProcs/numSlots;
20445        if (emptyFactor < 1) emptyFactor = 1;
20446        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20447        if (cachedFactor < 1) cachedFactor = 1;
20448        int stepCached = 0;
20449        int stepEmpty = 0;
20450        int numCached = 0;
20451        int numEmpty = 0;
20452        int numTrimming = 0;
20453
20454        mNumNonCachedProcs = 0;
20455        mNumCachedHiddenProcs = 0;
20456
20457        // First update the OOM adjustment for each of the
20458        // application processes based on their current state.
20459        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20460        int nextCachedAdj = curCachedAdj+1;
20461        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20462        int nextEmptyAdj = curEmptyAdj+2;
20463        for (int i=N-1; i>=0; i--) {
20464            ProcessRecord app = mLruProcesses.get(i);
20465            if (!app.killedByAm && app.thread != null) {
20466                app.procStateChanged = false;
20467                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20468
20469                // If we haven't yet assigned the final cached adj
20470                // to the process, do that now.
20471                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20472                    switch (app.curProcState) {
20473                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20474                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20475                            // This process is a cached process holding activities...
20476                            // assign it the next cached value for that type, and then
20477                            // step that cached level.
20478                            app.curRawAdj = curCachedAdj;
20479                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20480                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20481                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20482                                    + ")");
20483                            if (curCachedAdj != nextCachedAdj) {
20484                                stepCached++;
20485                                if (stepCached >= cachedFactor) {
20486                                    stepCached = 0;
20487                                    curCachedAdj = nextCachedAdj;
20488                                    nextCachedAdj += 2;
20489                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20490                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20491                                    }
20492                                }
20493                            }
20494                            break;
20495                        default:
20496                            // For everything else, assign next empty cached process
20497                            // level and bump that up.  Note that this means that
20498                            // long-running services that have dropped down to the
20499                            // cached level will be treated as empty (since their process
20500                            // state is still as a service), which is what we want.
20501                            app.curRawAdj = curEmptyAdj;
20502                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20503                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20504                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20505                                    + ")");
20506                            if (curEmptyAdj != nextEmptyAdj) {
20507                                stepEmpty++;
20508                                if (stepEmpty >= emptyFactor) {
20509                                    stepEmpty = 0;
20510                                    curEmptyAdj = nextEmptyAdj;
20511                                    nextEmptyAdj += 2;
20512                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20513                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20514                                    }
20515                                }
20516                            }
20517                            break;
20518                    }
20519                }
20520
20521                applyOomAdjLocked(app, true, now, nowElapsed);
20522
20523                // Count the number of process types.
20524                switch (app.curProcState) {
20525                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20526                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20527                        mNumCachedHiddenProcs++;
20528                        numCached++;
20529                        if (numCached > cachedProcessLimit) {
20530                            app.kill("cached #" + numCached, true);
20531                        }
20532                        break;
20533                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20534                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20535                                && app.lastActivityTime < oldTime) {
20536                            app.kill("empty for "
20537                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20538                                    / 1000) + "s", true);
20539                        } else {
20540                            numEmpty++;
20541                            if (numEmpty > emptyProcessLimit) {
20542                                app.kill("empty #" + numEmpty, true);
20543                            }
20544                        }
20545                        break;
20546                    default:
20547                        mNumNonCachedProcs++;
20548                        break;
20549                }
20550
20551                if (app.isolated && app.services.size() <= 0) {
20552                    // If this is an isolated process, and there are no
20553                    // services running in it, then the process is no longer
20554                    // needed.  We agressively kill these because we can by
20555                    // definition not re-use the same process again, and it is
20556                    // good to avoid having whatever code was running in them
20557                    // left sitting around after no longer needed.
20558                    app.kill("isolated not needed", true);
20559                } else {
20560                    // Keeping this process, update its uid.
20561                    final UidRecord uidRec = app.uidRecord;
20562                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20563                        uidRec.curProcState = app.curProcState;
20564                    }
20565                }
20566
20567                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20568                        && !app.killedByAm) {
20569                    numTrimming++;
20570                }
20571            }
20572        }
20573
20574        mNumServiceProcs = mNewNumServiceProcs;
20575
20576        // Now determine the memory trimming level of background processes.
20577        // Unfortunately we need to start at the back of the list to do this
20578        // properly.  We only do this if the number of background apps we
20579        // are managing to keep around is less than half the maximum we desire;
20580        // if we are keeping a good number around, we'll let them use whatever
20581        // memory they want.
20582        final int numCachedAndEmpty = numCached + numEmpty;
20583        int memFactor;
20584        if (numCached <= ProcessList.TRIM_CACHED_APPS
20585                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20586            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20587                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20588            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20589                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20590            } else {
20591                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20592            }
20593        } else {
20594            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20595        }
20596        // We always allow the memory level to go up (better).  We only allow it to go
20597        // down if we are in a state where that is allowed, *and* the total number of processes
20598        // has gone down since last time.
20599        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20600                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20601                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20602        if (memFactor > mLastMemoryLevel) {
20603            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20604                memFactor = mLastMemoryLevel;
20605                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20606            }
20607        }
20608        if (memFactor != mLastMemoryLevel) {
20609            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20610        }
20611        mLastMemoryLevel = memFactor;
20612        mLastNumProcesses = mLruProcesses.size();
20613        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20614        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20615        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20616            if (mLowRamStartTime == 0) {
20617                mLowRamStartTime = now;
20618            }
20619            int step = 0;
20620            int fgTrimLevel;
20621            switch (memFactor) {
20622                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20623                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20624                    break;
20625                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20626                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20627                    break;
20628                default:
20629                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20630                    break;
20631            }
20632            int factor = numTrimming/3;
20633            int minFactor = 2;
20634            if (mHomeProcess != null) minFactor++;
20635            if (mPreviousProcess != null) minFactor++;
20636            if (factor < minFactor) factor = minFactor;
20637            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20638            for (int i=N-1; i>=0; i--) {
20639                ProcessRecord app = mLruProcesses.get(i);
20640                if (allChanged || app.procStateChanged) {
20641                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20642                    app.procStateChanged = false;
20643                }
20644                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20645                        && !app.killedByAm) {
20646                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20647                        try {
20648                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20649                                    "Trimming memory of " + app.processName + " to " + curLevel);
20650                            app.thread.scheduleTrimMemory(curLevel);
20651                        } catch (RemoteException e) {
20652                        }
20653                        if (false) {
20654                            // For now we won't do this; our memory trimming seems
20655                            // to be good enough at this point that destroying
20656                            // activities causes more harm than good.
20657                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20658                                    && app != mHomeProcess && app != mPreviousProcess) {
20659                                // Need to do this on its own message because the stack may not
20660                                // be in a consistent state at this point.
20661                                // For these apps we will also finish their activities
20662                                // to help them free memory.
20663                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20664                            }
20665                        }
20666                    }
20667                    app.trimMemoryLevel = curLevel;
20668                    step++;
20669                    if (step >= factor) {
20670                        step = 0;
20671                        switch (curLevel) {
20672                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20673                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20674                                break;
20675                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20676                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20677                                break;
20678                        }
20679                    }
20680                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20681                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20682                            && app.thread != null) {
20683                        try {
20684                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20685                                    "Trimming memory of heavy-weight " + app.processName
20686                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20687                            app.thread.scheduleTrimMemory(
20688                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20689                        } catch (RemoteException e) {
20690                        }
20691                    }
20692                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20693                } else {
20694                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20695                            || app.systemNoUi) && app.pendingUiClean) {
20696                        // If this application is now in the background and it
20697                        // had done UI, then give it the special trim level to
20698                        // have it free UI resources.
20699                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20700                        if (app.trimMemoryLevel < level && app.thread != null) {
20701                            try {
20702                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20703                                        "Trimming memory of bg-ui " + app.processName
20704                                        + " to " + level);
20705                                app.thread.scheduleTrimMemory(level);
20706                            } catch (RemoteException e) {
20707                            }
20708                        }
20709                        app.pendingUiClean = false;
20710                    }
20711                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20712                        try {
20713                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20714                                    "Trimming memory of fg " + app.processName
20715                                    + " to " + fgTrimLevel);
20716                            app.thread.scheduleTrimMemory(fgTrimLevel);
20717                        } catch (RemoteException e) {
20718                        }
20719                    }
20720                    app.trimMemoryLevel = fgTrimLevel;
20721                }
20722            }
20723        } else {
20724            if (mLowRamStartTime != 0) {
20725                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20726                mLowRamStartTime = 0;
20727            }
20728            for (int i=N-1; i>=0; i--) {
20729                ProcessRecord app = mLruProcesses.get(i);
20730                if (allChanged || app.procStateChanged) {
20731                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20732                    app.procStateChanged = false;
20733                }
20734                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20735                        || app.systemNoUi) && app.pendingUiClean) {
20736                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20737                            && app.thread != null) {
20738                        try {
20739                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20740                                    "Trimming memory of ui hidden " + app.processName
20741                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20742                            app.thread.scheduleTrimMemory(
20743                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20744                        } catch (RemoteException e) {
20745                        }
20746                    }
20747                    app.pendingUiClean = false;
20748                }
20749                app.trimMemoryLevel = 0;
20750            }
20751        }
20752
20753        if (mAlwaysFinishActivities) {
20754            // Need to do this on its own message because the stack may not
20755            // be in a consistent state at this point.
20756            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20757        }
20758
20759        if (allChanged) {
20760            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20761        }
20762
20763        // Update from any uid changes.
20764        for (int i=mActiveUids.size()-1; i>=0; i--) {
20765            final UidRecord uidRec = mActiveUids.valueAt(i);
20766            int uidChange = UidRecord.CHANGE_PROCSTATE;
20767            if (uidRec.setProcState != uidRec.curProcState) {
20768                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20769                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20770                        + " to " + uidRec.curProcState);
20771                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20772                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20773                        uidRec.lastBackgroundTime = nowElapsed;
20774                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20775                            // Note: the background settle time is in elapsed realtime, while
20776                            // the handler time base is uptime.  All this means is that we may
20777                            // stop background uids later than we had intended, but that only
20778                            // happens because the device was sleeping so we are okay anyway.
20779                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20780                        }
20781                    }
20782                } else {
20783                    if (uidRec.idle) {
20784                        uidChange = UidRecord.CHANGE_ACTIVE;
20785                        uidRec.idle = false;
20786                    }
20787                    uidRec.lastBackgroundTime = 0;
20788                }
20789                uidRec.setProcState = uidRec.curProcState;
20790                enqueueUidChangeLocked(uidRec, -1, uidChange);
20791                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20792            }
20793        }
20794
20795        if (mProcessStats.shouldWriteNowLocked(now)) {
20796            mHandler.post(new Runnable() {
20797                @Override public void run() {
20798                    synchronized (ActivityManagerService.this) {
20799                        mProcessStats.writeStateAsyncLocked();
20800                    }
20801                }
20802            });
20803        }
20804
20805        if (DEBUG_OOM_ADJ) {
20806            final long duration = SystemClock.uptimeMillis() - now;
20807            if (false) {
20808                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20809                        new RuntimeException("here").fillInStackTrace());
20810            } else {
20811                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20812            }
20813        }
20814    }
20815
20816    final void idleUids() {
20817        synchronized (this) {
20818            final long nowElapsed = SystemClock.elapsedRealtime();
20819            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20820            long nextTime = 0;
20821            for (int i=mActiveUids.size()-1; i>=0; i--) {
20822                final UidRecord uidRec = mActiveUids.valueAt(i);
20823                final long bgTime = uidRec.lastBackgroundTime;
20824                if (bgTime > 0 && !uidRec.idle) {
20825                    if (bgTime <= maxBgTime) {
20826                        uidRec.idle = true;
20827                        doStopUidLocked(uidRec.uid, uidRec);
20828                    } else {
20829                        if (nextTime == 0 || nextTime > bgTime) {
20830                            nextTime = bgTime;
20831                        }
20832                    }
20833                }
20834            }
20835            if (nextTime > 0) {
20836                mHandler.removeMessages(IDLE_UIDS_MSG);
20837                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20838                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20839            }
20840        }
20841    }
20842
20843    final void runInBackgroundDisabled(int uid) {
20844        synchronized (this) {
20845            UidRecord uidRec = mActiveUids.get(uid);
20846            if (uidRec != null) {
20847                // This uid is actually running...  should it be considered background now?
20848                if (uidRec.idle) {
20849                    doStopUidLocked(uidRec.uid, uidRec);
20850                }
20851            } else {
20852                // This uid isn't actually running...  still send a report about it being "stopped".
20853                doStopUidLocked(uid, null);
20854            }
20855        }
20856    }
20857
20858    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20859        mServices.stopInBackgroundLocked(uid);
20860        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20861    }
20862
20863    final void trimApplications() {
20864        synchronized (this) {
20865            int i;
20866
20867            // First remove any unused application processes whose package
20868            // has been removed.
20869            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20870                final ProcessRecord app = mRemovedProcesses.get(i);
20871                if (app.activities.size() == 0
20872                        && app.curReceiver == null && app.services.size() == 0) {
20873                    Slog.i(
20874                        TAG, "Exiting empty application process "
20875                        + app.toShortString() + " ("
20876                        + (app.thread != null ? app.thread.asBinder() : null)
20877                        + ")\n");
20878                    if (app.pid > 0 && app.pid != MY_PID) {
20879                        app.kill("empty", false);
20880                    } else {
20881                        try {
20882                            app.thread.scheduleExit();
20883                        } catch (Exception e) {
20884                            // Ignore exceptions.
20885                        }
20886                    }
20887                    cleanUpApplicationRecordLocked(app, false, true, -1);
20888                    mRemovedProcesses.remove(i);
20889
20890                    if (app.persistent) {
20891                        addAppLocked(app.info, false, null /* ABI override */);
20892                    }
20893                }
20894            }
20895
20896            // Now update the oom adj for all processes.
20897            updateOomAdjLocked();
20898        }
20899    }
20900
20901    /** This method sends the specified signal to each of the persistent apps */
20902    public void signalPersistentProcesses(int sig) throws RemoteException {
20903        if (sig != Process.SIGNAL_USR1) {
20904            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20905        }
20906
20907        synchronized (this) {
20908            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20909                    != PackageManager.PERMISSION_GRANTED) {
20910                throw new SecurityException("Requires permission "
20911                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20912            }
20913
20914            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20915                ProcessRecord r = mLruProcesses.get(i);
20916                if (r.thread != null && r.persistent) {
20917                    Process.sendSignal(r.pid, sig);
20918                }
20919            }
20920        }
20921    }
20922
20923    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20924        if (proc == null || proc == mProfileProc) {
20925            proc = mProfileProc;
20926            profileType = mProfileType;
20927            clearProfilerLocked();
20928        }
20929        if (proc == null) {
20930            return;
20931        }
20932        try {
20933            proc.thread.profilerControl(false, null, profileType);
20934        } catch (RemoteException e) {
20935            throw new IllegalStateException("Process disappeared");
20936        }
20937    }
20938
20939    private void clearProfilerLocked() {
20940        if (mProfileFd != null) {
20941            try {
20942                mProfileFd.close();
20943            } catch (IOException e) {
20944            }
20945        }
20946        mProfileApp = null;
20947        mProfileProc = null;
20948        mProfileFile = null;
20949        mProfileType = 0;
20950        mAutoStopProfiler = false;
20951        mSamplingInterval = 0;
20952    }
20953
20954    public boolean profileControl(String process, int userId, boolean start,
20955            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20956
20957        try {
20958            synchronized (this) {
20959                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20960                // its own permission.
20961                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20962                        != PackageManager.PERMISSION_GRANTED) {
20963                    throw new SecurityException("Requires permission "
20964                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20965                }
20966
20967                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20968                    throw new IllegalArgumentException("null profile info or fd");
20969                }
20970
20971                ProcessRecord proc = null;
20972                if (process != null) {
20973                    proc = findProcessLocked(process, userId, "profileControl");
20974                }
20975
20976                if (start && (proc == null || proc.thread == null)) {
20977                    throw new IllegalArgumentException("Unknown process: " + process);
20978                }
20979
20980                if (start) {
20981                    stopProfilerLocked(null, 0);
20982                    setProfileApp(proc.info, proc.processName, profilerInfo);
20983                    mProfileProc = proc;
20984                    mProfileType = profileType;
20985                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20986                    try {
20987                        fd = fd.dup();
20988                    } catch (IOException e) {
20989                        fd = null;
20990                    }
20991                    profilerInfo.profileFd = fd;
20992                    proc.thread.profilerControl(start, profilerInfo, profileType);
20993                    fd = null;
20994                    mProfileFd = null;
20995                } else {
20996                    stopProfilerLocked(proc, profileType);
20997                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20998                        try {
20999                            profilerInfo.profileFd.close();
21000                        } catch (IOException e) {
21001                        }
21002                    }
21003                }
21004
21005                return true;
21006            }
21007        } catch (RemoteException e) {
21008            throw new IllegalStateException("Process disappeared");
21009        } finally {
21010            if (profilerInfo != null && profilerInfo.profileFd != null) {
21011                try {
21012                    profilerInfo.profileFd.close();
21013                } catch (IOException e) {
21014                }
21015            }
21016        }
21017    }
21018
21019    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21020        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21021                userId, true, ALLOW_FULL_ONLY, callName, null);
21022        ProcessRecord proc = null;
21023        try {
21024            int pid = Integer.parseInt(process);
21025            synchronized (mPidsSelfLocked) {
21026                proc = mPidsSelfLocked.get(pid);
21027            }
21028        } catch (NumberFormatException e) {
21029        }
21030
21031        if (proc == null) {
21032            ArrayMap<String, SparseArray<ProcessRecord>> all
21033                    = mProcessNames.getMap();
21034            SparseArray<ProcessRecord> procs = all.get(process);
21035            if (procs != null && procs.size() > 0) {
21036                proc = procs.valueAt(0);
21037                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21038                    for (int i=1; i<procs.size(); i++) {
21039                        ProcessRecord thisProc = procs.valueAt(i);
21040                        if (thisProc.userId == userId) {
21041                            proc = thisProc;
21042                            break;
21043                        }
21044                    }
21045                }
21046            }
21047        }
21048
21049        return proc;
21050    }
21051
21052    public boolean dumpHeap(String process, int userId, boolean managed,
21053            String path, ParcelFileDescriptor fd) throws RemoteException {
21054
21055        try {
21056            synchronized (this) {
21057                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21058                // its own permission (same as profileControl).
21059                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21060                        != PackageManager.PERMISSION_GRANTED) {
21061                    throw new SecurityException("Requires permission "
21062                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21063                }
21064
21065                if (fd == null) {
21066                    throw new IllegalArgumentException("null fd");
21067                }
21068
21069                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21070                if (proc == null || proc.thread == null) {
21071                    throw new IllegalArgumentException("Unknown process: " + process);
21072                }
21073
21074                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21075                if (!isDebuggable) {
21076                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21077                        throw new SecurityException("Process not debuggable: " + proc);
21078                    }
21079                }
21080
21081                proc.thread.dumpHeap(managed, path, fd);
21082                fd = null;
21083                return true;
21084            }
21085        } catch (RemoteException e) {
21086            throw new IllegalStateException("Process disappeared");
21087        } finally {
21088            if (fd != null) {
21089                try {
21090                    fd.close();
21091                } catch (IOException e) {
21092                }
21093            }
21094        }
21095    }
21096
21097    @Override
21098    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21099            String reportPackage) {
21100        if (processName != null) {
21101            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21102                    "setDumpHeapDebugLimit()");
21103        } else {
21104            synchronized (mPidsSelfLocked) {
21105                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21106                if (proc == null) {
21107                    throw new SecurityException("No process found for calling pid "
21108                            + Binder.getCallingPid());
21109                }
21110                if (!Build.IS_DEBUGGABLE
21111                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21112                    throw new SecurityException("Not running a debuggable build");
21113                }
21114                processName = proc.processName;
21115                uid = proc.uid;
21116                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21117                    throw new SecurityException("Package " + reportPackage + " is not running in "
21118                            + proc);
21119                }
21120            }
21121        }
21122        synchronized (this) {
21123            if (maxMemSize > 0) {
21124                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21125            } else {
21126                if (uid != 0) {
21127                    mMemWatchProcesses.remove(processName, uid);
21128                } else {
21129                    mMemWatchProcesses.getMap().remove(processName);
21130                }
21131            }
21132        }
21133    }
21134
21135    @Override
21136    public void dumpHeapFinished(String path) {
21137        synchronized (this) {
21138            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21139                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21140                        + " does not match last pid " + mMemWatchDumpPid);
21141                return;
21142            }
21143            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21144                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21145                        + " does not match last path " + mMemWatchDumpFile);
21146                return;
21147            }
21148            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21149            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21150        }
21151    }
21152
21153    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21154    public void monitor() {
21155        synchronized (this) { }
21156    }
21157
21158    void onCoreSettingsChange(Bundle settings) {
21159        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21160            ProcessRecord processRecord = mLruProcesses.get(i);
21161            try {
21162                if (processRecord.thread != null) {
21163                    processRecord.thread.setCoreSettings(settings);
21164                }
21165            } catch (RemoteException re) {
21166                /* ignore */
21167            }
21168        }
21169    }
21170
21171    // Multi-user methods
21172
21173    /**
21174     * Start user, if its not already running, but don't bring it to foreground.
21175     */
21176    @Override
21177    public boolean startUserInBackground(final int userId) {
21178        return mUserController.startUser(userId, /* foreground */ false);
21179    }
21180
21181    @Override
21182    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21183        return mUserController.unlockUser(userId, token, secret, listener);
21184    }
21185
21186    @Override
21187    public boolean switchUser(final int targetUserId) {
21188        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21189        UserInfo currentUserInfo;
21190        UserInfo targetUserInfo;
21191        synchronized (this) {
21192            int currentUserId = mUserController.getCurrentUserIdLocked();
21193            currentUserInfo = mUserController.getUserInfo(currentUserId);
21194            targetUserInfo = mUserController.getUserInfo(targetUserId);
21195            if (targetUserInfo == null) {
21196                Slog.w(TAG, "No user info for user #" + targetUserId);
21197                return false;
21198            }
21199            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21200                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21201                        + " when device is in demo mode");
21202                return false;
21203            }
21204            if (!targetUserInfo.supportsSwitchTo()) {
21205                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21206                return false;
21207            }
21208            if (targetUserInfo.isManagedProfile()) {
21209                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21210                return false;
21211            }
21212            mUserController.setTargetUserIdLocked(targetUserId);
21213        }
21214        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21215        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21216        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21217        return true;
21218    }
21219
21220    void scheduleStartProfilesLocked() {
21221        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21222            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21223                    DateUtils.SECOND_IN_MILLIS);
21224        }
21225    }
21226
21227    @Override
21228    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21229        return mUserController.stopUser(userId, force, callback);
21230    }
21231
21232    @Override
21233    public UserInfo getCurrentUser() {
21234        return mUserController.getCurrentUser();
21235    }
21236
21237    @Override
21238    public boolean isUserRunning(int userId, int flags) {
21239        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21240                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21241            String msg = "Permission Denial: isUserRunning() from pid="
21242                    + Binder.getCallingPid()
21243                    + ", uid=" + Binder.getCallingUid()
21244                    + " requires " + INTERACT_ACROSS_USERS;
21245            Slog.w(TAG, msg);
21246            throw new SecurityException(msg);
21247        }
21248        synchronized (this) {
21249            return mUserController.isUserRunningLocked(userId, flags);
21250        }
21251    }
21252
21253    @Override
21254    public int[] getRunningUserIds() {
21255        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21256                != PackageManager.PERMISSION_GRANTED) {
21257            String msg = "Permission Denial: isUserRunning() from pid="
21258                    + Binder.getCallingPid()
21259                    + ", uid=" + Binder.getCallingUid()
21260                    + " requires " + INTERACT_ACROSS_USERS;
21261            Slog.w(TAG, msg);
21262            throw new SecurityException(msg);
21263        }
21264        synchronized (this) {
21265            return mUserController.getStartedUserArrayLocked();
21266        }
21267    }
21268
21269    @Override
21270    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21271        mUserController.registerUserSwitchObserver(observer);
21272    }
21273
21274    @Override
21275    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21276        mUserController.unregisterUserSwitchObserver(observer);
21277    }
21278
21279    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21280        if (info == null) return null;
21281        ApplicationInfo newInfo = new ApplicationInfo(info);
21282        newInfo.initForUser(userId);
21283        return newInfo;
21284    }
21285
21286    public boolean isUserStopped(int userId) {
21287        synchronized (this) {
21288            return mUserController.getStartedUserStateLocked(userId) == null;
21289        }
21290    }
21291
21292    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21293        if (aInfo == null
21294                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21295            return aInfo;
21296        }
21297
21298        ActivityInfo info = new ActivityInfo(aInfo);
21299        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21300        return info;
21301    }
21302
21303    private boolean processSanityChecksLocked(ProcessRecord process) {
21304        if (process == null || process.thread == null) {
21305            return false;
21306        }
21307
21308        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21309        if (!isDebuggable) {
21310            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21311                return false;
21312            }
21313        }
21314
21315        return true;
21316    }
21317
21318    public boolean startBinderTracking() throws RemoteException {
21319        synchronized (this) {
21320            mBinderTransactionTrackingEnabled = true;
21321            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21322            // permission (same as profileControl).
21323            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21324                    != PackageManager.PERMISSION_GRANTED) {
21325                throw new SecurityException("Requires permission "
21326                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21327            }
21328
21329            for (int i = 0; i < mLruProcesses.size(); i++) {
21330                ProcessRecord process = mLruProcesses.get(i);
21331                if (!processSanityChecksLocked(process)) {
21332                    continue;
21333                }
21334                try {
21335                    process.thread.startBinderTracking();
21336                } catch (RemoteException e) {
21337                    Log.v(TAG, "Process disappared");
21338                }
21339            }
21340            return true;
21341        }
21342    }
21343
21344    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21345        try {
21346            synchronized (this) {
21347                mBinderTransactionTrackingEnabled = false;
21348                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21349                // permission (same as profileControl).
21350                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21351                        != PackageManager.PERMISSION_GRANTED) {
21352                    throw new SecurityException("Requires permission "
21353                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21354                }
21355
21356                if (fd == null) {
21357                    throw new IllegalArgumentException("null fd");
21358                }
21359
21360                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21361                pw.println("Binder transaction traces for all processes.\n");
21362                for (ProcessRecord process : mLruProcesses) {
21363                    if (!processSanityChecksLocked(process)) {
21364                        continue;
21365                    }
21366
21367                    pw.println("Traces for process: " + process.processName);
21368                    pw.flush();
21369                    try {
21370                        TransferPipe tp = new TransferPipe();
21371                        try {
21372                            process.thread.stopBinderTrackingAndDump(
21373                                    tp.getWriteFd().getFileDescriptor());
21374                            tp.go(fd.getFileDescriptor());
21375                        } finally {
21376                            tp.kill();
21377                        }
21378                    } catch (IOException e) {
21379                        pw.println("Failure while dumping IPC traces from " + process +
21380                                ".  Exception: " + e);
21381                        pw.flush();
21382                    } catch (RemoteException e) {
21383                        pw.println("Got a RemoteException while dumping IPC traces from " +
21384                                process + ".  Exception: " + e);
21385                        pw.flush();
21386                    }
21387                }
21388                fd = null;
21389                return true;
21390            }
21391        } finally {
21392            if (fd != null) {
21393                try {
21394                    fd.close();
21395                } catch (IOException e) {
21396                }
21397            }
21398        }
21399    }
21400
21401    private final class LocalService extends ActivityManagerInternal {
21402        @Override
21403        public void onWakefulnessChanged(int wakefulness) {
21404            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21405        }
21406
21407        @Override
21408        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21409                String processName, String abiOverride, int uid, Runnable crashHandler) {
21410            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21411                    processName, abiOverride, uid, crashHandler);
21412        }
21413
21414        @Override
21415        public SleepToken acquireSleepToken(String tag) {
21416            Preconditions.checkNotNull(tag);
21417
21418            synchronized (ActivityManagerService.this) {
21419                SleepTokenImpl token = new SleepTokenImpl(tag);
21420                mSleepTokens.add(token);
21421                updateSleepIfNeededLocked();
21422                applyVrModeIfNeededLocked(mFocusedActivity, false);
21423                return token;
21424            }
21425        }
21426
21427        @Override
21428        public ComponentName getHomeActivityForUser(int userId) {
21429            synchronized (ActivityManagerService.this) {
21430                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21431                return homeActivity == null ? null : homeActivity.realActivity;
21432            }
21433        }
21434
21435        @Override
21436        public void onUserRemoved(int userId) {
21437            synchronized (ActivityManagerService.this) {
21438                ActivityManagerService.this.onUserStoppedLocked(userId);
21439            }
21440        }
21441
21442        @Override
21443        public void onLocalVoiceInteractionStarted(IBinder activity,
21444                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21445            synchronized (ActivityManagerService.this) {
21446                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21447                        voiceSession, voiceInteractor);
21448            }
21449        }
21450
21451        @Override
21452        public void notifyStartingWindowDrawn() {
21453            synchronized (ActivityManagerService.this) {
21454                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21455            }
21456        }
21457
21458        @Override
21459        public void notifyAppTransitionStarting(int reason) {
21460            synchronized (ActivityManagerService.this) {
21461                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21462            }
21463        }
21464
21465        @Override
21466        public void notifyAppTransitionFinished() {
21467            synchronized (ActivityManagerService.this) {
21468                mStackSupervisor.notifyAppTransitionDone();
21469            }
21470        }
21471
21472        @Override
21473        public void notifyAppTransitionCancelled() {
21474            synchronized (ActivityManagerService.this) {
21475                mStackSupervisor.notifyAppTransitionDone();
21476            }
21477        }
21478
21479        @Override
21480        public List<IBinder> getTopVisibleActivities() {
21481            synchronized (ActivityManagerService.this) {
21482                return mStackSupervisor.getTopVisibleActivities();
21483            }
21484        }
21485
21486        @Override
21487        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21488            synchronized (ActivityManagerService.this) {
21489                mStackSupervisor.setDockedStackMinimized(minimized);
21490            }
21491        }
21492
21493        @Override
21494        public void killForegroundAppsForUser(int userHandle) {
21495            synchronized (ActivityManagerService.this) {
21496                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21497                final int NP = mProcessNames.getMap().size();
21498                for (int ip = 0; ip < NP; ip++) {
21499                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21500                    final int NA = apps.size();
21501                    for (int ia = 0; ia < NA; ia++) {
21502                        final ProcessRecord app = apps.valueAt(ia);
21503                        if (app.persistent) {
21504                            // We don't kill persistent processes.
21505                            continue;
21506                        }
21507                        if (app.removed) {
21508                            procs.add(app);
21509                        } else if (app.userId == userHandle && app.foregroundActivities) {
21510                            app.removed = true;
21511                            procs.add(app);
21512                        }
21513                    }
21514                }
21515
21516                final int N = procs.size();
21517                for (int i = 0; i < N; i++) {
21518                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21519                }
21520            }
21521        }
21522
21523        @Override
21524        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21525            if (!(target instanceof PendingIntentRecord)) {
21526                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21527                return;
21528            }
21529            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21530        }
21531    }
21532
21533    private final class SleepTokenImpl extends SleepToken {
21534        private final String mTag;
21535        private final long mAcquireTime;
21536
21537        public SleepTokenImpl(String tag) {
21538            mTag = tag;
21539            mAcquireTime = SystemClock.uptimeMillis();
21540        }
21541
21542        @Override
21543        public void release() {
21544            synchronized (ActivityManagerService.this) {
21545                if (mSleepTokens.remove(this)) {
21546                    updateSleepIfNeededLocked();
21547                }
21548            }
21549        }
21550
21551        @Override
21552        public String toString() {
21553            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21554        }
21555    }
21556
21557    /**
21558     * An implementation of IAppTask, that allows an app to manage its own tasks via
21559     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21560     * only the process that calls getAppTasks() can call the AppTask methods.
21561     */
21562    class AppTaskImpl extends IAppTask.Stub {
21563        private int mTaskId;
21564        private int mCallingUid;
21565
21566        public AppTaskImpl(int taskId, int callingUid) {
21567            mTaskId = taskId;
21568            mCallingUid = callingUid;
21569        }
21570
21571        private void checkCaller() {
21572            if (mCallingUid != Binder.getCallingUid()) {
21573                throw new SecurityException("Caller " + mCallingUid
21574                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21575            }
21576        }
21577
21578        @Override
21579        public void finishAndRemoveTask() {
21580            checkCaller();
21581
21582            synchronized (ActivityManagerService.this) {
21583                long origId = Binder.clearCallingIdentity();
21584                try {
21585                    // We remove the task from recents to preserve backwards
21586                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21587                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21588                    }
21589                } finally {
21590                    Binder.restoreCallingIdentity(origId);
21591                }
21592            }
21593        }
21594
21595        @Override
21596        public ActivityManager.RecentTaskInfo getTaskInfo() {
21597            checkCaller();
21598
21599            synchronized (ActivityManagerService.this) {
21600                long origId = Binder.clearCallingIdentity();
21601                try {
21602                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21603                    if (tr == null) {
21604                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21605                    }
21606                    return createRecentTaskInfoFromTaskRecord(tr);
21607                } finally {
21608                    Binder.restoreCallingIdentity(origId);
21609                }
21610            }
21611        }
21612
21613        @Override
21614        public void moveToFront() {
21615            checkCaller();
21616            // Will bring task to front if it already has a root activity.
21617            final long origId = Binder.clearCallingIdentity();
21618            try {
21619                synchronized (this) {
21620                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21621                }
21622            } finally {
21623                Binder.restoreCallingIdentity(origId);
21624            }
21625        }
21626
21627        @Override
21628        public int startActivity(IBinder whoThread, String callingPackage,
21629                Intent intent, String resolvedType, Bundle bOptions) {
21630            checkCaller();
21631
21632            int callingUser = UserHandle.getCallingUserId();
21633            TaskRecord tr;
21634            IApplicationThread appThread;
21635            synchronized (ActivityManagerService.this) {
21636                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21637                if (tr == null) {
21638                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21639                }
21640                appThread = ApplicationThreadNative.asInterface(whoThread);
21641                if (appThread == null) {
21642                    throw new IllegalArgumentException("Bad app thread " + appThread);
21643                }
21644            }
21645            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21646                    resolvedType, null, null, null, null, 0, 0, null, null,
21647                    null, bOptions, false, callingUser, null, tr);
21648        }
21649
21650        @Override
21651        public void setExcludeFromRecents(boolean exclude) {
21652            checkCaller();
21653
21654            synchronized (ActivityManagerService.this) {
21655                long origId = Binder.clearCallingIdentity();
21656                try {
21657                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21658                    if (tr == null) {
21659                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21660                    }
21661                    Intent intent = tr.getBaseIntent();
21662                    if (exclude) {
21663                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21664                    } else {
21665                        intent.setFlags(intent.getFlags()
21666                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21667                    }
21668                } finally {
21669                    Binder.restoreCallingIdentity(origId);
21670                }
21671            }
21672        }
21673    }
21674
21675    /**
21676     * Kill processes for the user with id userId and that depend on the package named packageName
21677     */
21678    @Override
21679    public void killPackageDependents(String packageName, int userId) {
21680        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21681        if (packageName == null) {
21682            throw new NullPointerException(
21683                    "Cannot kill the dependents of a package without its name.");
21684        }
21685
21686        long callingId = Binder.clearCallingIdentity();
21687        IPackageManager pm = AppGlobals.getPackageManager();
21688        int pkgUid = -1;
21689        try {
21690            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21691        } catch (RemoteException e) {
21692        }
21693        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21694            throw new IllegalArgumentException(
21695                    "Cannot kill dependents of non-existing package " + packageName);
21696        }
21697        try {
21698            synchronized(this) {
21699                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21700                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21701                        "dep: " + packageName);
21702            }
21703        } finally {
21704            Binder.restoreCallingIdentity(callingId);
21705        }
21706    }
21707}
21708