ActivityManagerService.java revision c5f86647b19d5cac4d9874ef84954fcf7a6d5fa9
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.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
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.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    // it's a semaphore; boost when 0->1, reset when 1->0
644    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
645        @Override protected Integer initialValue() {
646            return 0;
647        }
648    };
649
650    static void boostPriorityForLockedSection() {
651        if (sIsBoosted.get() == 0) {
652            // boost to prio 118 while holding a global lock
653            Process.setThreadPriority(Process.myTid(), -2);
654            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
655        }
656        int cur = sIsBoosted.get();
657        sIsBoosted.set(cur + 1);
658    }
659
660    static void resetPriorityAfterLockedSection() {
661        sIsBoosted.set(sIsBoosted.get() - 1);
662        if (sIsBoosted.get() == 0) {
663            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
664            Process.setThreadPriority(Process.myTid(), 0);
665        }
666    }
667    public class PendingAssistExtras extends Binder implements Runnable {
668        public final ActivityRecord activity;
669        public final Bundle extras;
670        public final Intent intent;
671        public final String hint;
672        public final IResultReceiver receiver;
673        public final int userHandle;
674        public boolean haveResult = false;
675        public Bundle result = null;
676        public AssistStructure structure = null;
677        public AssistContent content = null;
678        public Bundle receiverExtras;
679
680        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
681                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
682            activity = _activity;
683            extras = _extras;
684            intent = _intent;
685            hint = _hint;
686            receiver = _receiver;
687            receiverExtras = _receiverExtras;
688            userHandle = _userHandle;
689        }
690        @Override
691        public void run() {
692            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
693            synchronized (this) {
694                haveResult = true;
695                notifyAll();
696            }
697            pendingAssistExtrasTimedOut(this);
698        }
699    }
700
701    final ArrayList<PendingAssistExtras> mPendingAssistExtras
702            = new ArrayList<PendingAssistExtras>();
703
704    /**
705     * Process management.
706     */
707    final ProcessList mProcessList = new ProcessList();
708
709    /**
710     * All of the applications we currently have running organized by name.
711     * The keys are strings of the application package name (as
712     * returned by the package manager), and the keys are ApplicationRecord
713     * objects.
714     */
715    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
716
717    /**
718     * Tracking long-term execution of processes to look for abuse and other
719     * bad app behavior.
720     */
721    final ProcessStatsService mProcessStats;
722
723    /**
724     * The currently running isolated processes.
725     */
726    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
727
728    /**
729     * Counter for assigning isolated process uids, to avoid frequently reusing the
730     * same ones.
731     */
732    int mNextIsolatedProcessUid = 0;
733
734    /**
735     * The currently running heavy-weight process, if any.
736     */
737    ProcessRecord mHeavyWeightProcess = null;
738
739    /**
740     * All of the processes we currently have running organized by pid.
741     * The keys are the pid running the application.
742     *
743     * <p>NOTE: This object is protected by its own lock, NOT the global
744     * activity manager lock!
745     */
746    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
747
748    /**
749     * All of the processes that have been forced to be foreground.  The key
750     * is the pid of the caller who requested it (we hold a death
751     * link on it).
752     */
753    abstract class ForegroundToken implements IBinder.DeathRecipient {
754        int pid;
755        IBinder token;
756    }
757    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
758
759    /**
760     * List of records for processes that someone had tried to start before the
761     * system was ready.  We don't start them at that point, but ensure they
762     * are started by the time booting is complete.
763     */
764    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of persistent applications that are in the process
768     * of being started.
769     */
770    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Processes that are being forcibly torn down.
774     */
775    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of running applications, sorted by recent usage.
779     * The first entry in the list is the least recently used.
780     */
781    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Where in mLruProcesses that the processes hosting activities start.
785     */
786    int mLruProcessActivityStart = 0;
787
788    /**
789     * Where in mLruProcesses that the processes hosting services start.
790     * This is after (lower index) than mLruProcessesActivityStart.
791     */
792    int mLruProcessServiceStart = 0;
793
794    /**
795     * List of processes that should gc as soon as things are idle.
796     */
797    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
798
799    /**
800     * Processes we want to collect PSS data from.
801     */
802    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
803
804    private boolean mBinderTransactionTrackingEnabled = false;
805
806    /**
807     * Last time we requested PSS data of all processes.
808     */
809    long mLastFullPssTime = SystemClock.uptimeMillis();
810
811    /**
812     * If set, the next time we collect PSS data we should do a full collection
813     * with data from native processes and the kernel.
814     */
815    boolean mFullPssPending = false;
816
817    /**
818     * This is the process holding what we currently consider to be
819     * the "home" activity.
820     */
821    ProcessRecord mHomeProcess;
822
823    /**
824     * This is the process holding the activity the user last visited that
825     * is in a different process from the one they are currently in.
826     */
827    ProcessRecord mPreviousProcess;
828
829    /**
830     * The time at which the previous process was last visible.
831     */
832    long mPreviousProcessVisibleTime;
833
834    /**
835     * Track all uids that have actively running processes.
836     */
837    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
838
839    /**
840     * This is for verifying the UID report flow.
841     */
842    static final boolean VALIDATE_UID_STATES = true;
843    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
844
845    /**
846     * Packages that the user has asked to have run in screen size
847     * compatibility mode instead of filling the screen.
848     */
849    final CompatModePackages mCompatModePackages;
850
851    /**
852     * Set of IntentSenderRecord objects that are currently active.
853     */
854    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
855            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
856
857    /**
858     * Fingerprints (hashCode()) of stack traces that we've
859     * already logged DropBox entries for.  Guarded by itself.  If
860     * something (rogue user app) forces this over
861     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
862     */
863    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
864    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
865
866    /**
867     * Strict Mode background batched logging state.
868     *
869     * The string buffer is guarded by itself, and its lock is also
870     * used to determine if another batched write is already
871     * in-flight.
872     */
873    private final StringBuilder mStrictModeBuffer = new StringBuilder();
874
875    /**
876     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
877     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
878     */
879    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
880
881    /**
882     * Resolver for broadcast intents to registered receivers.
883     * Holds BroadcastFilter (subclass of IntentFilter).
884     */
885    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
886            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
887        @Override
888        protected boolean allowFilterResult(
889                BroadcastFilter filter, List<BroadcastFilter> dest) {
890            IBinder target = filter.receiverList.receiver.asBinder();
891            for (int i = dest.size() - 1; i >= 0; i--) {
892                if (dest.get(i).receiverList.receiver.asBinder() == target) {
893                    return false;
894                }
895            }
896            return true;
897        }
898
899        @Override
900        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
901            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
902                    || userId == filter.owningUserId) {
903                return super.newResult(filter, match, userId);
904            }
905            return null;
906        }
907
908        @Override
909        protected BroadcastFilter[] newArray(int size) {
910            return new BroadcastFilter[size];
911        }
912
913        @Override
914        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
915            return packageName.equals(filter.packageName);
916        }
917    };
918
919    /**
920     * State of all active sticky broadcasts per user.  Keys are the action of the
921     * sticky Intent, values are an ArrayList of all broadcasted intents with
922     * that action (which should usually be one).  The SparseArray is keyed
923     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
924     * for stickies that are sent to all users.
925     */
926    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
927            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
928
929    final ActiveServices mServices;
930
931    final static class Association {
932        final int mSourceUid;
933        final String mSourceProcess;
934        final int mTargetUid;
935        final ComponentName mTargetComponent;
936        final String mTargetProcess;
937
938        int mCount;
939        long mTime;
940
941        int mNesting;
942        long mStartTime;
943
944        // states of the source process when the bind occurred.
945        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
946        long mLastStateUptime;
947        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
948                - ActivityManager.MIN_PROCESS_STATE+1];
949
950        Association(int sourceUid, String sourceProcess, int targetUid,
951                ComponentName targetComponent, String targetProcess) {
952            mSourceUid = sourceUid;
953            mSourceProcess = sourceProcess;
954            mTargetUid = targetUid;
955            mTargetComponent = targetComponent;
956            mTargetProcess = targetProcess;
957        }
958    }
959
960    /**
961     * When service association tracking is enabled, this is all of the associations we
962     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
963     * -> association data.
964     */
965    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
966            mAssociations = new SparseArray<>();
967    boolean mTrackingAssociations;
968
969    /**
970     * Backup/restore process management
971     */
972    String mBackupAppName = null;
973    BackupRecord mBackupTarget = null;
974
975    final ProviderMap mProviderMap;
976
977    /**
978     * List of content providers who have clients waiting for them.  The
979     * application is currently being launched and the provider will be
980     * removed from this list once it is published.
981     */
982    final ArrayList<ContentProviderRecord> mLaunchingProviders
983            = new ArrayList<ContentProviderRecord>();
984
985    /**
986     * File storing persisted {@link #mGrantedUriPermissions}.
987     */
988    private final AtomicFile mGrantFile;
989
990    /** XML constants used in {@link #mGrantFile} */
991    private static final String TAG_URI_GRANTS = "uri-grants";
992    private static final String TAG_URI_GRANT = "uri-grant";
993    private static final String ATTR_USER_HANDLE = "userHandle";
994    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
995    private static final String ATTR_TARGET_USER_ID = "targetUserId";
996    private static final String ATTR_SOURCE_PKG = "sourcePkg";
997    private static final String ATTR_TARGET_PKG = "targetPkg";
998    private static final String ATTR_URI = "uri";
999    private static final String ATTR_MODE_FLAGS = "modeFlags";
1000    private static final String ATTR_CREATED_TIME = "createdTime";
1001    private static final String ATTR_PREFIX = "prefix";
1002
1003    /**
1004     * Global set of specific {@link Uri} permissions that have been granted.
1005     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1006     * to {@link UriPermission#uri} to {@link UriPermission}.
1007     */
1008    @GuardedBy("this")
1009    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1010            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1011
1012    public static class GrantUri {
1013        public final int sourceUserId;
1014        public final Uri uri;
1015        public boolean prefix;
1016
1017        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1018            this.sourceUserId = sourceUserId;
1019            this.uri = uri;
1020            this.prefix = prefix;
1021        }
1022
1023        @Override
1024        public int hashCode() {
1025            int hashCode = 1;
1026            hashCode = 31 * hashCode + sourceUserId;
1027            hashCode = 31 * hashCode + uri.hashCode();
1028            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1029            return hashCode;
1030        }
1031
1032        @Override
1033        public boolean equals(Object o) {
1034            if (o instanceof GrantUri) {
1035                GrantUri other = (GrantUri) o;
1036                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1037                        && prefix == other.prefix;
1038            }
1039            return false;
1040        }
1041
1042        @Override
1043        public String toString() {
1044            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1045            if (prefix) result += " [prefix]";
1046            return result;
1047        }
1048
1049        public String toSafeString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1056            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1057                    ContentProvider.getUriWithoutUserId(uri), false);
1058        }
1059    }
1060
1061    CoreSettingsObserver mCoreSettingsObserver;
1062
1063    FontScaleSettingObserver mFontScaleSettingObserver;
1064
1065    private final class FontScaleSettingObserver extends ContentObserver {
1066        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1067
1068        public FontScaleSettingObserver() {
1069            super(mHandler);
1070            ContentResolver resolver = mContext.getContentResolver();
1071            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1072        }
1073
1074        @Override
1075        public void onChange(boolean selfChange, Uri uri) {
1076            if (mFontScaleUri.equals(uri)) {
1077                updateFontScaleIfNeeded();
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Thread-local storage used to carry caller permissions over through
1084     * indirect content-provider access.
1085     */
1086    private class Identity {
1087        public final IBinder token;
1088        public final int pid;
1089        public final int uid;
1090
1091        Identity(IBinder _token, int _pid, int _uid) {
1092            token = _token;
1093            pid = _pid;
1094            uid = _uid;
1095        }
1096    }
1097
1098    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1099
1100    /**
1101     * All information we have collected about the runtime performance of
1102     * any user id that can impact battery performance.
1103     */
1104    final BatteryStatsService mBatteryStatsService;
1105
1106    /**
1107     * Information about component usage
1108     */
1109    UsageStatsManagerInternal mUsageStatsService;
1110
1111    /**
1112     * Access to DeviceIdleController service.
1113     */
1114    DeviceIdleController.LocalService mLocalDeviceIdleController;
1115
1116    /**
1117     * Information about and control over application operations
1118     */
1119    final AppOpsService mAppOpsService;
1120
1121    /**
1122     * Current configuration information.  HistoryRecord objects are given
1123     * a reference to this object to indicate which configuration they are
1124     * currently running in, so this object must be kept immutable.
1125     */
1126    Configuration mConfiguration = new Configuration();
1127
1128    /**
1129     * Current sequencing integer of the configuration, for skipping old
1130     * configurations.
1131     */
1132    int mConfigurationSeq = 0;
1133
1134    boolean mSuppressResizeConfigChanges = false;
1135
1136    /**
1137     * Hardware-reported OpenGLES version.
1138     */
1139    final int GL_ES_VERSION;
1140
1141    /**
1142     * List of initialization arguments to pass to all processes when binding applications to them.
1143     * For example, references to the commonly used services.
1144     */
1145    HashMap<String, IBinder> mAppBindArgs;
1146
1147    /**
1148     * Temporary to avoid allocations.  Protected by main lock.
1149     */
1150    final StringBuilder mStringBuilder = new StringBuilder(256);
1151
1152    /**
1153     * Used to control how we initialize the service.
1154     */
1155    ComponentName mTopComponent;
1156    String mTopAction = Intent.ACTION_MAIN;
1157    String mTopData;
1158
1159    volatile boolean mProcessesReady = false;
1160    volatile boolean mSystemReady = false;
1161    volatile boolean mOnBattery = false;
1162    volatile int mFactoryTest;
1163
1164    @GuardedBy("this") boolean mBooting = false;
1165    @GuardedBy("this") boolean mCallFinishBooting = false;
1166    @GuardedBy("this") boolean mBootAnimationComplete = false;
1167    @GuardedBy("this") boolean mLaunchWarningShown = false;
1168    @GuardedBy("this") boolean mCheckedForSetup = false;
1169
1170    Context mContext;
1171
1172    /**
1173     * The time at which we will allow normal application switches again,
1174     * after a call to {@link #stopAppSwitches()}.
1175     */
1176    long mAppSwitchesAllowedTime;
1177
1178    /**
1179     * This is set to true after the first switch after mAppSwitchesAllowedTime
1180     * is set; any switches after that will clear the time.
1181     */
1182    boolean mDidAppSwitch;
1183
1184    /**
1185     * Last time (in realtime) at which we checked for power usage.
1186     */
1187    long mLastPowerCheckRealtime;
1188
1189    /**
1190     * Last time (in uptime) at which we checked for power usage.
1191     */
1192    long mLastPowerCheckUptime;
1193
1194    /**
1195     * Set while we are wanting to sleep, to prevent any
1196     * activities from being started/resumed.
1197     */
1198    private boolean mSleeping = false;
1199
1200    /**
1201     * The process state used for processes that are running the top activities.
1202     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1203     */
1204    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1205
1206    /**
1207     * Set while we are running a voice interaction.  This overrides
1208     * sleeping while it is active.
1209     */
1210    private IVoiceInteractionSession mRunningVoice;
1211
1212    /**
1213     * For some direct access we need to power manager.
1214     */
1215    PowerManagerInternal mLocalPowerManager;
1216
1217    /**
1218     * We want to hold a wake lock while running a voice interaction session, since
1219     * this may happen with the screen off and we need to keep the CPU running to
1220     * be able to continue to interact with the user.
1221     */
1222    PowerManager.WakeLock mVoiceWakeLock;
1223
1224    /**
1225     * State of external calls telling us if the device is awake or asleep.
1226     */
1227    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1228
1229    /**
1230     * A list of tokens that cause the top activity to be put to sleep.
1231     * They are used by components that may hide and block interaction with underlying
1232     * activities.
1233     */
1234    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1235
1236    static final int LOCK_SCREEN_HIDDEN = 0;
1237    static final int LOCK_SCREEN_LEAVING = 1;
1238    static final int LOCK_SCREEN_SHOWN = 2;
1239    /**
1240     * State of external call telling us if the lock screen is shown.
1241     */
1242    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1243
1244    /**
1245     * Set if we are shutting down the system, similar to sleeping.
1246     */
1247    boolean mShuttingDown = false;
1248
1249    /**
1250     * Current sequence id for oom_adj computation traversal.
1251     */
1252    int mAdjSeq = 0;
1253
1254    /**
1255     * Current sequence id for process LRU updating.
1256     */
1257    int mLruSeq = 0;
1258
1259    /**
1260     * Keep track of the non-cached/empty process we last found, to help
1261     * determine how to distribute cached/empty processes next time.
1262     */
1263    int mNumNonCachedProcs = 0;
1264
1265    /**
1266     * Keep track of the number of cached hidden procs, to balance oom adj
1267     * distribution between those and empty procs.
1268     */
1269    int mNumCachedHiddenProcs = 0;
1270
1271    /**
1272     * Keep track of the number of service processes we last found, to
1273     * determine on the next iteration which should be B services.
1274     */
1275    int mNumServiceProcs = 0;
1276    int mNewNumAServiceProcs = 0;
1277    int mNewNumServiceProcs = 0;
1278
1279    /**
1280     * Allow the current computed overall memory level of the system to go down?
1281     * This is set to false when we are killing processes for reasons other than
1282     * memory management, so that the now smaller process list will not be taken as
1283     * an indication that memory is tighter.
1284     */
1285    boolean mAllowLowerMemLevel = false;
1286
1287    /**
1288     * The last computed memory level, for holding when we are in a state that
1289     * processes are going away for other reasons.
1290     */
1291    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1292
1293    /**
1294     * The last total number of process we have, to determine if changes actually look
1295     * like a shrinking number of process due to lower RAM.
1296     */
1297    int mLastNumProcesses;
1298
1299    /**
1300     * The uptime of the last time we performed idle maintenance.
1301     */
1302    long mLastIdleTime = SystemClock.uptimeMillis();
1303
1304    /**
1305     * Total time spent with RAM that has been added in the past since the last idle time.
1306     */
1307    long mLowRamTimeSinceLastIdle = 0;
1308
1309    /**
1310     * If RAM is currently low, when that horrible situation started.
1311     */
1312    long mLowRamStartTime = 0;
1313
1314    /**
1315     * For reporting to battery stats the current top application.
1316     */
1317    private String mCurResumedPackage = null;
1318    private int mCurResumedUid = -1;
1319
1320    /**
1321     * For reporting to battery stats the apps currently running foreground
1322     * service.  The ProcessMap is package/uid tuples; each of these contain
1323     * an array of the currently foreground processes.
1324     */
1325    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1326            = new ProcessMap<ArrayList<ProcessRecord>>();
1327
1328    /**
1329     * This is set if we had to do a delayed dexopt of an app before launching
1330     * it, to increase the ANR timeouts in that case.
1331     */
1332    boolean mDidDexOpt;
1333
1334    /**
1335     * Set if the systemServer made a call to enterSafeMode.
1336     */
1337    boolean mSafeMode;
1338
1339    /**
1340     * If true, we are running under a test environment so will sample PSS from processes
1341     * much more rapidly to try to collect better data when the tests are rapidly
1342     * running through apps.
1343     */
1344    boolean mTestPssMode = false;
1345
1346    String mDebugApp = null;
1347    boolean mWaitForDebugger = false;
1348    boolean mDebugTransient = false;
1349    String mOrigDebugApp = null;
1350    boolean mOrigWaitForDebugger = false;
1351    boolean mAlwaysFinishActivities = false;
1352    boolean mLenientBackgroundCheck = false;
1353    boolean mForceResizableActivities;
1354    boolean mSupportsMultiWindow;
1355    boolean mSupportsFreeformWindowManagement;
1356    boolean mSupportsPictureInPicture;
1357    boolean mSupportsLeanbackOnly;
1358    Rect mDefaultPinnedStackBounds;
1359    IActivityController mController = null;
1360    boolean mControllerIsAMonkey = false;
1361    String mProfileApp = null;
1362    ProcessRecord mProfileProc = null;
1363    String mProfileFile;
1364    ParcelFileDescriptor mProfileFd;
1365    int mSamplingInterval = 0;
1366    boolean mAutoStopProfiler = false;
1367    int mProfileType = 0;
1368    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1369    String mMemWatchDumpProcName;
1370    String mMemWatchDumpFile;
1371    int mMemWatchDumpPid;
1372    int mMemWatchDumpUid;
1373    String mTrackAllocationApp = null;
1374    String mNativeDebuggingApp = null;
1375
1376    final long[] mTmpLong = new long[2];
1377
1378    static final class ProcessChangeItem {
1379        static final int CHANGE_ACTIVITIES = 1<<0;
1380        static final int CHANGE_PROCESS_STATE = 1<<1;
1381        int changes;
1382        int uid;
1383        int pid;
1384        int processState;
1385        boolean foregroundActivities;
1386    }
1387
1388    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1389    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1390
1391    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1392    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1393
1394    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1395    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1396
1397    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1398    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1399
1400    /**
1401     * Runtime CPU use collection thread.  This object's lock is used to
1402     * perform synchronization with the thread (notifying it to run).
1403     */
1404    final Thread mProcessCpuThread;
1405
1406    /**
1407     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1408     * Must acquire this object's lock when accessing it.
1409     * NOTE: this lock will be held while doing long operations (trawling
1410     * through all processes in /proc), so it should never be acquired by
1411     * any critical paths such as when holding the main activity manager lock.
1412     */
1413    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1414            MONITOR_THREAD_CPU_USAGE);
1415    final AtomicLong mLastCpuTime = new AtomicLong(0);
1416    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1417
1418    long mLastWriteTime = 0;
1419
1420    /**
1421     * Used to retain an update lock when the foreground activity is in
1422     * immersive mode.
1423     */
1424    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1425
1426    /**
1427     * Set to true after the system has finished booting.
1428     */
1429    boolean mBooted = false;
1430
1431    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1432    int mProcessLimitOverride = -1;
1433
1434    WindowManagerService mWindowManager;
1435    final ActivityThread mSystemThread;
1436
1437    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1438        final ProcessRecord mApp;
1439        final int mPid;
1440        final IApplicationThread mAppThread;
1441
1442        AppDeathRecipient(ProcessRecord app, int pid,
1443                IApplicationThread thread) {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "New death recipient " + this
1446                + " for thread " + thread.asBinder());
1447            mApp = app;
1448            mPid = pid;
1449            mAppThread = thread;
1450        }
1451
1452        @Override
1453        public void binderDied() {
1454            if (DEBUG_ALL) Slog.v(
1455                TAG, "Death received in " + this
1456                + " for thread " + mAppThread.asBinder());
1457            synchronized(ActivityManagerService.this) {
1458                appDiedLocked(mApp, mPid, mAppThread, true);
1459            }
1460        }
1461    }
1462
1463    static final int SHOW_ERROR_UI_MSG = 1;
1464    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1465    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1466    static final int UPDATE_CONFIGURATION_MSG = 4;
1467    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1468    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1469    static final int SERVICE_TIMEOUT_MSG = 12;
1470    static final int UPDATE_TIME_ZONE = 13;
1471    static final int SHOW_UID_ERROR_UI_MSG = 14;
1472    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1473    static final int PROC_START_TIMEOUT_MSG = 20;
1474    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1475    static final int KILL_APPLICATION_MSG = 22;
1476    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1477    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1478    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1479    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1480    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1481    static final int CLEAR_DNS_CACHE_MSG = 28;
1482    static final int UPDATE_HTTP_PROXY_MSG = 29;
1483    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1484    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1485    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1486    static final int REPORT_MEM_USAGE_MSG = 33;
1487    static final int REPORT_USER_SWITCH_MSG = 34;
1488    static final int CONTINUE_USER_SWITCH_MSG = 35;
1489    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1490    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1491    static final int PERSIST_URI_GRANTS_MSG = 38;
1492    static final int REQUEST_ALL_PSS_MSG = 39;
1493    static final int START_PROFILES_MSG = 40;
1494    static final int UPDATE_TIME = 41;
1495    static final int SYSTEM_USER_START_MSG = 42;
1496    static final int SYSTEM_USER_CURRENT_MSG = 43;
1497    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1498    static final int FINISH_BOOTING_MSG = 45;
1499    static final int START_USER_SWITCH_UI_MSG = 46;
1500    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1501    static final int DISMISS_DIALOG_UI_MSG = 48;
1502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1503    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1504    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1505    static final int DELETE_DUMPHEAP_MSG = 52;
1506    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1507    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1508    static final int REPORT_TIME_TRACKER_MSG = 55;
1509    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1510    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1511    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1513    static final int IDLE_UIDS_MSG = 60;
1514    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1515    static final int LOG_STACK_STATE = 62;
1516    static final int VR_MODE_CHANGE_MSG = 63;
1517    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1518    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1519    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1520    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1521    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1522    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1523    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1524
1525    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1526    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1527    static final int FIRST_COMPAT_MODE_MSG = 300;
1528    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1529
1530    static ServiceThread sKillThread = null;
1531    static KillHandler sKillHandler = null;
1532
1533    CompatModeDialog mCompatModeDialog;
1534    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1535    long mLastMemUsageReportTime = 0;
1536
1537    /**
1538     * Flag whether the current user is a "monkey", i.e. whether
1539     * the UI is driven by a UI automation tool.
1540     */
1541    private boolean mUserIsMonkey;
1542
1543    /** Flag whether the device has a Recents UI */
1544    boolean mHasRecents;
1545
1546    /** The dimensions of the thumbnails in the Recents UI. */
1547    int mThumbnailWidth;
1548    int mThumbnailHeight;
1549    float mFullscreenThumbnailScale;
1550
1551    final ServiceThread mHandlerThread;
1552    final MainHandler mHandler;
1553    final UiHandler mUiHandler;
1554
1555    PackageManagerInternal mPackageManagerInt;
1556
1557    // VoiceInteraction session ID that changes for each new request except when
1558    // being called for multiwindow assist in a single session.
1559    private int mViSessionId = 1000;
1560
1561    final boolean mPermissionReviewRequired;
1562
1563    final class KillHandler extends Handler {
1564        static final int KILL_PROCESS_GROUP_MSG = 4000;
1565
1566        public KillHandler(Looper looper) {
1567            super(looper, null, true);
1568        }
1569
1570        @Override
1571        public void handleMessage(Message msg) {
1572            switch (msg.what) {
1573                case KILL_PROCESS_GROUP_MSG:
1574                {
1575                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1576                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1577                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1578                }
1579                break;
1580
1581                default:
1582                    super.handleMessage(msg);
1583            }
1584        }
1585    }
1586
1587    final class UiHandler extends Handler {
1588        public UiHandler() {
1589            super(com.android.server.UiThread.get().getLooper(), null, true);
1590        }
1591
1592        @Override
1593        public void handleMessage(Message msg) {
1594            switch (msg.what) {
1595            case SHOW_ERROR_UI_MSG: {
1596                mAppErrors.handleShowAppErrorUi(msg);
1597                ensureBootCompleted();
1598            } break;
1599            case SHOW_NOT_RESPONDING_UI_MSG: {
1600                mAppErrors.handleShowAnrUi(msg);
1601                ensureBootCompleted();
1602            } break;
1603            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605                synchronized (ActivityManagerService.this) {
1606                    ProcessRecord proc = (ProcessRecord) data.get("app");
1607                    if (proc == null) {
1608                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1609                        break;
1610                    }
1611                    if (proc.crashDialog != null) {
1612                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1613                        return;
1614                    }
1615                    AppErrorResult res = (AppErrorResult) data.get("result");
1616                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617                        Dialog d = new StrictModeViolationDialog(mContext,
1618                                ActivityManagerService.this, res, proc);
1619                        d.show();
1620                        proc.crashDialog = d;
1621                    } else {
1622                        // The device is asleep, so just pretend that the user
1623                        // saw a crash dialog and hit "force quit".
1624                        res.set(0);
1625                    }
1626                }
1627                ensureBootCompleted();
1628            } break;
1629            case SHOW_FACTORY_ERROR_UI_MSG: {
1630                Dialog d = new FactoryErrorDialog(
1631                    mContext, msg.getData().getCharSequence("msg"));
1632                d.show();
1633                ensureBootCompleted();
1634            } break;
1635            case WAIT_FOR_DEBUGGER_UI_MSG: {
1636                synchronized (ActivityManagerService.this) {
1637                    ProcessRecord app = (ProcessRecord)msg.obj;
1638                    if (msg.arg1 != 0) {
1639                        if (!app.waitedForDebugger) {
1640                            Dialog d = new AppWaitingForDebuggerDialog(
1641                                    ActivityManagerService.this,
1642                                    mContext, app);
1643                            app.waitDialog = d;
1644                            app.waitedForDebugger = true;
1645                            d.show();
1646                        }
1647                    } else {
1648                        if (app.waitDialog != null) {
1649                            app.waitDialog.dismiss();
1650                            app.waitDialog = null;
1651                        }
1652                    }
1653                }
1654            } break;
1655            case SHOW_UID_ERROR_UI_MSG: {
1656                if (mShowDialogs) {
1657                    AlertDialog d = new BaseErrorDialog(mContext);
1658                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659                    d.setCancelable(false);
1660                    d.setTitle(mContext.getText(R.string.android_system_label));
1661                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1664                    d.show();
1665                }
1666            } break;
1667            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1668                if (mShowDialogs) {
1669                    AlertDialog d = new BaseErrorDialog(mContext);
1670                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671                    d.setCancelable(false);
1672                    d.setTitle(mContext.getText(R.string.android_system_label));
1673                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1676                    d.show();
1677                }
1678            } break;
1679            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680                synchronized (ActivityManagerService.this) {
1681                    ActivityRecord ar = (ActivityRecord) msg.obj;
1682                    if (mCompatModeDialog != null) {
1683                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1684                                ar.info.applicationInfo.packageName)) {
1685                            return;
1686                        }
1687                        mCompatModeDialog.dismiss();
1688                        mCompatModeDialog = null;
1689                    }
1690                    if (ar != null && false) {
1691                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1692                                ar.packageName)) {
1693                            int mode = mCompatModePackages.computeCompatModeLocked(
1694                                    ar.info.applicationInfo);
1695                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697                                mCompatModeDialog = new CompatModeDialog(
1698                                        ActivityManagerService.this, mContext,
1699                                        ar.info.applicationInfo);
1700                                mCompatModeDialog.show();
1701                            }
1702                        }
1703                    }
1704                }
1705                break;
1706            }
1707            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1708                synchronized (ActivityManagerService.this) {
1709                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1710                    if (mUnsupportedDisplaySizeDialog != null) {
1711                        mUnsupportedDisplaySizeDialog.dismiss();
1712                        mUnsupportedDisplaySizeDialog = null;
1713                    }
1714                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1715                            ar.packageName)) {
1716                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1717                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1718                        mUnsupportedDisplaySizeDialog.show();
1719                    }
1720                }
1721                break;
1722            }
1723            case START_USER_SWITCH_UI_MSG: {
1724                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1725                break;
1726            }
1727            case DISMISS_DIALOG_UI_MSG: {
1728                final Dialog d = (Dialog) msg.obj;
1729                d.dismiss();
1730                break;
1731            }
1732            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1733                dispatchProcessesChanged();
1734                break;
1735            }
1736            case DISPATCH_PROCESS_DIED_UI_MSG: {
1737                final int pid = msg.arg1;
1738                final int uid = msg.arg2;
1739                dispatchProcessDied(pid, uid);
1740                break;
1741            }
1742            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1743                dispatchUidsChanged();
1744            } break;
1745            }
1746        }
1747    }
1748
1749    final class MainHandler extends Handler {
1750        public MainHandler(Looper looper) {
1751            super(looper, null, true);
1752        }
1753
1754        @Override
1755        public void handleMessage(Message msg) {
1756            switch (msg.what) {
1757            case UPDATE_CONFIGURATION_MSG: {
1758                final ContentResolver resolver = mContext.getContentResolver();
1759                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1760                        msg.arg1);
1761            } break;
1762            case GC_BACKGROUND_PROCESSES_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    performAppGcsIfAppropriateLocked();
1765                }
1766            } break;
1767            case SERVICE_TIMEOUT_MSG: {
1768                if (mDidDexOpt) {
1769                    mDidDexOpt = false;
1770                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1771                    nmsg.obj = msg.obj;
1772                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1773                    return;
1774                }
1775                mServices.serviceTimeout((ProcessRecord)msg.obj);
1776            } break;
1777            case UPDATE_TIME_ZONE: {
1778                synchronized (ActivityManagerService.this) {
1779                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1780                        ProcessRecord r = mLruProcesses.get(i);
1781                        if (r.thread != null) {
1782                            try {
1783                                r.thread.updateTimeZone();
1784                            } catch (RemoteException ex) {
1785                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1786                            }
1787                        }
1788                    }
1789                }
1790            } break;
1791            case CLEAR_DNS_CACHE_MSG: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.clearDnsCache();
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804            } break;
1805            case UPDATE_HTTP_PROXY_MSG: {
1806                ProxyInfo proxy = (ProxyInfo)msg.obj;
1807                String host = "";
1808                String port = "";
1809                String exclList = "";
1810                Uri pacFileUrl = Uri.EMPTY;
1811                if (proxy != null) {
1812                    host = proxy.getHost();
1813                    port = Integer.toString(proxy.getPort());
1814                    exclList = proxy.getExclusionListAsString();
1815                    pacFileUrl = proxy.getPacFileUrl();
1816                }
1817                synchronized (ActivityManagerService.this) {
1818                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1819                        ProcessRecord r = mLruProcesses.get(i);
1820                        if (r.thread != null) {
1821                            try {
1822                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1823                            } catch (RemoteException ex) {
1824                                Slog.w(TAG, "Failed to update http proxy for: " +
1825                                        r.info.processName);
1826                            }
1827                        }
1828                    }
1829                }
1830            } break;
1831            case PROC_START_TIMEOUT_MSG: {
1832                if (mDidDexOpt) {
1833                    mDidDexOpt = false;
1834                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1835                    nmsg.obj = msg.obj;
1836                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1837                    return;
1838                }
1839                ProcessRecord app = (ProcessRecord)msg.obj;
1840                synchronized (ActivityManagerService.this) {
1841                    processStartTimedOutLocked(app);
1842                }
1843            } break;
1844            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1845                ProcessRecord app = (ProcessRecord)msg.obj;
1846                synchronized (ActivityManagerService.this) {
1847                    processContentProviderPublishTimedOutLocked(app);
1848                }
1849            } break;
1850            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1851                synchronized (ActivityManagerService.this) {
1852                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1853                }
1854            } break;
1855            case KILL_APPLICATION_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    final int appId = msg.arg1;
1858                    final int userId = msg.arg2;
1859                    Bundle bundle = (Bundle)msg.obj;
1860                    String pkg = bundle.getString("pkg");
1861                    String reason = bundle.getString("reason");
1862                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1863                            false, userId, reason);
1864                }
1865            } break;
1866            case FINALIZE_PENDING_INTENT_MSG: {
1867                ((PendingIntentRecord)msg.obj).completeFinalize();
1868            } break;
1869            case POST_HEAVY_NOTIFICATION_MSG: {
1870                INotificationManager inm = NotificationManager.getService();
1871                if (inm == null) {
1872                    return;
1873                }
1874
1875                ActivityRecord root = (ActivityRecord)msg.obj;
1876                ProcessRecord process = root.app;
1877                if (process == null) {
1878                    return;
1879                }
1880
1881                try {
1882                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1883                    String text = mContext.getString(R.string.heavy_weight_notification,
1884                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1885                    Notification notification = new Notification.Builder(context)
1886                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1887                            .setWhen(0)
1888                            .setOngoing(true)
1889                            .setTicker(text)
1890                            .setColor(mContext.getColor(
1891                                    com.android.internal.R.color.system_notification_accent_color))
1892                            .setContentTitle(text)
1893                            .setContentText(
1894                                    mContext.getText(R.string.heavy_weight_notification_detail))
1895                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1896                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1897                                    new UserHandle(root.userId)))
1898                            .build();
1899                    try {
1900                        int[] outId = new int[1];
1901                        inm.enqueueNotificationWithTag("android", "android", null,
1902                                R.string.heavy_weight_notification,
1903                                notification, outId, root.userId);
1904                    } catch (RuntimeException e) {
1905                        Slog.w(ActivityManagerService.TAG,
1906                                "Error showing notification for heavy-weight app", e);
1907                    } catch (RemoteException e) {
1908                    }
1909                } catch (NameNotFoundException e) {
1910                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1911                }
1912            } break;
1913            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1914                INotificationManager inm = NotificationManager.getService();
1915                if (inm == null) {
1916                    return;
1917                }
1918                try {
1919                    inm.cancelNotificationWithTag("android", null,
1920                            R.string.heavy_weight_notification,  msg.arg1);
1921                } catch (RuntimeException e) {
1922                    Slog.w(ActivityManagerService.TAG,
1923                            "Error canceling notification for service", e);
1924                } catch (RemoteException e) {
1925                }
1926            } break;
1927            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1928                synchronized (ActivityManagerService.this) {
1929                    checkExcessivePowerUsageLocked(true);
1930                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1932                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1933                }
1934            } break;
1935            case REPORT_MEM_USAGE_MSG: {
1936                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1937                Thread thread = new Thread() {
1938                    @Override public void run() {
1939                        reportMemUsage(memInfos);
1940                    }
1941                };
1942                thread.start();
1943                break;
1944            }
1945            case REPORT_USER_SWITCH_MSG: {
1946                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1947                break;
1948            }
1949            case CONTINUE_USER_SWITCH_MSG: {
1950                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1951                break;
1952            }
1953            case USER_SWITCH_TIMEOUT_MSG: {
1954                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1955                break;
1956            }
1957            case IMMERSIVE_MODE_LOCK_MSG: {
1958                final boolean nextState = (msg.arg1 != 0);
1959                if (mUpdateLock.isHeld() != nextState) {
1960                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1961                            "Applying new update lock state '" + nextState
1962                            + "' for " + (ActivityRecord)msg.obj);
1963                    if (nextState) {
1964                        mUpdateLock.acquire();
1965                    } else {
1966                        mUpdateLock.release();
1967                    }
1968                }
1969                break;
1970            }
1971            case PERSIST_URI_GRANTS_MSG: {
1972                writeGrantedUriPermissions();
1973                break;
1974            }
1975            case REQUEST_ALL_PSS_MSG: {
1976                synchronized (ActivityManagerService.this) {
1977                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1978                }
1979                break;
1980            }
1981            case START_PROFILES_MSG: {
1982                synchronized (ActivityManagerService.this) {
1983                    mUserController.startProfilesLocked();
1984                }
1985                break;
1986            }
1987            case UPDATE_TIME: {
1988                synchronized (ActivityManagerService.this) {
1989                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1990                        ProcessRecord r = mLruProcesses.get(i);
1991                        if (r.thread != null) {
1992                            try {
1993                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1994                            } catch (RemoteException ex) {
1995                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1996                            }
1997                        }
1998                    }
1999                }
2000                break;
2001            }
2002            case SYSTEM_USER_START_MSG: {
2003                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2004                        Integer.toString(msg.arg1), msg.arg1);
2005                mSystemServiceManager.startUser(msg.arg1);
2006                break;
2007            }
2008            case SYSTEM_USER_UNLOCK_MSG: {
2009                final int userId = msg.arg1;
2010                mSystemServiceManager.unlockUser(userId);
2011                synchronized (ActivityManagerService.this) {
2012                    mRecentTasks.loadUserRecentsLocked(userId);
2013                }
2014                if (userId == UserHandle.USER_SYSTEM) {
2015                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2016                }
2017                installEncryptionUnawareProviders(userId);
2018                mUserController.finishUserUnlocked((UserState) msg.obj);
2019                break;
2020            }
2021            case SYSTEM_USER_CURRENT_MSG: {
2022                mBatteryStatsService.noteEvent(
2023                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2024                        Integer.toString(msg.arg2), msg.arg2);
2025                mBatteryStatsService.noteEvent(
2026                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2027                        Integer.toString(msg.arg1), msg.arg1);
2028                mSystemServiceManager.switchUser(msg.arg1);
2029                break;
2030            }
2031            case ENTER_ANIMATION_COMPLETE_MSG: {
2032                synchronized (ActivityManagerService.this) {
2033                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2034                    if (r != null && r.app != null && r.app.thread != null) {
2035                        try {
2036                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2037                        } catch (RemoteException e) {
2038                        }
2039                    }
2040                }
2041                break;
2042            }
2043            case FINISH_BOOTING_MSG: {
2044                if (msg.arg1 != 0) {
2045                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2046                    finishBooting();
2047                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2048                }
2049                if (msg.arg2 != 0) {
2050                    enableScreenAfterBoot();
2051                }
2052                break;
2053            }
2054            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2055                try {
2056                    Locale l = (Locale) msg.obj;
2057                    IBinder service = ServiceManager.getService("mount");
2058                    IMountService mountService = IMountService.Stub.asInterface(service);
2059                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2060                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2061                } catch (RemoteException e) {
2062                    Log.e(TAG, "Error storing locale for decryption UI", e);
2063                }
2064                break;
2065            }
2066            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2067                synchronized (ActivityManagerService.this) {
2068                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2069                        try {
2070                            // Make a one-way callback to the listener
2071                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2072                        } catch (RemoteException e){
2073                            // Handled by the RemoteCallbackList
2074                        }
2075                    }
2076                    mTaskStackListeners.finishBroadcast();
2077                }
2078                break;
2079            }
2080            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2081                synchronized (ActivityManagerService.this) {
2082                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2083                        try {
2084                            // Make a one-way callback to the listener
2085                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2086                        } catch (RemoteException e){
2087                            // Handled by the RemoteCallbackList
2088                        }
2089                    }
2090                    mTaskStackListeners.finishBroadcast();
2091                }
2092                break;
2093            }
2094            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2095                synchronized (ActivityManagerService.this) {
2096                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097                        try {
2098                            // Make a one-way callback to the listener
2099                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2100                        } catch (RemoteException e){
2101                            // Handled by the RemoteCallbackList
2102                        }
2103                    }
2104                    mTaskStackListeners.finishBroadcast();
2105                }
2106                break;
2107            }
2108            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2109                synchronized (ActivityManagerService.this) {
2110                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111                        try {
2112                            // Make a one-way callback to the listener
2113                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2114                        } catch (RemoteException e){
2115                            // Handled by the RemoteCallbackList
2116                        }
2117                    }
2118                    mTaskStackListeners.finishBroadcast();
2119                }
2120                break;
2121            }
2122            case NOTIFY_FORCED_RESIZABLE_MSG: {
2123                synchronized (ActivityManagerService.this) {
2124                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2125                        try {
2126                            // Make a one-way callback to the listener
2127                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2128                                    (String) msg.obj, msg.arg1);
2129                        } catch (RemoteException e){
2130                            // Handled by the RemoteCallbackList
2131                        }
2132                    }
2133                    mTaskStackListeners.finishBroadcast();
2134                }
2135                break;
2136            }
2137                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2138                    synchronized (ActivityManagerService.this) {
2139                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                            try {
2141                                // Make a one-way callback to the listener
2142                                mTaskStackListeners.getBroadcastItem(i)
2143                                        .onActivityDismissingDockedStack();
2144                            } catch (RemoteException e){
2145                                // Handled by the RemoteCallbackList
2146                            }
2147                        }
2148                        mTaskStackListeners.finishBroadcast();
2149                    }
2150                    break;
2151                }
2152            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2153                final int uid = msg.arg1;
2154                final byte[] firstPacket = (byte[]) msg.obj;
2155
2156                synchronized (mPidsSelfLocked) {
2157                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2158                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2159                        if (p.uid == uid) {
2160                            try {
2161                                p.thread.notifyCleartextNetwork(firstPacket);
2162                            } catch (RemoteException ignored) {
2163                            }
2164                        }
2165                    }
2166                }
2167                break;
2168            }
2169            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2170                final String procName;
2171                final int uid;
2172                final long memLimit;
2173                final String reportPackage;
2174                synchronized (ActivityManagerService.this) {
2175                    procName = mMemWatchDumpProcName;
2176                    uid = mMemWatchDumpUid;
2177                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2178                    if (val == null) {
2179                        val = mMemWatchProcesses.get(procName, 0);
2180                    }
2181                    if (val != null) {
2182                        memLimit = val.first;
2183                        reportPackage = val.second;
2184                    } else {
2185                        memLimit = 0;
2186                        reportPackage = null;
2187                    }
2188                }
2189                if (procName == null) {
2190                    return;
2191                }
2192
2193                if (DEBUG_PSS) Slog.d(TAG_PSS,
2194                        "Showing dump heap notification from " + procName + "/" + uid);
2195
2196                INotificationManager inm = NotificationManager.getService();
2197                if (inm == null) {
2198                    return;
2199                }
2200
2201                String text = mContext.getString(R.string.dump_heap_notification, procName);
2202
2203
2204                Intent deleteIntent = new Intent();
2205                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2206                Intent intent = new Intent();
2207                intent.setClassName("android", DumpHeapActivity.class.getName());
2208                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2209                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2210                if (reportPackage != null) {
2211                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2212                }
2213                int userId = UserHandle.getUserId(uid);
2214                Notification notification = new Notification.Builder(mContext)
2215                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2216                        .setWhen(0)
2217                        .setOngoing(true)
2218                        .setAutoCancel(true)
2219                        .setTicker(text)
2220                        .setColor(mContext.getColor(
2221                                com.android.internal.R.color.system_notification_accent_color))
2222                        .setContentTitle(text)
2223                        .setContentText(
2224                                mContext.getText(R.string.dump_heap_notification_detail))
2225                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2226                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2227                                new UserHandle(userId)))
2228                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2229                                deleteIntent, 0, UserHandle.SYSTEM))
2230                        .build();
2231
2232                try {
2233                    int[] outId = new int[1];
2234                    inm.enqueueNotificationWithTag("android", "android", null,
2235                            R.string.dump_heap_notification,
2236                            notification, outId, userId);
2237                } catch (RuntimeException e) {
2238                    Slog.w(ActivityManagerService.TAG,
2239                            "Error showing notification for dump heap", e);
2240                } catch (RemoteException e) {
2241                }
2242            } break;
2243            case DELETE_DUMPHEAP_MSG: {
2244                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2245                        DumpHeapActivity.JAVA_URI,
2246                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2247                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2248                        UserHandle.myUserId());
2249                synchronized (ActivityManagerService.this) {
2250                    mMemWatchDumpFile = null;
2251                    mMemWatchDumpProcName = null;
2252                    mMemWatchDumpPid = -1;
2253                    mMemWatchDumpUid = -1;
2254                }
2255            } break;
2256            case FOREGROUND_PROFILE_CHANGED_MSG: {
2257                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2258            } break;
2259            case REPORT_TIME_TRACKER_MSG: {
2260                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2261                tracker.deliverResult(mContext);
2262            } break;
2263            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2264                mUserController.dispatchUserSwitchComplete(msg.arg1);
2265            } break;
2266            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2267                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2268                try {
2269                    connection.shutdown();
2270                } catch (RemoteException e) {
2271                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2272                }
2273                // Only a UiAutomation can set this flag and now that
2274                // it is finished we make sure it is reset to its default.
2275                mUserIsMonkey = false;
2276            } break;
2277            case APP_BOOST_DEACTIVATE_MSG: {
2278                synchronized(ActivityManagerService.this) {
2279                    if (mIsBoosted) {
2280                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2281                            nativeMigrateFromBoost();
2282                            mIsBoosted = false;
2283                            mBoostStartTime = 0;
2284                        } else {
2285                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2286                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2287                        }
2288                    }
2289                }
2290            } break;
2291            case IDLE_UIDS_MSG: {
2292                idleUids();
2293            } break;
2294            case LOG_STACK_STATE: {
2295                synchronized (ActivityManagerService.this) {
2296                    mStackSupervisor.logStackState();
2297                }
2298            } break;
2299            case VR_MODE_CHANGE_MSG: {
2300                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2301                final ActivityRecord r = (ActivityRecord) msg.obj;
2302                boolean vrMode;
2303                ComponentName requestedPackage;
2304                ComponentName callingPackage;
2305                int userId;
2306                synchronized (ActivityManagerService.this) {
2307                    vrMode = r.requestedVrComponent != null;
2308                    requestedPackage = r.requestedVrComponent;
2309                    userId = r.userId;
2310                    callingPackage = r.info.getComponentName();
2311                    if (mInVrMode != vrMode) {
2312                        mInVrMode = vrMode;
2313                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2314                    }
2315                }
2316                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2317            } break;
2318            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2319                final ActivityRecord r = (ActivityRecord) msg.obj;
2320                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2321                if (needsVrMode) {
2322                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2323                            r.info.getComponentName(), false);
2324                }
2325            } break;
2326            }
2327        }
2328    };
2329
2330    static final int COLLECT_PSS_BG_MSG = 1;
2331
2332    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2333        @Override
2334        public void handleMessage(Message msg) {
2335            switch (msg.what) {
2336            case COLLECT_PSS_BG_MSG: {
2337                long start = SystemClock.uptimeMillis();
2338                MemInfoReader memInfo = null;
2339                synchronized (ActivityManagerService.this) {
2340                    if (mFullPssPending) {
2341                        mFullPssPending = false;
2342                        memInfo = new MemInfoReader();
2343                    }
2344                }
2345                if (memInfo != null) {
2346                    updateCpuStatsNow();
2347                    long nativeTotalPss = 0;
2348                    synchronized (mProcessCpuTracker) {
2349                        final int N = mProcessCpuTracker.countStats();
2350                        for (int j=0; j<N; j++) {
2351                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2352                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2353                                // This is definitely an application process; skip it.
2354                                continue;
2355                            }
2356                            synchronized (mPidsSelfLocked) {
2357                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2358                                    // This is one of our own processes; skip it.
2359                                    continue;
2360                                }
2361                            }
2362                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2363                        }
2364                    }
2365                    memInfo.readMemInfo();
2366                    synchronized (ActivityManagerService.this) {
2367                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2368                                + (SystemClock.uptimeMillis()-start) + "ms");
2369                        final long cachedKb = memInfo.getCachedSizeKb();
2370                        final long freeKb = memInfo.getFreeSizeKb();
2371                        final long zramKb = memInfo.getZramTotalSizeKb();
2372                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2373                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2374                                kernelKb*1024, nativeTotalPss*1024);
2375                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2376                                nativeTotalPss);
2377                    }
2378                }
2379
2380                int num = 0;
2381                long[] tmp = new long[2];
2382                do {
2383                    ProcessRecord proc;
2384                    int procState;
2385                    int pid;
2386                    long lastPssTime;
2387                    synchronized (ActivityManagerService.this) {
2388                        if (mPendingPssProcesses.size() <= 0) {
2389                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2390                                    "Collected PSS of " + num + " processes in "
2391                                    + (SystemClock.uptimeMillis() - start) + "ms");
2392                            mPendingPssProcesses.clear();
2393                            return;
2394                        }
2395                        proc = mPendingPssProcesses.remove(0);
2396                        procState = proc.pssProcState;
2397                        lastPssTime = proc.lastPssTime;
2398                        if (proc.thread != null && procState == proc.setProcState
2399                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2400                                        < SystemClock.uptimeMillis()) {
2401                            pid = proc.pid;
2402                        } else {
2403                            proc = null;
2404                            pid = 0;
2405                        }
2406                    }
2407                    if (proc != null) {
2408                        long pss = Debug.getPss(pid, tmp, null);
2409                        synchronized (ActivityManagerService.this) {
2410                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2411                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2412                                num++;
2413                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2414                                        SystemClock.uptimeMillis());
2415                            }
2416                        }
2417                    }
2418                } while (true);
2419            }
2420            }
2421        }
2422    };
2423
2424    public void setSystemProcess() {
2425        try {
2426            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2427            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2428            ServiceManager.addService("meminfo", new MemBinder(this));
2429            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2430            ServiceManager.addService("dbinfo", new DbBinder(this));
2431            if (MONITOR_CPU_USAGE) {
2432                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2433            }
2434            ServiceManager.addService("permission", new PermissionController(this));
2435            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2436
2437            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2438                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2439            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2440
2441            synchronized (this) {
2442                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2443                app.persistent = true;
2444                app.pid = MY_PID;
2445                app.maxAdj = ProcessList.SYSTEM_ADJ;
2446                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2447                synchronized (mPidsSelfLocked) {
2448                    mPidsSelfLocked.put(app.pid, app);
2449                }
2450                updateLruProcessLocked(app, false, null);
2451                updateOomAdjLocked();
2452            }
2453        } catch (PackageManager.NameNotFoundException e) {
2454            throw new RuntimeException(
2455                    "Unable to find android system package", e);
2456        }
2457    }
2458
2459    public void setWindowManager(WindowManagerService wm) {
2460        mWindowManager = wm;
2461        mStackSupervisor.setWindowManager(wm);
2462        mActivityStarter.setWindowManager(wm);
2463    }
2464
2465    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2466        mUsageStatsService = usageStatsManager;
2467    }
2468
2469    public void startObservingNativeCrashes() {
2470        final NativeCrashListener ncl = new NativeCrashListener(this);
2471        ncl.start();
2472    }
2473
2474    public IAppOpsService getAppOpsService() {
2475        return mAppOpsService;
2476    }
2477
2478    static class MemBinder extends Binder {
2479        ActivityManagerService mActivityManagerService;
2480        MemBinder(ActivityManagerService activityManagerService) {
2481            mActivityManagerService = activityManagerService;
2482        }
2483
2484        @Override
2485        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2486            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2487                    != PackageManager.PERMISSION_GRANTED) {
2488                pw.println("Permission Denial: can't dump meminfo from from pid="
2489                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2490                        + " without permission " + android.Manifest.permission.DUMP);
2491                return;
2492            }
2493
2494            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2495        }
2496    }
2497
2498    static class GraphicsBinder extends Binder {
2499        ActivityManagerService mActivityManagerService;
2500        GraphicsBinder(ActivityManagerService activityManagerService) {
2501            mActivityManagerService = activityManagerService;
2502        }
2503
2504        @Override
2505        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2506            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2507                    != PackageManager.PERMISSION_GRANTED) {
2508                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2509                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2510                        + " without permission " + android.Manifest.permission.DUMP);
2511                return;
2512            }
2513
2514            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2515        }
2516    }
2517
2518    static class DbBinder extends Binder {
2519        ActivityManagerService mActivityManagerService;
2520        DbBinder(ActivityManagerService activityManagerService) {
2521            mActivityManagerService = activityManagerService;
2522        }
2523
2524        @Override
2525        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2526            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2527                    != PackageManager.PERMISSION_GRANTED) {
2528                pw.println("Permission Denial: can't dump dbinfo from from pid="
2529                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2530                        + " without permission " + android.Manifest.permission.DUMP);
2531                return;
2532            }
2533
2534            mActivityManagerService.dumpDbInfo(fd, pw, args);
2535        }
2536    }
2537
2538    static class CpuBinder extends Binder {
2539        ActivityManagerService mActivityManagerService;
2540        CpuBinder(ActivityManagerService activityManagerService) {
2541            mActivityManagerService = activityManagerService;
2542        }
2543
2544        @Override
2545        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2546            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2547                    != PackageManager.PERMISSION_GRANTED) {
2548                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2549                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2550                        + " without permission " + android.Manifest.permission.DUMP);
2551                return;
2552            }
2553
2554            synchronized (mActivityManagerService.mProcessCpuTracker) {
2555                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2556                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2557                        SystemClock.uptimeMillis()));
2558            }
2559        }
2560    }
2561
2562    public static final class Lifecycle extends SystemService {
2563        private final ActivityManagerService mService;
2564
2565        public Lifecycle(Context context) {
2566            super(context);
2567            mService = new ActivityManagerService(context);
2568        }
2569
2570        @Override
2571        public void onStart() {
2572            mService.start();
2573        }
2574
2575        public ActivityManagerService getService() {
2576            return mService;
2577        }
2578    }
2579
2580    // Note: This method is invoked on the main thread but may need to attach various
2581    // handlers to other threads.  So take care to be explicit about the looper.
2582    public ActivityManagerService(Context systemContext) {
2583        mContext = systemContext;
2584        mFactoryTest = FactoryTest.getMode();
2585        mSystemThread = ActivityThread.currentActivityThread();
2586
2587        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2588
2589        mPermissionReviewRequired = mContext.getResources().getBoolean(
2590                com.android.internal.R.bool.config_permissionReviewRequired);
2591
2592        mHandlerThread = new ServiceThread(TAG,
2593                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2594        mHandlerThread.start();
2595        mHandler = new MainHandler(mHandlerThread.getLooper());
2596        mUiHandler = new UiHandler();
2597
2598        /* static; one-time init here */
2599        if (sKillHandler == null) {
2600            sKillThread = new ServiceThread(TAG + ":kill",
2601                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2602            sKillThread.start();
2603            sKillHandler = new KillHandler(sKillThread.getLooper());
2604        }
2605
2606        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2607                "foreground", BROADCAST_FG_TIMEOUT, false);
2608        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2609                "background", BROADCAST_BG_TIMEOUT, true);
2610        mBroadcastQueues[0] = mFgBroadcastQueue;
2611        mBroadcastQueues[1] = mBgBroadcastQueue;
2612
2613        mServices = new ActiveServices(this);
2614        mProviderMap = new ProviderMap(this);
2615        mAppErrors = new AppErrors(mContext, this);
2616
2617        // TODO: Move creation of battery stats service outside of activity manager service.
2618        File dataDir = Environment.getDataDirectory();
2619        File systemDir = new File(dataDir, "system");
2620        systemDir.mkdirs();
2621        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2622        mBatteryStatsService.getActiveStatistics().readLocked();
2623        mBatteryStatsService.scheduleWriteToDisk();
2624        mOnBattery = DEBUG_POWER ? true
2625                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2626        mBatteryStatsService.getActiveStatistics().setCallback(this);
2627
2628        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2629
2630        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2631        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2632                new IAppOpsCallback.Stub() {
2633                    @Override public void opChanged(int op, int uid, String packageName) {
2634                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2635                            if (mAppOpsService.checkOperation(op, uid, packageName)
2636                                    != AppOpsManager.MODE_ALLOWED) {
2637                                runInBackgroundDisabled(uid);
2638                            }
2639                        }
2640                    }
2641                });
2642
2643        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2644
2645        mUserController = new UserController(this);
2646
2647        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2648            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2649
2650        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2651
2652        mConfiguration.setToDefaults();
2653        mConfiguration.setLocales(LocaleList.getDefault());
2654
2655        mConfigurationSeq = mConfiguration.seq = 1;
2656        mProcessCpuTracker.init();
2657
2658        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2659        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2660        mStackSupervisor = new ActivityStackSupervisor(this);
2661        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2662        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2663
2664        mProcessCpuThread = new Thread("CpuTracker") {
2665            @Override
2666            public void run() {
2667                while (true) {
2668                    try {
2669                        try {
2670                            synchronized(this) {
2671                                final long now = SystemClock.uptimeMillis();
2672                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2673                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2674                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2675                                //        + ", write delay=" + nextWriteDelay);
2676                                if (nextWriteDelay < nextCpuDelay) {
2677                                    nextCpuDelay = nextWriteDelay;
2678                                }
2679                                if (nextCpuDelay > 0) {
2680                                    mProcessCpuMutexFree.set(true);
2681                                    this.wait(nextCpuDelay);
2682                                }
2683                            }
2684                        } catch (InterruptedException e) {
2685                        }
2686                        updateCpuStatsNow();
2687                    } catch (Exception e) {
2688                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2689                    }
2690                }
2691            }
2692        };
2693
2694        Watchdog.getInstance().addMonitor(this);
2695        Watchdog.getInstance().addThread(mHandler);
2696    }
2697
2698    public void setSystemServiceManager(SystemServiceManager mgr) {
2699        mSystemServiceManager = mgr;
2700    }
2701
2702    public void setInstaller(Installer installer) {
2703        mInstaller = installer;
2704    }
2705
2706    private void start() {
2707        Process.removeAllProcessGroups();
2708        mProcessCpuThread.start();
2709
2710        mBatteryStatsService.publish(mContext);
2711        mAppOpsService.publish(mContext);
2712        Slog.d("AppOps", "AppOpsService published");
2713        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2714    }
2715
2716    void onUserStoppedLocked(int userId) {
2717        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2718    }
2719
2720    public void initPowerManagement() {
2721        mStackSupervisor.initPowerManagement();
2722        mBatteryStatsService.initPowerManagement();
2723        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2724        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2725        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2726        mVoiceWakeLock.setReferenceCounted(false);
2727    }
2728
2729    @Override
2730    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2731            throws RemoteException {
2732        if (code == SYSPROPS_TRANSACTION) {
2733            // We need to tell all apps about the system property change.
2734            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2735            synchronized(this) {
2736                final int NP = mProcessNames.getMap().size();
2737                for (int ip=0; ip<NP; ip++) {
2738                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2739                    final int NA = apps.size();
2740                    for (int ia=0; ia<NA; ia++) {
2741                        ProcessRecord app = apps.valueAt(ia);
2742                        if (app.thread != null) {
2743                            procs.add(app.thread.asBinder());
2744                        }
2745                    }
2746                }
2747            }
2748
2749            int N = procs.size();
2750            for (int i=0; i<N; i++) {
2751                Parcel data2 = Parcel.obtain();
2752                try {
2753                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2754                } catch (RemoteException e) {
2755                }
2756                data2.recycle();
2757            }
2758        }
2759        try {
2760            return super.onTransact(code, data, reply, flags);
2761        } catch (RuntimeException e) {
2762            // The activity manager only throws security exceptions, so let's
2763            // log all others.
2764            if (!(e instanceof SecurityException)) {
2765                Slog.wtf(TAG, "Activity Manager Crash", e);
2766            }
2767            throw e;
2768        }
2769    }
2770
2771    void updateCpuStats() {
2772        final long now = SystemClock.uptimeMillis();
2773        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2774            return;
2775        }
2776        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2777            synchronized (mProcessCpuThread) {
2778                mProcessCpuThread.notify();
2779            }
2780        }
2781    }
2782
2783    void updateCpuStatsNow() {
2784        synchronized (mProcessCpuTracker) {
2785            mProcessCpuMutexFree.set(false);
2786            final long now = SystemClock.uptimeMillis();
2787            boolean haveNewCpuStats = false;
2788
2789            if (MONITOR_CPU_USAGE &&
2790                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2791                mLastCpuTime.set(now);
2792                mProcessCpuTracker.update();
2793                if (mProcessCpuTracker.hasGoodLastStats()) {
2794                    haveNewCpuStats = true;
2795                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2796                    //Slog.i(TAG, "Total CPU usage: "
2797                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2798
2799                    // Slog the cpu usage if the property is set.
2800                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2801                        int user = mProcessCpuTracker.getLastUserTime();
2802                        int system = mProcessCpuTracker.getLastSystemTime();
2803                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2804                        int irq = mProcessCpuTracker.getLastIrqTime();
2805                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2806                        int idle = mProcessCpuTracker.getLastIdleTime();
2807
2808                        int total = user + system + iowait + irq + softIrq + idle;
2809                        if (total == 0) total = 1;
2810
2811                        EventLog.writeEvent(EventLogTags.CPU,
2812                                ((user+system+iowait+irq+softIrq) * 100) / total,
2813                                (user * 100) / total,
2814                                (system * 100) / total,
2815                                (iowait * 100) / total,
2816                                (irq * 100) / total,
2817                                (softIrq * 100) / total);
2818                    }
2819                }
2820            }
2821
2822            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2823            synchronized(bstats) {
2824                synchronized(mPidsSelfLocked) {
2825                    if (haveNewCpuStats) {
2826                        if (bstats.startAddingCpuLocked()) {
2827                            int totalUTime = 0;
2828                            int totalSTime = 0;
2829                            final int N = mProcessCpuTracker.countStats();
2830                            for (int i=0; i<N; i++) {
2831                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2832                                if (!st.working) {
2833                                    continue;
2834                                }
2835                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2836                                totalUTime += st.rel_utime;
2837                                totalSTime += st.rel_stime;
2838                                if (pr != null) {
2839                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2840                                    if (ps == null || !ps.isActive()) {
2841                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2842                                                pr.info.uid, pr.processName);
2843                                    }
2844                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2845                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2846                                } else {
2847                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2848                                    if (ps == null || !ps.isActive()) {
2849                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2850                                                bstats.mapUid(st.uid), st.name);
2851                                    }
2852                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2853                                }
2854                            }
2855                            final int userTime = mProcessCpuTracker.getLastUserTime();
2856                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2857                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2858                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2859                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2860                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2861                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2862                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2863                        }
2864                    }
2865                }
2866
2867                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2868                    mLastWriteTime = now;
2869                    mBatteryStatsService.scheduleWriteToDisk();
2870                }
2871            }
2872        }
2873    }
2874
2875    @Override
2876    public void batteryNeedsCpuUpdate() {
2877        updateCpuStatsNow();
2878    }
2879
2880    @Override
2881    public void batteryPowerChanged(boolean onBattery) {
2882        // When plugging in, update the CPU stats first before changing
2883        // the plug state.
2884        updateCpuStatsNow();
2885        synchronized (this) {
2886            synchronized(mPidsSelfLocked) {
2887                mOnBattery = DEBUG_POWER ? true : onBattery;
2888            }
2889        }
2890    }
2891
2892    @Override
2893    public void batterySendBroadcast(Intent intent) {
2894        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2895                AppOpsManager.OP_NONE, null, false, false,
2896                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2897    }
2898
2899    /**
2900     * Initialize the application bind args. These are passed to each
2901     * process when the bindApplication() IPC is sent to the process. They're
2902     * lazily setup to make sure the services are running when they're asked for.
2903     */
2904    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2905        if (mAppBindArgs == null) {
2906            mAppBindArgs = new HashMap<>();
2907
2908            // Isolated processes won't get this optimization, so that we don't
2909            // violate the rules about which services they have access to.
2910            if (!isolated) {
2911                // Setup the application init args
2912                mAppBindArgs.put("package", ServiceManager.getService("package"));
2913                mAppBindArgs.put("window", ServiceManager.getService("window"));
2914                mAppBindArgs.put(Context.ALARM_SERVICE,
2915                        ServiceManager.getService(Context.ALARM_SERVICE));
2916            }
2917        }
2918        return mAppBindArgs;
2919    }
2920
2921    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2922        if (r == null || mFocusedActivity == r) {
2923            return false;
2924        }
2925
2926        if (!r.isFocusable()) {
2927            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2928            return false;
2929        }
2930
2931        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2932
2933        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2934        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2935                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2936        mDoingSetFocusedActivity = true;
2937
2938        final ActivityRecord last = mFocusedActivity;
2939        mFocusedActivity = r;
2940        if (r.task.isApplicationTask()) {
2941            if (mCurAppTimeTracker != r.appTimeTracker) {
2942                // We are switching app tracking.  Complete the current one.
2943                if (mCurAppTimeTracker != null) {
2944                    mCurAppTimeTracker.stop();
2945                    mHandler.obtainMessage(
2946                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2947                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2948                    mCurAppTimeTracker = null;
2949                }
2950                if (r.appTimeTracker != null) {
2951                    mCurAppTimeTracker = r.appTimeTracker;
2952                    startTimeTrackingFocusedActivityLocked();
2953                }
2954            } else {
2955                startTimeTrackingFocusedActivityLocked();
2956            }
2957        } else {
2958            r.appTimeTracker = null;
2959        }
2960        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2961        // TODO: Probably not, because we don't want to resume voice on switching
2962        // back to this activity
2963        if (r.task.voiceInteractor != null) {
2964            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2965        } else {
2966            finishRunningVoiceLocked();
2967            IVoiceInteractionSession session;
2968            if (last != null && ((session = last.task.voiceSession) != null
2969                    || (session = last.voiceSession) != null)) {
2970                // We had been in a voice interaction session, but now focused has
2971                // move to something different.  Just finish the session, we can't
2972                // return to it and retain the proper state and synchronization with
2973                // the voice interaction service.
2974                finishVoiceTask(session);
2975            }
2976        }
2977        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2978            mWindowManager.setFocusedApp(r.appToken, true);
2979        }
2980        applyUpdateLockStateLocked(r);
2981        applyUpdateVrModeLocked(r);
2982        if (mFocusedActivity.userId != mLastFocusedUserId) {
2983            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2984            mHandler.obtainMessage(
2985                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2986            mLastFocusedUserId = mFocusedActivity.userId;
2987        }
2988
2989        // Log a warning if the focused app is changed during the process. This could
2990        // indicate a problem of the focus setting logic!
2991        if (mFocusedActivity != r) Slog.w(TAG,
2992                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2993        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2994
2995        EventLogTags.writeAmFocusedActivity(
2996                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2997                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2998                reason);
2999        return true;
3000    }
3001
3002    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3003        if (mFocusedActivity != goingAway) {
3004            return;
3005        }
3006
3007        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3008        if (focusedStack != null) {
3009            final ActivityRecord top = focusedStack.topActivity();
3010            if (top != null && top.userId != mLastFocusedUserId) {
3011                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3012                mHandler.sendMessage(
3013                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3014                mLastFocusedUserId = top.userId;
3015            }
3016        }
3017
3018        // Try to move focus to another activity if possible.
3019        if (setFocusedActivityLocked(
3020                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3021            return;
3022        }
3023
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3025                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3026        mFocusedActivity = null;
3027        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3028    }
3029
3030    @Override
3031    public void setFocusedStack(int stackId) {
3032        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3033        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3034        final long callingId = Binder.clearCallingIdentity();
3035        try {
3036            synchronized (this) {
3037                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3038                if (stack == null) {
3039                    return;
3040                }
3041                final ActivityRecord r = stack.topRunningActivityLocked();
3042                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3043                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3044                }
3045            }
3046        } finally {
3047            Binder.restoreCallingIdentity(callingId);
3048        }
3049    }
3050
3051    @Override
3052    public void setFocusedTask(int taskId) {
3053        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3054        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3055        final long callingId = Binder.clearCallingIdentity();
3056        try {
3057            synchronized (this) {
3058                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3059                if (task == null) {
3060                    return;
3061                }
3062                final ActivityRecord r = task.topRunningActivityLocked();
3063                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3064                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3065                }
3066            }
3067        } finally {
3068            Binder.restoreCallingIdentity(callingId);
3069        }
3070    }
3071
3072    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3073    @Override
3074    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3075        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3076        synchronized (this) {
3077            if (listener != null) {
3078                mTaskStackListeners.register(listener);
3079            }
3080        }
3081    }
3082
3083    @Override
3084    public void notifyActivityDrawn(IBinder token) {
3085        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3086        synchronized (this) {
3087            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3088            if (r != null) {
3089                r.task.stack.notifyActivityDrawnLocked(r);
3090            }
3091        }
3092    }
3093
3094    final void applyUpdateLockStateLocked(ActivityRecord r) {
3095        // Modifications to the UpdateLock state are done on our handler, outside
3096        // the activity manager's locks.  The new state is determined based on the
3097        // state *now* of the relevant activity record.  The object is passed to
3098        // the handler solely for logging detail, not to be consulted/modified.
3099        final boolean nextState = r != null && r.immersive;
3100        mHandler.sendMessage(
3101                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3102    }
3103
3104    final void applyUpdateVrModeLocked(ActivityRecord r) {
3105        mHandler.sendMessage(
3106                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3107    }
3108
3109    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3110        mHandler.sendMessage(
3111                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3112    }
3113
3114    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3115            ComponentName callingPackage, boolean immediate) {
3116        VrManagerInternal vrService =
3117                LocalServices.getService(VrManagerInternal.class);
3118        if (immediate) {
3119            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3120        } else {
3121            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3122        }
3123    }
3124
3125    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3126        Message msg = Message.obtain();
3127        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3128        msg.obj = r.task.askedCompatMode ? null : r;
3129        mUiHandler.sendMessage(msg);
3130    }
3131
3132    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3133        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3134                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3135            final Message msg = Message.obtain();
3136            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3137            msg.obj = r;
3138            mUiHandler.sendMessage(msg);
3139        }
3140    }
3141
3142    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3143            String what, Object obj, ProcessRecord srcApp) {
3144        app.lastActivityTime = now;
3145
3146        if (app.activities.size() > 0) {
3147            // Don't want to touch dependent processes that are hosting activities.
3148            return index;
3149        }
3150
3151        int lrui = mLruProcesses.lastIndexOf(app);
3152        if (lrui < 0) {
3153            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3154                    + what + " " + obj + " from " + srcApp);
3155            return index;
3156        }
3157
3158        if (lrui >= index) {
3159            // Don't want to cause this to move dependent processes *back* in the
3160            // list as if they were less frequently used.
3161            return index;
3162        }
3163
3164        if (lrui >= mLruProcessActivityStart) {
3165            // Don't want to touch dependent processes that are hosting activities.
3166            return index;
3167        }
3168
3169        mLruProcesses.remove(lrui);
3170        if (index > 0) {
3171            index--;
3172        }
3173        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3174                + " in LRU list: " + app);
3175        mLruProcesses.add(index, app);
3176        return index;
3177    }
3178
3179    static void killProcessGroup(int uid, int pid) {
3180        if (sKillHandler != null) {
3181            sKillHandler.sendMessage(
3182                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3183        } else {
3184            Slog.w(TAG, "Asked to kill process group before system bringup!");
3185            Process.killProcessGroup(uid, pid);
3186        }
3187    }
3188
3189    final void removeLruProcessLocked(ProcessRecord app) {
3190        int lrui = mLruProcesses.lastIndexOf(app);
3191        if (lrui >= 0) {
3192            if (!app.killed) {
3193                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3194                Process.killProcessQuiet(app.pid);
3195                killProcessGroup(app.uid, app.pid);
3196            }
3197            if (lrui <= mLruProcessActivityStart) {
3198                mLruProcessActivityStart--;
3199            }
3200            if (lrui <= mLruProcessServiceStart) {
3201                mLruProcessServiceStart--;
3202            }
3203            mLruProcesses.remove(lrui);
3204        }
3205    }
3206
3207    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3208            ProcessRecord client) {
3209        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3210                || app.treatLikeActivity;
3211        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3212        if (!activityChange && hasActivity) {
3213            // The process has activities, so we are only allowing activity-based adjustments
3214            // to move it.  It should be kept in the front of the list with other
3215            // processes that have activities, and we don't want those to change their
3216            // order except due to activity operations.
3217            return;
3218        }
3219
3220        mLruSeq++;
3221        final long now = SystemClock.uptimeMillis();
3222        app.lastActivityTime = now;
3223
3224        // First a quick reject: if the app is already at the position we will
3225        // put it, then there is nothing to do.
3226        if (hasActivity) {
3227            final int N = mLruProcesses.size();
3228            if (N > 0 && mLruProcesses.get(N-1) == app) {
3229                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3230                return;
3231            }
3232        } else {
3233            if (mLruProcessServiceStart > 0
3234                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3235                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3236                return;
3237            }
3238        }
3239
3240        int lrui = mLruProcesses.lastIndexOf(app);
3241
3242        if (app.persistent && lrui >= 0) {
3243            // We don't care about the position of persistent processes, as long as
3244            // they are in the list.
3245            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3246            return;
3247        }
3248
3249        /* In progress: compute new position first, so we can avoid doing work
3250           if the process is not actually going to move.  Not yet working.
3251        int addIndex;
3252        int nextIndex;
3253        boolean inActivity = false, inService = false;
3254        if (hasActivity) {
3255            // Process has activities, put it at the very tipsy-top.
3256            addIndex = mLruProcesses.size();
3257            nextIndex = mLruProcessServiceStart;
3258            inActivity = true;
3259        } else if (hasService) {
3260            // Process has services, put it at the top of the service list.
3261            addIndex = mLruProcessActivityStart;
3262            nextIndex = mLruProcessServiceStart;
3263            inActivity = true;
3264            inService = true;
3265        } else  {
3266            // Process not otherwise of interest, it goes to the top of the non-service area.
3267            addIndex = mLruProcessServiceStart;
3268            if (client != null) {
3269                int clientIndex = mLruProcesses.lastIndexOf(client);
3270                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3271                        + app);
3272                if (clientIndex >= 0 && addIndex > clientIndex) {
3273                    addIndex = clientIndex;
3274                }
3275            }
3276            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3277        }
3278
3279        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3280                + mLruProcessActivityStart + "): " + app);
3281        */
3282
3283        if (lrui >= 0) {
3284            if (lrui < mLruProcessActivityStart) {
3285                mLruProcessActivityStart--;
3286            }
3287            if (lrui < mLruProcessServiceStart) {
3288                mLruProcessServiceStart--;
3289            }
3290            /*
3291            if (addIndex > lrui) {
3292                addIndex--;
3293            }
3294            if (nextIndex > lrui) {
3295                nextIndex--;
3296            }
3297            */
3298            mLruProcesses.remove(lrui);
3299        }
3300
3301        /*
3302        mLruProcesses.add(addIndex, app);
3303        if (inActivity) {
3304            mLruProcessActivityStart++;
3305        }
3306        if (inService) {
3307            mLruProcessActivityStart++;
3308        }
3309        */
3310
3311        int nextIndex;
3312        if (hasActivity) {
3313            final int N = mLruProcesses.size();
3314            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3315                // Process doesn't have activities, but has clients with
3316                // activities...  move it up, but one below the top (the top
3317                // should always have a real activity).
3318                if (DEBUG_LRU) Slog.d(TAG_LRU,
3319                        "Adding to second-top of LRU activity list: " + app);
3320                mLruProcesses.add(N - 1, app);
3321                // To keep it from spamming the LRU list (by making a bunch of clients),
3322                // we will push down any other entries owned by the app.
3323                final int uid = app.info.uid;
3324                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3325                    ProcessRecord subProc = mLruProcesses.get(i);
3326                    if (subProc.info.uid == uid) {
3327                        // We want to push this one down the list.  If the process after
3328                        // it is for the same uid, however, don't do so, because we don't
3329                        // want them internally to be re-ordered.
3330                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3331                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3332                                    "Pushing uid " + uid + " swapping at " + i + ": "
3333                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3334                            ProcessRecord tmp = mLruProcesses.get(i);
3335                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3336                            mLruProcesses.set(i - 1, tmp);
3337                            i--;
3338                        }
3339                    } else {
3340                        // A gap, we can stop here.
3341                        break;
3342                    }
3343                }
3344            } else {
3345                // Process has activities, put it at the very tipsy-top.
3346                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3347                mLruProcesses.add(app);
3348            }
3349            nextIndex = mLruProcessServiceStart;
3350        } else if (hasService) {
3351            // Process has services, put it at the top of the service list.
3352            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3353            mLruProcesses.add(mLruProcessActivityStart, app);
3354            nextIndex = mLruProcessServiceStart;
3355            mLruProcessActivityStart++;
3356        } else  {
3357            // Process not otherwise of interest, it goes to the top of the non-service area.
3358            int index = mLruProcessServiceStart;
3359            if (client != null) {
3360                // If there is a client, don't allow the process to be moved up higher
3361                // in the list than that client.
3362                int clientIndex = mLruProcesses.lastIndexOf(client);
3363                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3364                        + " when updating " + app);
3365                if (clientIndex <= lrui) {
3366                    // Don't allow the client index restriction to push it down farther in the
3367                    // list than it already is.
3368                    clientIndex = lrui;
3369                }
3370                if (clientIndex >= 0 && index > clientIndex) {
3371                    index = clientIndex;
3372                }
3373            }
3374            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3375            mLruProcesses.add(index, app);
3376            nextIndex = index-1;
3377            mLruProcessActivityStart++;
3378            mLruProcessServiceStart++;
3379        }
3380
3381        // If the app is currently using a content provider or service,
3382        // bump those processes as well.
3383        for (int j=app.connections.size()-1; j>=0; j--) {
3384            ConnectionRecord cr = app.connections.valueAt(j);
3385            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3386                    && cr.binding.service.app != null
3387                    && cr.binding.service.app.lruSeq != mLruSeq
3388                    && !cr.binding.service.app.persistent) {
3389                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3390                        "service connection", cr, app);
3391            }
3392        }
3393        for (int j=app.conProviders.size()-1; j>=0; j--) {
3394            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3395            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3396                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3397                        "provider reference", cpr, app);
3398            }
3399        }
3400    }
3401
3402    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3403        if (uid == Process.SYSTEM_UID) {
3404            // The system gets to run in any process.  If there are multiple
3405            // processes with the same uid, just pick the first (this
3406            // should never happen).
3407            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3408            if (procs == null) return null;
3409            final int procCount = procs.size();
3410            for (int i = 0; i < procCount; i++) {
3411                final int procUid = procs.keyAt(i);
3412                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3413                    // Don't use an app process or different user process for system component.
3414                    continue;
3415                }
3416                return procs.valueAt(i);
3417            }
3418        }
3419        ProcessRecord proc = mProcessNames.get(processName, uid);
3420        if (false && proc != null && !keepIfLarge
3421                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3422                && proc.lastCachedPss >= 4000) {
3423            // Turn this condition on to cause killing to happen regularly, for testing.
3424            if (proc.baseProcessTracker != null) {
3425                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3426            }
3427            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3428        } else if (proc != null && !keepIfLarge
3429                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3430                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3431            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3432            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3433                if (proc.baseProcessTracker != null) {
3434                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3435                }
3436                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3437            }
3438        }
3439        return proc;
3440    }
3441
3442    void notifyPackageUse(String packageName, int reason) {
3443        IPackageManager pm = AppGlobals.getPackageManager();
3444        try {
3445            pm.notifyPackageUse(packageName, reason);
3446        } catch (RemoteException e) {
3447        }
3448    }
3449
3450    boolean isNextTransitionForward() {
3451        int transit = mWindowManager.getPendingAppTransition();
3452        return transit == TRANSIT_ACTIVITY_OPEN
3453                || transit == TRANSIT_TASK_OPEN
3454                || transit == TRANSIT_TASK_TO_FRONT;
3455    }
3456
3457    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3458            String processName, String abiOverride, int uid, Runnable crashHandler) {
3459        synchronized(this) {
3460            ApplicationInfo info = new ApplicationInfo();
3461            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3462            // For isolated processes, the former contains the parent's uid and the latter the
3463            // actual uid of the isolated process.
3464            // In the special case introduced by this method (which is, starting an isolated
3465            // process directly from the SystemServer without an actual parent app process) the
3466            // closest thing to a parent's uid is SYSTEM_UID.
3467            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3468            // the |isolated| logic in the ProcessRecord constructor.
3469            info.uid = Process.SYSTEM_UID;
3470            info.processName = processName;
3471            info.className = entryPoint;
3472            info.packageName = "android";
3473            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3474                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3475                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3476                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3477                    crashHandler);
3478            return proc != null ? proc.pid : 0;
3479        }
3480    }
3481
3482    final ProcessRecord startProcessLocked(String processName,
3483            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3484            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3485            boolean isolated, boolean keepIfLarge) {
3486        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3487                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3488                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3489                null /* crashHandler */);
3490    }
3491
3492    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3493            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3494            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3495            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3496        long startTime = SystemClock.elapsedRealtime();
3497        ProcessRecord app;
3498        if (!isolated) {
3499            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3500            checkTime(startTime, "startProcess: after getProcessRecord");
3501
3502            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3503                // If we are in the background, then check to see if this process
3504                // is bad.  If so, we will just silently fail.
3505                if (mAppErrors.isBadProcessLocked(info)) {
3506                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3507                            + "/" + info.processName);
3508                    return null;
3509                }
3510            } else {
3511                // When the user is explicitly starting a process, then clear its
3512                // crash count so that we won't make it bad until they see at
3513                // least one crash dialog again, and make the process good again
3514                // if it had been bad.
3515                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3516                        + "/" + info.processName);
3517                mAppErrors.resetProcessCrashTimeLocked(info);
3518                if (mAppErrors.isBadProcessLocked(info)) {
3519                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3520                            UserHandle.getUserId(info.uid), info.uid,
3521                            info.processName);
3522                    mAppErrors.clearBadProcessLocked(info);
3523                    if (app != null) {
3524                        app.bad = false;
3525                    }
3526                }
3527            }
3528        } else {
3529            // If this is an isolated process, it can't re-use an existing process.
3530            app = null;
3531        }
3532
3533        // app launch boost for big.little configurations
3534        // use cpusets to migrate freshly launched tasks to big cores
3535        nativeMigrateToBoost();
3536        mIsBoosted = true;
3537        mBoostStartTime = SystemClock.uptimeMillis();
3538        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3539        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3540
3541        // We don't have to do anything more if:
3542        // (1) There is an existing application record; and
3543        // (2) The caller doesn't think it is dead, OR there is no thread
3544        //     object attached to it so we know it couldn't have crashed; and
3545        // (3) There is a pid assigned to it, so it is either starting or
3546        //     already running.
3547        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3548                + " app=" + app + " knownToBeDead=" + knownToBeDead
3549                + " thread=" + (app != null ? app.thread : null)
3550                + " pid=" + (app != null ? app.pid : -1));
3551        if (app != null && app.pid > 0) {
3552            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3553                // We already have the app running, or are waiting for it to
3554                // come up (we have a pid but not yet its thread), so keep it.
3555                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3556                // If this is a new package in the process, add the package to the list
3557                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3558                checkTime(startTime, "startProcess: done, added package to proc");
3559                return app;
3560            }
3561
3562            // An application record is attached to a previous process,
3563            // clean it up now.
3564            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3565            checkTime(startTime, "startProcess: bad proc running, killing");
3566            killProcessGroup(app.uid, app.pid);
3567            handleAppDiedLocked(app, true, true);
3568            checkTime(startTime, "startProcess: done killing old proc");
3569        }
3570
3571        String hostingNameStr = hostingName != null
3572                ? hostingName.flattenToShortString() : null;
3573
3574        if (app == null) {
3575            checkTime(startTime, "startProcess: creating new process record");
3576            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3577            if (app == null) {
3578                Slog.w(TAG, "Failed making new process record for "
3579                        + processName + "/" + info.uid + " isolated=" + isolated);
3580                return null;
3581            }
3582            app.crashHandler = crashHandler;
3583            checkTime(startTime, "startProcess: done creating new process record");
3584        } else {
3585            // If this is a new package in the process, add the package to the list
3586            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3587            checkTime(startTime, "startProcess: added package to existing proc");
3588        }
3589
3590        // If the system is not ready yet, then hold off on starting this
3591        // process until it is.
3592        if (!mProcessesReady
3593                && !isAllowedWhileBooting(info)
3594                && !allowWhileBooting) {
3595            if (!mProcessesOnHold.contains(app)) {
3596                mProcessesOnHold.add(app);
3597            }
3598            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3599                    "System not ready, putting on hold: " + app);
3600            checkTime(startTime, "startProcess: returning with proc on hold");
3601            return app;
3602        }
3603
3604        checkTime(startTime, "startProcess: stepping in to startProcess");
3605        startProcessLocked(
3606                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3607        checkTime(startTime, "startProcess: done starting proc!");
3608        return (app.pid != 0) ? app : null;
3609    }
3610
3611    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3612        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3613    }
3614
3615    private final void startProcessLocked(ProcessRecord app,
3616            String hostingType, String hostingNameStr) {
3617        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3618                null /* entryPoint */, null /* entryPointArgs */);
3619    }
3620
3621    private final void startProcessLocked(ProcessRecord app, String hostingType,
3622            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3623        long startTime = SystemClock.elapsedRealtime();
3624        if (app.pid > 0 && app.pid != MY_PID) {
3625            checkTime(startTime, "startProcess: removing from pids map");
3626            synchronized (mPidsSelfLocked) {
3627                mPidsSelfLocked.remove(app.pid);
3628                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3629            }
3630            checkTime(startTime, "startProcess: done removing from pids map");
3631            app.setPid(0);
3632        }
3633
3634        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3635                "startProcessLocked removing on hold: " + app);
3636        mProcessesOnHold.remove(app);
3637
3638        checkTime(startTime, "startProcess: starting to update cpu stats");
3639        updateCpuStats();
3640        checkTime(startTime, "startProcess: done updating cpu stats");
3641
3642        try {
3643            try {
3644                final int userId = UserHandle.getUserId(app.uid);
3645                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3646            } catch (RemoteException e) {
3647                throw e.rethrowAsRuntimeException();
3648            }
3649
3650            int uid = app.uid;
3651            int[] gids = null;
3652            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3653            if (!app.isolated) {
3654                int[] permGids = null;
3655                try {
3656                    checkTime(startTime, "startProcess: getting gids from package manager");
3657                    final IPackageManager pm = AppGlobals.getPackageManager();
3658                    permGids = pm.getPackageGids(app.info.packageName,
3659                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3660                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3661                            MountServiceInternal.class);
3662                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3663                            app.info.packageName);
3664                } catch (RemoteException e) {
3665                    throw e.rethrowAsRuntimeException();
3666                }
3667
3668                /*
3669                 * Add shared application and profile GIDs so applications can share some
3670                 * resources like shared libraries and access user-wide resources
3671                 */
3672                if (ArrayUtils.isEmpty(permGids)) {
3673                    gids = new int[2];
3674                } else {
3675                    gids = new int[permGids.length + 2];
3676                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3677                }
3678                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3679                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3680            }
3681            checkTime(startTime, "startProcess: building args");
3682            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3683                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3684                        && mTopComponent != null
3685                        && app.processName.equals(mTopComponent.getPackageName())) {
3686                    uid = 0;
3687                }
3688                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3689                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3690                    uid = 0;
3691                }
3692            }
3693            int debugFlags = 0;
3694            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3695                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3696                // Also turn on CheckJNI for debuggable apps. It's quite
3697                // awkward to turn on otherwise.
3698                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3699            }
3700            // Run the app in safe mode if its manifest requests so or the
3701            // system is booted in safe mode.
3702            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3703                mSafeMode == true) {
3704                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3705            }
3706            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3707                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3708            }
3709            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3710            if ("true".equals(genDebugInfoProperty)) {
3711                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3712            }
3713            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3714                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3715            }
3716            if ("1".equals(SystemProperties.get("debug.assert"))) {
3717                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3718            }
3719            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3720                // Enable all debug flags required by the native debugger.
3721                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3722                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3723                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3724                mNativeDebuggingApp = null;
3725            }
3726
3727            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3728            if (requiredAbi == null) {
3729                requiredAbi = Build.SUPPORTED_ABIS[0];
3730            }
3731
3732            String instructionSet = null;
3733            if (app.info.primaryCpuAbi != null) {
3734                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3735            }
3736
3737            app.gids = gids;
3738            app.requiredAbi = requiredAbi;
3739            app.instructionSet = instructionSet;
3740
3741            // Start the process.  It will either succeed and return a result containing
3742            // the PID of the new process, or else throw a RuntimeException.
3743            boolean isActivityProcess = (entryPoint == null);
3744            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3745            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3746                    app.processName);
3747            checkTime(startTime, "startProcess: asking zygote to start proc");
3748            Process.ProcessStartResult startResult;
3749            if (hostingType.equals("webview_service")) {
3750                startResult = Process.startWebView(entryPoint,
3751                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3752                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3753                        app.info.dataDir, entryPointArgs);
3754            } else {
3755                startResult = Process.start(entryPoint,
3756                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3757                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3758                        app.info.dataDir, entryPointArgs);
3759            }
3760            checkTime(startTime, "startProcess: returned from zygote!");
3761            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3762
3763            if (app.isolated) {
3764                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3765            }
3766            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3767            checkTime(startTime, "startProcess: done updating battery stats");
3768
3769            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3770                    UserHandle.getUserId(uid), startResult.pid, uid,
3771                    app.processName, hostingType,
3772                    hostingNameStr != null ? hostingNameStr : "");
3773
3774            try {
3775                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3776                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3777            } catch (RemoteException ex) {
3778                // Ignore
3779            }
3780
3781            if (app.persistent) {
3782                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3783            }
3784
3785            checkTime(startTime, "startProcess: building log message");
3786            StringBuilder buf = mStringBuilder;
3787            buf.setLength(0);
3788            buf.append("Start proc ");
3789            buf.append(startResult.pid);
3790            buf.append(':');
3791            buf.append(app.processName);
3792            buf.append('/');
3793            UserHandle.formatUid(buf, uid);
3794            if (!isActivityProcess) {
3795                buf.append(" [");
3796                buf.append(entryPoint);
3797                buf.append("]");
3798            }
3799            buf.append(" for ");
3800            buf.append(hostingType);
3801            if (hostingNameStr != null) {
3802                buf.append(" ");
3803                buf.append(hostingNameStr);
3804            }
3805            Slog.i(TAG, buf.toString());
3806            app.setPid(startResult.pid);
3807            app.usingWrapper = startResult.usingWrapper;
3808            app.removed = false;
3809            app.killed = false;
3810            app.killedByAm = false;
3811            checkTime(startTime, "startProcess: starting to update pids map");
3812            synchronized (mPidsSelfLocked) {
3813                this.mPidsSelfLocked.put(startResult.pid, app);
3814                if (isActivityProcess) {
3815                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3816                    msg.obj = app;
3817                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3818                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3819                }
3820            }
3821            checkTime(startTime, "startProcess: done updating pids map");
3822        } catch (RuntimeException e) {
3823            Slog.e(TAG, "Failure starting process " + app.processName, e);
3824
3825            // Something went very wrong while trying to start this process; one
3826            // common case is when the package is frozen due to an active
3827            // upgrade. To recover, clean up any active bookkeeping related to
3828            // starting this process. (We already invoked this method once when
3829            // the package was initially frozen through KILL_APPLICATION_MSG, so
3830            // it doesn't hurt to use it again.)
3831            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3832                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3833        }
3834    }
3835
3836    void updateUsageStats(ActivityRecord component, boolean resumed) {
3837        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3838                "updateUsageStats: comp=" + component + "res=" + resumed);
3839        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3840        if (resumed) {
3841            if (mUsageStatsService != null) {
3842                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3843                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3844            }
3845            synchronized (stats) {
3846                stats.noteActivityResumedLocked(component.app.uid);
3847            }
3848        } else {
3849            if (mUsageStatsService != null) {
3850                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3851                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3852            }
3853            synchronized (stats) {
3854                stats.noteActivityPausedLocked(component.app.uid);
3855            }
3856        }
3857    }
3858
3859    Intent getHomeIntent() {
3860        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3861        intent.setComponent(mTopComponent);
3862        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3863        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3864            intent.addCategory(Intent.CATEGORY_HOME);
3865        }
3866        return intent;
3867    }
3868
3869    boolean startHomeActivityLocked(int userId, String reason) {
3870        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3871                && mTopAction == null) {
3872            // We are running in factory test mode, but unable to find
3873            // the factory test app, so just sit around displaying the
3874            // error message and don't try to start anything.
3875            return false;
3876        }
3877        Intent intent = getHomeIntent();
3878        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3879        if (aInfo != null) {
3880            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3881            // Don't do this if the home app is currently being
3882            // instrumented.
3883            aInfo = new ActivityInfo(aInfo);
3884            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3885            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3886                    aInfo.applicationInfo.uid, true);
3887            if (app == null || app.instrumentationClass == null) {
3888                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3889                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3890            }
3891        } else {
3892            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3893        }
3894
3895        return true;
3896    }
3897
3898    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3899        ActivityInfo ai = null;
3900        ComponentName comp = intent.getComponent();
3901        try {
3902            if (comp != null) {
3903                // Factory test.
3904                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3905            } else {
3906                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3907                        intent,
3908                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3909                        flags, userId);
3910
3911                if (info != null) {
3912                    ai = info.activityInfo;
3913                }
3914            }
3915        } catch (RemoteException e) {
3916            // ignore
3917        }
3918
3919        return ai;
3920    }
3921
3922    /**
3923     * Starts the "new version setup screen" if appropriate.
3924     */
3925    void startSetupActivityLocked() {
3926        // Only do this once per boot.
3927        if (mCheckedForSetup) {
3928            return;
3929        }
3930
3931        // We will show this screen if the current one is a different
3932        // version than the last one shown, and we are not running in
3933        // low-level factory test mode.
3934        final ContentResolver resolver = mContext.getContentResolver();
3935        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3936                Settings.Global.getInt(resolver,
3937                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3938            mCheckedForSetup = true;
3939
3940            // See if we should be showing the platform update setup UI.
3941            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3942            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3943                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3944            if (!ris.isEmpty()) {
3945                final ResolveInfo ri = ris.get(0);
3946                String vers = ri.activityInfo.metaData != null
3947                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3948                        : null;
3949                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3950                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3951                            Intent.METADATA_SETUP_VERSION);
3952                }
3953                String lastVers = Settings.Secure.getString(
3954                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3955                if (vers != null && !vers.equals(lastVers)) {
3956                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3957                    intent.setComponent(new ComponentName(
3958                            ri.activityInfo.packageName, ri.activityInfo.name));
3959                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3960                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3961                            null, 0, 0, 0, null, false, false, null, null, null);
3962                }
3963            }
3964        }
3965    }
3966
3967    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3968        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3969    }
3970
3971    void enforceNotIsolatedCaller(String caller) {
3972        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3973            throw new SecurityException("Isolated process not allowed to call " + caller);
3974        }
3975    }
3976
3977    void enforceShellRestriction(String restriction, int userHandle) {
3978        if (Binder.getCallingUid() == Process.SHELL_UID) {
3979            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3980                throw new SecurityException("Shell does not have permission to access user "
3981                        + userHandle);
3982            }
3983        }
3984    }
3985
3986    @Override
3987    public int getFrontActivityScreenCompatMode() {
3988        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3989        synchronized (this) {
3990            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3991        }
3992    }
3993
3994    @Override
3995    public void setFrontActivityScreenCompatMode(int mode) {
3996        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3997                "setFrontActivityScreenCompatMode");
3998        synchronized (this) {
3999            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4000        }
4001    }
4002
4003    @Override
4004    public int getPackageScreenCompatMode(String packageName) {
4005        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4006        synchronized (this) {
4007            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4008        }
4009    }
4010
4011    @Override
4012    public void setPackageScreenCompatMode(String packageName, int mode) {
4013        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4014                "setPackageScreenCompatMode");
4015        synchronized (this) {
4016            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4017        }
4018    }
4019
4020    @Override
4021    public boolean getPackageAskScreenCompat(String packageName) {
4022        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4023        synchronized (this) {
4024            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4025        }
4026    }
4027
4028    @Override
4029    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4030        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4031                "setPackageAskScreenCompat");
4032        synchronized (this) {
4033            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4034        }
4035    }
4036
4037    private boolean hasUsageStatsPermission(String callingPackage) {
4038        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4039                Binder.getCallingUid(), callingPackage);
4040        if (mode == AppOpsManager.MODE_DEFAULT) {
4041            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4042                    == PackageManager.PERMISSION_GRANTED;
4043        }
4044        return mode == AppOpsManager.MODE_ALLOWED;
4045    }
4046
4047    @Override
4048    public int getPackageProcessState(String packageName, String callingPackage) {
4049        if (!hasUsageStatsPermission(callingPackage)) {
4050            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4051                    "getPackageProcessState");
4052        }
4053
4054        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4055        synchronized (this) {
4056            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4057                final ProcessRecord proc = mLruProcesses.get(i);
4058                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4059                        || procState > proc.setProcState) {
4060                    boolean found = false;
4061                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4062                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4063                            procState = proc.setProcState;
4064                            found = true;
4065                        }
4066                    }
4067                    if (proc.pkgDeps != null && !found) {
4068                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4069                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4070                                procState = proc.setProcState;
4071                                break;
4072                            }
4073                        }
4074                    }
4075                }
4076            }
4077        }
4078        return procState;
4079    }
4080
4081    @Override
4082    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4083        synchronized (this) {
4084            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4085            if (app == null) {
4086                return false;
4087            }
4088            if (app.trimMemoryLevel < level && app.thread != null &&
4089                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4090                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4091                try {
4092                    app.thread.scheduleTrimMemory(level);
4093                    app.trimMemoryLevel = level;
4094                    return true;
4095                } catch (RemoteException e) {
4096                    // Fallthrough to failure case.
4097                }
4098            }
4099        }
4100        return false;
4101    }
4102
4103    private void dispatchProcessesChanged() {
4104        int N;
4105        synchronized (this) {
4106            N = mPendingProcessChanges.size();
4107            if (mActiveProcessChanges.length < N) {
4108                mActiveProcessChanges = new ProcessChangeItem[N];
4109            }
4110            mPendingProcessChanges.toArray(mActiveProcessChanges);
4111            mPendingProcessChanges.clear();
4112            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                    "*** Delivering " + N + " process changes");
4114        }
4115
4116        int i = mProcessObservers.beginBroadcast();
4117        while (i > 0) {
4118            i--;
4119            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4120            if (observer != null) {
4121                try {
4122                    for (int j=0; j<N; j++) {
4123                        ProcessChangeItem item = mActiveProcessChanges[j];
4124                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4125                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4126                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4127                                    + item.uid + ": " + item.foregroundActivities);
4128                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4129                                    item.foregroundActivities);
4130                        }
4131                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4132                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4133                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4134                                    + ": " + item.processState);
4135                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4136                        }
4137                    }
4138                } catch (RemoteException e) {
4139                }
4140            }
4141        }
4142        mProcessObservers.finishBroadcast();
4143
4144        synchronized (this) {
4145            for (int j=0; j<N; j++) {
4146                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4147            }
4148        }
4149    }
4150
4151    private void dispatchProcessDied(int pid, int uid) {
4152        int i = mProcessObservers.beginBroadcast();
4153        while (i > 0) {
4154            i--;
4155            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4156            if (observer != null) {
4157                try {
4158                    observer.onProcessDied(pid, uid);
4159                } catch (RemoteException e) {
4160                }
4161            }
4162        }
4163        mProcessObservers.finishBroadcast();
4164    }
4165
4166    private void dispatchUidsChanged() {
4167        int N;
4168        synchronized (this) {
4169            N = mPendingUidChanges.size();
4170            if (mActiveUidChanges.length < N) {
4171                mActiveUidChanges = new UidRecord.ChangeItem[N];
4172            }
4173            for (int i=0; i<N; i++) {
4174                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4175                mActiveUidChanges[i] = change;
4176                if (change.uidRecord != null) {
4177                    change.uidRecord.pendingChange = null;
4178                    change.uidRecord = null;
4179                }
4180            }
4181            mPendingUidChanges.clear();
4182            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4183                    "*** Delivering " + N + " uid changes");
4184        }
4185
4186        if (mLocalPowerManager != null) {
4187            for (int j=0; j<N; j++) {
4188                UidRecord.ChangeItem item = mActiveUidChanges[j];
4189                if (item.change == UidRecord.CHANGE_GONE
4190                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4191                    mLocalPowerManager.uidGone(item.uid);
4192                } else {
4193                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4194                }
4195            }
4196        }
4197
4198        int i = mUidObservers.beginBroadcast();
4199        while (i > 0) {
4200            i--;
4201            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4202            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4203            if (observer != null) {
4204                try {
4205                    for (int j=0; j<N; j++) {
4206                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4207                        final int change = item.change;
4208                        UidRecord validateUid = null;
4209                        if (VALIDATE_UID_STATES && i == 0) {
4210                            validateUid = mValidateUids.get(item.uid);
4211                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4212                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4213                                validateUid = new UidRecord(item.uid);
4214                                mValidateUids.put(item.uid, validateUid);
4215                            }
4216                        }
4217                        if (change == UidRecord.CHANGE_IDLE
4218                                || change == UidRecord.CHANGE_GONE_IDLE) {
4219                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4220                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4221                                        "UID idle uid=" + item.uid);
4222                                observer.onUidIdle(item.uid);
4223                            }
4224                            if (VALIDATE_UID_STATES && i == 0) {
4225                                if (validateUid != null) {
4226                                    validateUid.idle = true;
4227                                }
4228                            }
4229                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4230                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4231                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4232                                        "UID active uid=" + item.uid);
4233                                observer.onUidActive(item.uid);
4234                            }
4235                            if (VALIDATE_UID_STATES && i == 0) {
4236                                validateUid.idle = false;
4237                            }
4238                        }
4239                        if (change == UidRecord.CHANGE_GONE
4240                                || change == UidRecord.CHANGE_GONE_IDLE) {
4241                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4242                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4243                                        "UID gone uid=" + item.uid);
4244                                observer.onUidGone(item.uid);
4245                            }
4246                            if (VALIDATE_UID_STATES && i == 0) {
4247                                if (validateUid != null) {
4248                                    mValidateUids.remove(item.uid);
4249                                }
4250                            }
4251                        } else {
4252                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4253                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4254                                        "UID CHANGED uid=" + item.uid
4255                                                + ": " + item.processState);
4256                                observer.onUidStateChanged(item.uid, item.processState);
4257                            }
4258                            if (VALIDATE_UID_STATES && i == 0) {
4259                                validateUid.curProcState = validateUid.setProcState
4260                                        = item.processState;
4261                            }
4262                        }
4263                    }
4264                } catch (RemoteException e) {
4265                }
4266            }
4267        }
4268        mUidObservers.finishBroadcast();
4269
4270        synchronized (this) {
4271            for (int j=0; j<N; j++) {
4272                mAvailUidChanges.add(mActiveUidChanges[j]);
4273            }
4274        }
4275    }
4276
4277    @Override
4278    public final int startActivity(IApplicationThread caller, String callingPackage,
4279            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4280            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4281        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4282                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4283                UserHandle.getCallingUserId());
4284    }
4285
4286    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4287        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4288        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4289                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4290                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4291
4292        // TODO: Switch to user app stacks here.
4293        String mimeType = intent.getType();
4294        final Uri data = intent.getData();
4295        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4296            mimeType = getProviderMimeType(data, userId);
4297        }
4298        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4299
4300        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4301        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4302                null, 0, 0, null, null, null, null, false, userId, container, null);
4303    }
4304
4305    @Override
4306    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4309        enforceNotIsolatedCaller("startActivity");
4310        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4311                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4312        // TODO: Switch to user app stacks here.
4313        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4315                profilerInfo, null, null, bOptions, false, userId, null, null);
4316    }
4317
4318    @Override
4319    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4320            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4321            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4322            int userId) {
4323
4324        // This is very dangerous -- it allows you to perform a start activity (including
4325        // permission grants) as any app that may launch one of your own activities.  So
4326        // we will only allow this to be done from activities that are part of the core framework,
4327        // and then only when they are running as the system.
4328        final ActivityRecord sourceRecord;
4329        final int targetUid;
4330        final String targetPackage;
4331        synchronized (this) {
4332            if (resultTo == null) {
4333                throw new SecurityException("Must be called from an activity");
4334            }
4335            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4336            if (sourceRecord == null) {
4337                throw new SecurityException("Called with bad activity token: " + resultTo);
4338            }
4339            if (!sourceRecord.info.packageName.equals("android")) {
4340                throw new SecurityException(
4341                        "Must be called from an activity that is declared in the android package");
4342            }
4343            if (sourceRecord.app == null) {
4344                throw new SecurityException("Called without a process attached to activity");
4345            }
4346            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4347                // This is still okay, as long as this activity is running under the
4348                // uid of the original calling activity.
4349                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4350                    throw new SecurityException(
4351                            "Calling activity in uid " + sourceRecord.app.uid
4352                                    + " must be system uid or original calling uid "
4353                                    + sourceRecord.launchedFromUid);
4354                }
4355            }
4356            if (ignoreTargetSecurity) {
4357                if (intent.getComponent() == null) {
4358                    throw new SecurityException(
4359                            "Component must be specified with ignoreTargetSecurity");
4360                }
4361                if (intent.getSelector() != null) {
4362                    throw new SecurityException(
4363                            "Selector not allowed with ignoreTargetSecurity");
4364                }
4365            }
4366            targetUid = sourceRecord.launchedFromUid;
4367            targetPackage = sourceRecord.launchedFromPackage;
4368        }
4369
4370        if (userId == UserHandle.USER_NULL) {
4371            userId = UserHandle.getUserId(sourceRecord.app.uid);
4372        }
4373
4374        // TODO: Switch to user app stacks here.
4375        try {
4376            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4377                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4378                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4379            return ret;
4380        } catch (SecurityException e) {
4381            // XXX need to figure out how to propagate to original app.
4382            // A SecurityException here is generally actually a fault of the original
4383            // calling activity (such as a fairly granting permissions), so propagate it
4384            // back to them.
4385            /*
4386            StringBuilder msg = new StringBuilder();
4387            msg.append("While launching");
4388            msg.append(intent.toString());
4389            msg.append(": ");
4390            msg.append(e.getMessage());
4391            */
4392            throw e;
4393        }
4394    }
4395
4396    @Override
4397    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4398            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4399            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4400        enforceNotIsolatedCaller("startActivityAndWait");
4401        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4402                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4403        WaitResult res = new WaitResult();
4404        // TODO: Switch to user app stacks here.
4405        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4406                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4407                bOptions, false, userId, null, null);
4408        return res;
4409    }
4410
4411    @Override
4412    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4413            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4414            int startFlags, Configuration config, Bundle bOptions, int userId) {
4415        enforceNotIsolatedCaller("startActivityWithConfig");
4416        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4417                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4418        // TODO: Switch to user app stacks here.
4419        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4420                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4421                null, null, config, bOptions, false, userId, null, null);
4422        return ret;
4423    }
4424
4425    @Override
4426    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4427            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4428            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4429            throws TransactionTooLargeException {
4430        enforceNotIsolatedCaller("startActivityIntentSender");
4431        // Refuse possible leaked file descriptors
4432        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4433            throw new IllegalArgumentException("File descriptors passed in Intent");
4434        }
4435
4436        IIntentSender sender = intent.getTarget();
4437        if (!(sender instanceof PendingIntentRecord)) {
4438            throw new IllegalArgumentException("Bad PendingIntent object");
4439        }
4440
4441        PendingIntentRecord pir = (PendingIntentRecord)sender;
4442
4443        synchronized (this) {
4444            // If this is coming from the currently resumed activity, it is
4445            // effectively saying that app switches are allowed at this point.
4446            final ActivityStack stack = getFocusedStack();
4447            if (stack.mResumedActivity != null &&
4448                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4449                mAppSwitchesAllowedTime = 0;
4450            }
4451        }
4452        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4453                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4454        return ret;
4455    }
4456
4457    @Override
4458    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4459            Intent intent, String resolvedType, IVoiceInteractionSession session,
4460            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4461            Bundle bOptions, int userId) {
4462        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4463                != PackageManager.PERMISSION_GRANTED) {
4464            String msg = "Permission Denial: startVoiceActivity() from pid="
4465                    + Binder.getCallingPid()
4466                    + ", uid=" + Binder.getCallingUid()
4467                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4468            Slog.w(TAG, msg);
4469            throw new SecurityException(msg);
4470        }
4471        if (session == null || interactor == null) {
4472            throw new NullPointerException("null session or interactor");
4473        }
4474        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4475                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4476        // TODO: Switch to user app stacks here.
4477        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4478                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4479                null, bOptions, false, userId, null, null);
4480    }
4481
4482    @Override
4483    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4484            throws RemoteException {
4485        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4486        synchronized (this) {
4487            ActivityRecord activity = getFocusedStack().topActivity();
4488            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4489                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4490            }
4491            if (mRunningVoice != null || activity.task.voiceSession != null
4492                    || activity.voiceSession != null) {
4493                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4494                return;
4495            }
4496            if (activity.pendingVoiceInteractionStart) {
4497                Slog.w(TAG, "Pending start of voice interaction already.");
4498                return;
4499            }
4500            activity.pendingVoiceInteractionStart = true;
4501        }
4502        LocalServices.getService(VoiceInteractionManagerInternal.class)
4503                .startLocalVoiceInteraction(callingActivity, options);
4504    }
4505
4506    @Override
4507    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4508        LocalServices.getService(VoiceInteractionManagerInternal.class)
4509                .stopLocalVoiceInteraction(callingActivity);
4510    }
4511
4512    @Override
4513    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4514        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4515                .supportsLocalVoiceInteraction();
4516    }
4517
4518    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4519            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4520        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4521        if (activityToCallback == null) return;
4522        activityToCallback.setVoiceSessionLocked(voiceSession);
4523
4524        // Inform the activity
4525        try {
4526            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4527                    voiceInteractor);
4528            long token = Binder.clearCallingIdentity();
4529            try {
4530                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4531            } finally {
4532                Binder.restoreCallingIdentity(token);
4533            }
4534            // TODO: VI Should we cache the activity so that it's easier to find later
4535            // rather than scan through all the stacks and activities?
4536        } catch (RemoteException re) {
4537            activityToCallback.clearVoiceSessionLocked();
4538            // TODO: VI Should this terminate the voice session?
4539        }
4540    }
4541
4542    @Override
4543    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4544        synchronized (this) {
4545            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4546                if (keepAwake) {
4547                    mVoiceWakeLock.acquire();
4548                } else {
4549                    mVoiceWakeLock.release();
4550                }
4551            }
4552        }
4553    }
4554
4555    @Override
4556    public boolean startNextMatchingActivity(IBinder callingActivity,
4557            Intent intent, Bundle bOptions) {
4558        // Refuse possible leaked file descriptors
4559        if (intent != null && intent.hasFileDescriptors() == true) {
4560            throw new IllegalArgumentException("File descriptors passed in Intent");
4561        }
4562        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4563
4564        synchronized (this) {
4565            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4566            if (r == null) {
4567                ActivityOptions.abort(options);
4568                return false;
4569            }
4570            if (r.app == null || r.app.thread == null) {
4571                // The caller is not running...  d'oh!
4572                ActivityOptions.abort(options);
4573                return false;
4574            }
4575            intent = new Intent(intent);
4576            // The caller is not allowed to change the data.
4577            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4578            // And we are resetting to find the next component...
4579            intent.setComponent(null);
4580
4581            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4582
4583            ActivityInfo aInfo = null;
4584            try {
4585                List<ResolveInfo> resolves =
4586                    AppGlobals.getPackageManager().queryIntentActivities(
4587                            intent, r.resolvedType,
4588                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4589                            UserHandle.getCallingUserId()).getList();
4590
4591                // Look for the original activity in the list...
4592                final int N = resolves != null ? resolves.size() : 0;
4593                for (int i=0; i<N; i++) {
4594                    ResolveInfo rInfo = resolves.get(i);
4595                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4596                            && rInfo.activityInfo.name.equals(r.info.name)) {
4597                        // We found the current one...  the next matching is
4598                        // after it.
4599                        i++;
4600                        if (i<N) {
4601                            aInfo = resolves.get(i).activityInfo;
4602                        }
4603                        if (debug) {
4604                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4605                                    + "/" + r.info.name);
4606                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4607                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4608                        }
4609                        break;
4610                    }
4611                }
4612            } catch (RemoteException e) {
4613            }
4614
4615            if (aInfo == null) {
4616                // Nobody who is next!
4617                ActivityOptions.abort(options);
4618                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4619                return false;
4620            }
4621
4622            intent.setComponent(new ComponentName(
4623                    aInfo.applicationInfo.packageName, aInfo.name));
4624            intent.setFlags(intent.getFlags()&~(
4625                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4626                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4627                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4628                    Intent.FLAG_ACTIVITY_NEW_TASK));
4629
4630            // Okay now we need to start the new activity, replacing the
4631            // currently running activity.  This is a little tricky because
4632            // we want to start the new one as if the current one is finished,
4633            // but not finish the current one first so that there is no flicker.
4634            // And thus...
4635            final boolean wasFinishing = r.finishing;
4636            r.finishing = true;
4637
4638            // Propagate reply information over to the new activity.
4639            final ActivityRecord resultTo = r.resultTo;
4640            final String resultWho = r.resultWho;
4641            final int requestCode = r.requestCode;
4642            r.resultTo = null;
4643            if (resultTo != null) {
4644                resultTo.removeResultsLocked(r, resultWho, requestCode);
4645            }
4646
4647            final long origId = Binder.clearCallingIdentity();
4648            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4649                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4650                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4651                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4652                    false, false, null, null, null);
4653            Binder.restoreCallingIdentity(origId);
4654
4655            r.finishing = wasFinishing;
4656            if (res != ActivityManager.START_SUCCESS) {
4657                return false;
4658            }
4659            return true;
4660        }
4661    }
4662
4663    @Override
4664    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4665        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4666            String msg = "Permission Denial: startActivityFromRecents called without " +
4667                    START_TASKS_FROM_RECENTS;
4668            Slog.w(TAG, msg);
4669            throw new SecurityException(msg);
4670        }
4671        final long origId = Binder.clearCallingIdentity();
4672        try {
4673            synchronized (this) {
4674                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4675            }
4676        } finally {
4677            Binder.restoreCallingIdentity(origId);
4678        }
4679    }
4680
4681    final int startActivityInPackage(int uid, String callingPackage,
4682            Intent intent, String resolvedType, IBinder resultTo,
4683            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4684            IActivityContainer container, TaskRecord inTask) {
4685
4686        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4687                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4688
4689        // TODO: Switch to user app stacks here.
4690        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4691                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4692                null, null, null, bOptions, false, userId, container, inTask);
4693        return ret;
4694    }
4695
4696    @Override
4697    public final int startActivities(IApplicationThread caller, String callingPackage,
4698            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4699            int userId) {
4700        enforceNotIsolatedCaller("startActivities");
4701        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4702                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4703        // TODO: Switch to user app stacks here.
4704        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4705                resolvedTypes, resultTo, bOptions, userId);
4706        return ret;
4707    }
4708
4709    final int startActivitiesInPackage(int uid, String callingPackage,
4710            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4711            Bundle bOptions, int userId) {
4712
4713        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4714                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4715        // TODO: Switch to user app stacks here.
4716        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4717                resultTo, bOptions, userId);
4718        return ret;
4719    }
4720
4721    @Override
4722    public void reportActivityFullyDrawn(IBinder token) {
4723        synchronized (this) {
4724            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4725            if (r == null) {
4726                return;
4727            }
4728            r.reportFullyDrawnLocked();
4729        }
4730    }
4731
4732    @Override
4733    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4734        synchronized (this) {
4735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736            if (r == null) {
4737                return;
4738            }
4739            TaskRecord task = r.task;
4740            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4741                // Fixed screen orientation isn't supported when activities aren't in full screen
4742                // mode.
4743                return;
4744            }
4745            final long origId = Binder.clearCallingIdentity();
4746            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4747            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4748                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4749            if (config != null) {
4750                r.frozenBeforeDestroy = true;
4751                if (!updateConfigurationLocked(config, r, false)) {
4752                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4753                }
4754            }
4755            Binder.restoreCallingIdentity(origId);
4756        }
4757    }
4758
4759    @Override
4760    public int getRequestedOrientation(IBinder token) {
4761        synchronized (this) {
4762            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4763            if (r == null) {
4764                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4765            }
4766            return mWindowManager.getAppOrientation(r.appToken);
4767        }
4768    }
4769
4770    /**
4771     * This is the internal entry point for handling Activity.finish().
4772     *
4773     * @param token The Binder token referencing the Activity we want to finish.
4774     * @param resultCode Result code, if any, from this Activity.
4775     * @param resultData Result data (Intent), if any, from this Activity.
4776     * @param finishTask Whether to finish the task associated with this Activity.
4777     *
4778     * @return Returns true if the activity successfully finished, or false if it is still running.
4779     */
4780    @Override
4781    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4782            int finishTask) {
4783        // Refuse possible leaked file descriptors
4784        if (resultData != null && resultData.hasFileDescriptors() == true) {
4785            throw new IllegalArgumentException("File descriptors passed in Intent");
4786        }
4787
4788        synchronized(this) {
4789            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4790            if (r == null) {
4791                return true;
4792            }
4793            // Keep track of the root activity of the task before we finish it
4794            TaskRecord tr = r.task;
4795            ActivityRecord rootR = tr.getRootActivity();
4796            if (rootR == null) {
4797                Slog.w(TAG, "Finishing task with all activities already finished");
4798            }
4799            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4800            // finish.
4801            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4802                    mStackSupervisor.isLastLockedTask(tr)) {
4803                Slog.i(TAG, "Not finishing task in lock task mode");
4804                mStackSupervisor.showLockTaskToast();
4805                return false;
4806            }
4807            if (mController != null) {
4808                // Find the first activity that is not finishing.
4809                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4810                if (next != null) {
4811                    // ask watcher if this is allowed
4812                    boolean resumeOK = true;
4813                    try {
4814                        resumeOK = mController.activityResuming(next.packageName);
4815                    } catch (RemoteException e) {
4816                        mController = null;
4817                        Watchdog.getInstance().setActivityController(null);
4818                    }
4819
4820                    if (!resumeOK) {
4821                        Slog.i(TAG, "Not finishing activity because controller resumed");
4822                        return false;
4823                    }
4824                }
4825            }
4826            final long origId = Binder.clearCallingIdentity();
4827            try {
4828                boolean res;
4829                final boolean finishWithRootActivity =
4830                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4831                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4832                        || (finishWithRootActivity && r == rootR)) {
4833                    // If requested, remove the task that is associated to this activity only if it
4834                    // was the root activity in the task. The result code and data is ignored
4835                    // because we don't support returning them across task boundaries. Also, to
4836                    // keep backwards compatibility we remove the task from recents when finishing
4837                    // task with root activity.
4838                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4839                    if (!res) {
4840                        Slog.i(TAG, "Removing task failed to finish activity");
4841                    }
4842                } else {
4843                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4844                            resultData, "app-request", true);
4845                    if (!res) {
4846                        Slog.i(TAG, "Failed to finish by app-request");
4847                    }
4848                }
4849                return res;
4850            } finally {
4851                Binder.restoreCallingIdentity(origId);
4852            }
4853        }
4854    }
4855
4856    @Override
4857    public final void finishHeavyWeightApp() {
4858        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4859                != PackageManager.PERMISSION_GRANTED) {
4860            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4861                    + Binder.getCallingPid()
4862                    + ", uid=" + Binder.getCallingUid()
4863                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4864            Slog.w(TAG, msg);
4865            throw new SecurityException(msg);
4866        }
4867
4868        synchronized(this) {
4869            if (mHeavyWeightProcess == null) {
4870                return;
4871            }
4872
4873            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4874            for (int i = 0; i < activities.size(); i++) {
4875                ActivityRecord r = activities.get(i);
4876                if (!r.finishing && r.isInStackLocked()) {
4877                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4878                            null, "finish-heavy", true);
4879                }
4880            }
4881
4882            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4883                    mHeavyWeightProcess.userId, 0));
4884            mHeavyWeightProcess = null;
4885        }
4886    }
4887
4888    @Override
4889    public void crashApplication(int uid, int initialPid, String packageName,
4890            String message) {
4891        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4892                != PackageManager.PERMISSION_GRANTED) {
4893            String msg = "Permission Denial: crashApplication() from pid="
4894                    + Binder.getCallingPid()
4895                    + ", uid=" + Binder.getCallingUid()
4896                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4897            Slog.w(TAG, msg);
4898            throw new SecurityException(msg);
4899        }
4900
4901        synchronized(this) {
4902            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4903        }
4904    }
4905
4906    @Override
4907    public final void finishSubActivity(IBinder token, String resultWho,
4908            int requestCode) {
4909        synchronized(this) {
4910            final long origId = Binder.clearCallingIdentity();
4911            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4912            if (r != null) {
4913                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4914            }
4915            Binder.restoreCallingIdentity(origId);
4916        }
4917    }
4918
4919    @Override
4920    public boolean finishActivityAffinity(IBinder token) {
4921        synchronized(this) {
4922            final long origId = Binder.clearCallingIdentity();
4923            try {
4924                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4925                if (r == null) {
4926                    return false;
4927                }
4928
4929                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4930                // can finish.
4931                final TaskRecord task = r.task;
4932                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4933                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4934                    mStackSupervisor.showLockTaskToast();
4935                    return false;
4936                }
4937                return task.stack.finishActivityAffinityLocked(r);
4938            } finally {
4939                Binder.restoreCallingIdentity(origId);
4940            }
4941        }
4942    }
4943
4944    @Override
4945    public void finishVoiceTask(IVoiceInteractionSession session) {
4946        synchronized (this) {
4947            final long origId = Binder.clearCallingIdentity();
4948            try {
4949                // TODO: VI Consider treating local voice interactions and voice tasks
4950                // differently here
4951                mStackSupervisor.finishVoiceTask(session);
4952            } finally {
4953                Binder.restoreCallingIdentity(origId);
4954            }
4955        }
4956
4957    }
4958
4959    @Override
4960    public boolean releaseActivityInstance(IBinder token) {
4961        synchronized(this) {
4962            final long origId = Binder.clearCallingIdentity();
4963            try {
4964                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4965                if (r == null) {
4966                    return false;
4967                }
4968                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4969            } finally {
4970                Binder.restoreCallingIdentity(origId);
4971            }
4972        }
4973    }
4974
4975    @Override
4976    public void releaseSomeActivities(IApplicationThread appInt) {
4977        synchronized(this) {
4978            final long origId = Binder.clearCallingIdentity();
4979            try {
4980                ProcessRecord app = getRecordForAppLocked(appInt);
4981                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4982            } finally {
4983                Binder.restoreCallingIdentity(origId);
4984            }
4985        }
4986    }
4987
4988    @Override
4989    public boolean willActivityBeVisible(IBinder token) {
4990        synchronized(this) {
4991            ActivityStack stack = ActivityRecord.getStackLocked(token);
4992            if (stack != null) {
4993                return stack.willActivityBeVisibleLocked(token);
4994            }
4995            return false;
4996        }
4997    }
4998
4999    @Override
5000    public void overridePendingTransition(IBinder token, String packageName,
5001            int enterAnim, int exitAnim) {
5002        synchronized(this) {
5003            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5004            if (self == null) {
5005                return;
5006            }
5007
5008            final long origId = Binder.clearCallingIdentity();
5009
5010            if (self.state == ActivityState.RESUMED
5011                    || self.state == ActivityState.PAUSING) {
5012                mWindowManager.overridePendingAppTransition(packageName,
5013                        enterAnim, exitAnim, null);
5014            }
5015
5016            Binder.restoreCallingIdentity(origId);
5017        }
5018    }
5019
5020    /**
5021     * Main function for removing an existing process from the activity manager
5022     * as a result of that process going away.  Clears out all connections
5023     * to the process.
5024     */
5025    private final void handleAppDiedLocked(ProcessRecord app,
5026            boolean restarting, boolean allowRestart) {
5027        int pid = app.pid;
5028        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5029        if (!kept && !restarting) {
5030            removeLruProcessLocked(app);
5031            if (pid > 0) {
5032                ProcessList.remove(pid);
5033            }
5034        }
5035
5036        if (mProfileProc == app) {
5037            clearProfilerLocked();
5038        }
5039
5040        // Remove this application's activities from active lists.
5041        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5042
5043        app.activities.clear();
5044
5045        if (app.instrumentationClass != null) {
5046            Slog.w(TAG, "Crash of app " + app.processName
5047                  + " running instrumentation " + app.instrumentationClass);
5048            Bundle info = new Bundle();
5049            info.putString("shortMsg", "Process crashed.");
5050            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5051        }
5052
5053        if (!restarting && hasVisibleActivities
5054                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5055            // If there was nothing to resume, and we are not already restarting this process, but
5056            // there is a visible activity that is hosted by the process...  then make sure all
5057            // visible activities are running, taking care of restarting this process.
5058            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5059        }
5060    }
5061
5062    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5063        IBinder threadBinder = thread.asBinder();
5064        // Find the application record.
5065        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5066            ProcessRecord rec = mLruProcesses.get(i);
5067            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5068                return i;
5069            }
5070        }
5071        return -1;
5072    }
5073
5074    final ProcessRecord getRecordForAppLocked(
5075            IApplicationThread thread) {
5076        if (thread == null) {
5077            return null;
5078        }
5079
5080        int appIndex = getLRURecordIndexForAppLocked(thread);
5081        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5082    }
5083
5084    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5085        // If there are no longer any background processes running,
5086        // and the app that died was not running instrumentation,
5087        // then tell everyone we are now low on memory.
5088        boolean haveBg = false;
5089        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5090            ProcessRecord rec = mLruProcesses.get(i);
5091            if (rec.thread != null
5092                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5093                haveBg = true;
5094                break;
5095            }
5096        }
5097
5098        if (!haveBg) {
5099            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5100            if (doReport) {
5101                long now = SystemClock.uptimeMillis();
5102                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5103                    doReport = false;
5104                } else {
5105                    mLastMemUsageReportTime = now;
5106                }
5107            }
5108            final ArrayList<ProcessMemInfo> memInfos
5109                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5110            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5111            long now = SystemClock.uptimeMillis();
5112            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5113                ProcessRecord rec = mLruProcesses.get(i);
5114                if (rec == dyingProc || rec.thread == null) {
5115                    continue;
5116                }
5117                if (doReport) {
5118                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5119                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5120                }
5121                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5122                    // The low memory report is overriding any current
5123                    // state for a GC request.  Make sure to do
5124                    // heavy/important/visible/foreground processes first.
5125                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5126                        rec.lastRequestedGc = 0;
5127                    } else {
5128                        rec.lastRequestedGc = rec.lastLowMemory;
5129                    }
5130                    rec.reportLowMemory = true;
5131                    rec.lastLowMemory = now;
5132                    mProcessesToGc.remove(rec);
5133                    addProcessToGcListLocked(rec);
5134                }
5135            }
5136            if (doReport) {
5137                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5138                mHandler.sendMessage(msg);
5139            }
5140            scheduleAppGcsLocked();
5141        }
5142    }
5143
5144    final void appDiedLocked(ProcessRecord app) {
5145       appDiedLocked(app, app.pid, app.thread, false);
5146    }
5147
5148    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5149            boolean fromBinderDied) {
5150        // First check if this ProcessRecord is actually active for the pid.
5151        synchronized (mPidsSelfLocked) {
5152            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5153            if (curProc != app) {
5154                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5155                return;
5156            }
5157        }
5158
5159        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5160        synchronized (stats) {
5161            stats.noteProcessDiedLocked(app.info.uid, pid);
5162        }
5163
5164        if (!app.killed) {
5165            if (!fromBinderDied) {
5166                Process.killProcessQuiet(pid);
5167            }
5168            killProcessGroup(app.uid, pid);
5169            app.killed = true;
5170        }
5171
5172        // Clean up already done if the process has been re-started.
5173        if (app.pid == pid && app.thread != null &&
5174                app.thread.asBinder() == thread.asBinder()) {
5175            boolean doLowMem = app.instrumentationClass == null;
5176            boolean doOomAdj = doLowMem;
5177            if (!app.killedByAm) {
5178                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5179                        + ") has died");
5180                mAllowLowerMemLevel = true;
5181            } else {
5182                // Note that we always want to do oom adj to update our state with the
5183                // new number of procs.
5184                mAllowLowerMemLevel = false;
5185                doLowMem = false;
5186            }
5187            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5188            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5189                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5190            handleAppDiedLocked(app, false, true);
5191
5192            if (doOomAdj) {
5193                updateOomAdjLocked();
5194            }
5195            if (doLowMem) {
5196                doLowMemReportIfNeededLocked(app);
5197            }
5198        } else if (app.pid != pid) {
5199            // A new process has already been started.
5200            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5201                    + ") has died and restarted (pid " + app.pid + ").");
5202            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5203        } else if (DEBUG_PROCESSES) {
5204            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5205                    + thread.asBinder());
5206        }
5207    }
5208
5209    /**
5210     * If a stack trace dump file is configured, dump process stack traces.
5211     * @param clearTraces causes the dump file to be erased prior to the new
5212     *    traces being written, if true; when false, the new traces will be
5213     *    appended to any existing file content.
5214     * @param firstPids of dalvik VM processes to dump stack traces for first
5215     * @param lastPids of dalvik VM processes to dump stack traces for last
5216     * @param nativeProcs optional list of native process names to dump stack crawls
5217     * @return file containing stack traces, or null if no dump file is configured
5218     */
5219    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5220            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5221        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5222        if (tracesPath == null || tracesPath.length() == 0) {
5223            return null;
5224        }
5225
5226        File tracesFile = new File(tracesPath);
5227        try {
5228            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5229            tracesFile.createNewFile();
5230            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5231        } catch (IOException e) {
5232            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5233            return null;
5234        }
5235
5236        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5237        return tracesFile;
5238    }
5239
5240    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5241            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5242        // Use a FileObserver to detect when traces finish writing.
5243        // The order of traces is considered important to maintain for legibility.
5244        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5245            @Override
5246            public synchronized void onEvent(int event, String path) { notify(); }
5247        };
5248
5249        try {
5250            observer.startWatching();
5251
5252            // First collect all of the stacks of the most important pids.
5253            if (firstPids != null) {
5254                try {
5255                    int num = firstPids.size();
5256                    for (int i = 0; i < num; i++) {
5257                        synchronized (observer) {
5258                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5259                                    + firstPids.get(i));
5260                            final long sime = SystemClock.elapsedRealtime();
5261                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5262                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5263                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5264                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5265                        }
5266                    }
5267                } catch (InterruptedException e) {
5268                    Slog.wtf(TAG, e);
5269                }
5270            }
5271
5272            // Next collect the stacks of the native pids
5273            if (nativeProcs != null) {
5274                int[] pids = Process.getPidsForCommands(nativeProcs);
5275                if (pids != null) {
5276                    for (int pid : pids) {
5277                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5278                        final long sime = SystemClock.elapsedRealtime();
5279                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5280                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5281                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5282                    }
5283                }
5284            }
5285
5286            // Lastly, measure CPU usage.
5287            if (processCpuTracker != null) {
5288                processCpuTracker.init();
5289                System.gc();
5290                processCpuTracker.update();
5291                try {
5292                    synchronized (processCpuTracker) {
5293                        processCpuTracker.wait(500); // measure over 1/2 second.
5294                    }
5295                } catch (InterruptedException e) {
5296                }
5297                processCpuTracker.update();
5298
5299                // We'll take the stack crawls of just the top apps using CPU.
5300                final int N = processCpuTracker.countWorkingStats();
5301                int numProcs = 0;
5302                for (int i=0; i<N && numProcs<5; i++) {
5303                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5304                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5305                        numProcs++;
5306                        try {
5307                            synchronized (observer) {
5308                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5309                                        + stats.pid);
5310                                final long stime = SystemClock.elapsedRealtime();
5311                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5312                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5313                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5314                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5315                            }
5316                        } catch (InterruptedException e) {
5317                            Slog.wtf(TAG, e);
5318                        }
5319                    } else if (DEBUG_ANR) {
5320                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5321                                + stats.pid);
5322                    }
5323                }
5324            }
5325        } finally {
5326            observer.stopWatching();
5327        }
5328    }
5329
5330    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5331        if (true || IS_USER_BUILD) {
5332            return;
5333        }
5334        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5335        if (tracesPath == null || tracesPath.length() == 0) {
5336            return;
5337        }
5338
5339        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5340        StrictMode.allowThreadDiskWrites();
5341        try {
5342            final File tracesFile = new File(tracesPath);
5343            final File tracesDir = tracesFile.getParentFile();
5344            final File tracesTmp = new File(tracesDir, "__tmp__");
5345            try {
5346                if (tracesFile.exists()) {
5347                    tracesTmp.delete();
5348                    tracesFile.renameTo(tracesTmp);
5349                }
5350                StringBuilder sb = new StringBuilder();
5351                Time tobj = new Time();
5352                tobj.set(System.currentTimeMillis());
5353                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5354                sb.append(": ");
5355                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5356                sb.append(" since ");
5357                sb.append(msg);
5358                FileOutputStream fos = new FileOutputStream(tracesFile);
5359                fos.write(sb.toString().getBytes());
5360                if (app == null) {
5361                    fos.write("\n*** No application process!".getBytes());
5362                }
5363                fos.close();
5364                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5365            } catch (IOException e) {
5366                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5367                return;
5368            }
5369
5370            if (app != null) {
5371                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5372                firstPids.add(app.pid);
5373                dumpStackTraces(tracesPath, firstPids, null, null, null);
5374            }
5375
5376            File lastTracesFile = null;
5377            File curTracesFile = null;
5378            for (int i=9; i>=0; i--) {
5379                String name = String.format(Locale.US, "slow%02d.txt", i);
5380                curTracesFile = new File(tracesDir, name);
5381                if (curTracesFile.exists()) {
5382                    if (lastTracesFile != null) {
5383                        curTracesFile.renameTo(lastTracesFile);
5384                    } else {
5385                        curTracesFile.delete();
5386                    }
5387                }
5388                lastTracesFile = curTracesFile;
5389            }
5390            tracesFile.renameTo(curTracesFile);
5391            if (tracesTmp.exists()) {
5392                tracesTmp.renameTo(tracesFile);
5393            }
5394        } finally {
5395            StrictMode.setThreadPolicy(oldPolicy);
5396        }
5397    }
5398
5399    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5400        if (!mLaunchWarningShown) {
5401            mLaunchWarningShown = true;
5402            mUiHandler.post(new Runnable() {
5403                @Override
5404                public void run() {
5405                    synchronized (ActivityManagerService.this) {
5406                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5407                        d.show();
5408                        mUiHandler.postDelayed(new Runnable() {
5409                            @Override
5410                            public void run() {
5411                                synchronized (ActivityManagerService.this) {
5412                                    d.dismiss();
5413                                    mLaunchWarningShown = false;
5414                                }
5415                            }
5416                        }, 4000);
5417                    }
5418                }
5419            });
5420        }
5421    }
5422
5423    @Override
5424    public boolean clearApplicationUserData(final String packageName,
5425            final IPackageDataObserver observer, int userId) {
5426        enforceNotIsolatedCaller("clearApplicationUserData");
5427        int uid = Binder.getCallingUid();
5428        int pid = Binder.getCallingPid();
5429        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5430                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5431
5432
5433        long callingId = Binder.clearCallingIdentity();
5434        try {
5435            IPackageManager pm = AppGlobals.getPackageManager();
5436            int pkgUid = -1;
5437            synchronized(this) {
5438                if (getPackageManagerInternalLocked().canPackageBeWiped(
5439                        userId, packageName)) {
5440                    throw new SecurityException(
5441                            "Cannot clear data for a device owner or a profile owner");
5442                }
5443
5444                try {
5445                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5446                } catch (RemoteException e) {
5447                }
5448                if (pkgUid == -1) {
5449                    Slog.w(TAG, "Invalid packageName: " + packageName);
5450                    if (observer != null) {
5451                        try {
5452                            observer.onRemoveCompleted(packageName, false);
5453                        } catch (RemoteException e) {
5454                            Slog.i(TAG, "Observer no longer exists.");
5455                        }
5456                    }
5457                    return false;
5458                }
5459                if (uid == pkgUid || checkComponentPermission(
5460                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5461                        pid, uid, -1, true)
5462                        == PackageManager.PERMISSION_GRANTED) {
5463                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5464                } else {
5465                    throw new SecurityException("PID " + pid + " does not have permission "
5466                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5467                                    + " of package " + packageName);
5468                }
5469
5470                // Remove all tasks match the cleared application package and user
5471                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5472                    final TaskRecord tr = mRecentTasks.get(i);
5473                    final String taskPackageName =
5474                            tr.getBaseIntent().getComponent().getPackageName();
5475                    if (tr.userId != userId) continue;
5476                    if (!taskPackageName.equals(packageName)) continue;
5477                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5478                }
5479            }
5480
5481            final int pkgUidF = pkgUid;
5482            final int userIdF = userId;
5483            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5484                @Override
5485                public void onRemoveCompleted(String packageName, boolean succeeded)
5486                        throws RemoteException {
5487                    synchronized (ActivityManagerService.this) {
5488                        finishForceStopPackageLocked(packageName, pkgUidF);
5489                    }
5490
5491                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5492                            Uri.fromParts("package", packageName, null));
5493                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5494                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5495                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5496                            null, null, 0, null, null, null, null, false, false, userIdF);
5497
5498                    if (observer != null) {
5499                        observer.onRemoveCompleted(packageName, succeeded);
5500                    }
5501                }
5502            };
5503
5504            try {
5505                // Clear application user data
5506                pm.clearApplicationUserData(packageName, localObserver, userId);
5507
5508                synchronized(this) {
5509                    // Remove all permissions granted from/to this package
5510                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5511                }
5512
5513                // Remove all zen rules created by this package; revoke it's zen access.
5514                INotificationManager inm = NotificationManager.getService();
5515                inm.removeAutomaticZenRules(packageName);
5516                inm.setNotificationPolicyAccessGranted(packageName, false);
5517
5518            } catch (RemoteException e) {
5519            }
5520        } finally {
5521            Binder.restoreCallingIdentity(callingId);
5522        }
5523        return true;
5524    }
5525
5526    @Override
5527    public void killBackgroundProcesses(final String packageName, int userId) {
5528        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5529                != PackageManager.PERMISSION_GRANTED &&
5530                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5531                        != PackageManager.PERMISSION_GRANTED) {
5532            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5533                    + Binder.getCallingPid()
5534                    + ", uid=" + Binder.getCallingUid()
5535                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5536            Slog.w(TAG, msg);
5537            throw new SecurityException(msg);
5538        }
5539
5540        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5541                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5542        long callingId = Binder.clearCallingIdentity();
5543        try {
5544            IPackageManager pm = AppGlobals.getPackageManager();
5545            synchronized(this) {
5546                int appId = -1;
5547                try {
5548                    appId = UserHandle.getAppId(
5549                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5550                } catch (RemoteException e) {
5551                }
5552                if (appId == -1) {
5553                    Slog.w(TAG, "Invalid packageName: " + packageName);
5554                    return;
5555                }
5556                killPackageProcessesLocked(packageName, appId, userId,
5557                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5558            }
5559        } finally {
5560            Binder.restoreCallingIdentity(callingId);
5561        }
5562    }
5563
5564    @Override
5565    public void killAllBackgroundProcesses() {
5566        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5567                != PackageManager.PERMISSION_GRANTED) {
5568            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5569                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5570                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5571            Slog.w(TAG, msg);
5572            throw new SecurityException(msg);
5573        }
5574
5575        final long callingId = Binder.clearCallingIdentity();
5576        try {
5577            synchronized (this) {
5578                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5579                final int NP = mProcessNames.getMap().size();
5580                for (int ip = 0; ip < NP; ip++) {
5581                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5582                    final int NA = apps.size();
5583                    for (int ia = 0; ia < NA; ia++) {
5584                        final ProcessRecord app = apps.valueAt(ia);
5585                        if (app.persistent) {
5586                            // We don't kill persistent processes.
5587                            continue;
5588                        }
5589                        if (app.removed) {
5590                            procs.add(app);
5591                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
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");
5601                }
5602
5603                mAllowLowerMemLevel = true;
5604
5605                updateOomAdjLocked();
5606                doLowMemReportIfNeededLocked(null);
5607            }
5608        } finally {
5609            Binder.restoreCallingIdentity(callingId);
5610        }
5611    }
5612
5613    /**
5614     * Kills all background processes, except those matching any of the
5615     * specified properties.
5616     *
5617     * @param minTargetSdk the target SDK version at or above which to preserve
5618     *                     processes, or {@code -1} to ignore the target SDK
5619     * @param maxProcState the process state at or below which to preserve
5620     *                     processes, or {@code -1} to ignore the process state
5621     */
5622    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5623        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5624                != PackageManager.PERMISSION_GRANTED) {
5625            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5626                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5627                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5628            Slog.w(TAG, msg);
5629            throw new SecurityException(msg);
5630        }
5631
5632        final long callingId = Binder.clearCallingIdentity();
5633        try {
5634            synchronized (this) {
5635                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5636                final int NP = mProcessNames.getMap().size();
5637                for (int ip = 0; ip < NP; ip++) {
5638                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5639                    final int NA = apps.size();
5640                    for (int ia = 0; ia < NA; ia++) {
5641                        final ProcessRecord app = apps.valueAt(ia);
5642                        if (app.removed) {
5643                            procs.add(app);
5644                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5645                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5646                            app.removed = true;
5647                            procs.add(app);
5648                        }
5649                    }
5650                }
5651
5652                final int N = procs.size();
5653                for (int i = 0; i < N; i++) {
5654                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5655                }
5656            }
5657        } finally {
5658            Binder.restoreCallingIdentity(callingId);
5659        }
5660    }
5661
5662    @Override
5663    public void forceStopPackage(final String packageName, int userId) {
5664        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5665                != PackageManager.PERMISSION_GRANTED) {
5666            String msg = "Permission Denial: forceStopPackage() from pid="
5667                    + Binder.getCallingPid()
5668                    + ", uid=" + Binder.getCallingUid()
5669                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5670            Slog.w(TAG, msg);
5671            throw new SecurityException(msg);
5672        }
5673        final int callingPid = Binder.getCallingPid();
5674        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5675                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5676        long callingId = Binder.clearCallingIdentity();
5677        try {
5678            IPackageManager pm = AppGlobals.getPackageManager();
5679            synchronized(this) {
5680                int[] users = userId == UserHandle.USER_ALL
5681                        ? mUserController.getUsers() : new int[] { userId };
5682                for (int user : users) {
5683                    int pkgUid = -1;
5684                    try {
5685                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5686                                user);
5687                    } catch (RemoteException e) {
5688                    }
5689                    if (pkgUid == -1) {
5690                        Slog.w(TAG, "Invalid packageName: " + packageName);
5691                        continue;
5692                    }
5693                    try {
5694                        pm.setPackageStoppedState(packageName, true, user);
5695                    } catch (RemoteException e) {
5696                    } catch (IllegalArgumentException e) {
5697                        Slog.w(TAG, "Failed trying to unstop package "
5698                                + packageName + ": " + e);
5699                    }
5700                    if (mUserController.isUserRunningLocked(user, 0)) {
5701                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5702                        finishForceStopPackageLocked(packageName, pkgUid);
5703                    }
5704                }
5705            }
5706        } finally {
5707            Binder.restoreCallingIdentity(callingId);
5708        }
5709    }
5710
5711    @Override
5712    public void addPackageDependency(String packageName) {
5713        synchronized (this) {
5714            int callingPid = Binder.getCallingPid();
5715            if (callingPid == Process.myPid()) {
5716                //  Yeah, um, no.
5717                return;
5718            }
5719            ProcessRecord proc;
5720            synchronized (mPidsSelfLocked) {
5721                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5722            }
5723            if (proc != null) {
5724                if (proc.pkgDeps == null) {
5725                    proc.pkgDeps = new ArraySet<String>(1);
5726                }
5727                proc.pkgDeps.add(packageName);
5728            }
5729        }
5730    }
5731
5732    /*
5733     * The pkg name and app id have to be specified.
5734     */
5735    @Override
5736    public void killApplication(String pkg, int appId, int userId, String reason) {
5737        if (pkg == null) {
5738            return;
5739        }
5740        // Make sure the uid is valid.
5741        if (appId < 0) {
5742            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5743            return;
5744        }
5745        int callerUid = Binder.getCallingUid();
5746        // Only the system server can kill an application
5747        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5748            // Post an aysnc message to kill the application
5749            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5750            msg.arg1 = appId;
5751            msg.arg2 = userId;
5752            Bundle bundle = new Bundle();
5753            bundle.putString("pkg", pkg);
5754            bundle.putString("reason", reason);
5755            msg.obj = bundle;
5756            mHandler.sendMessage(msg);
5757        } else {
5758            throw new SecurityException(callerUid + " cannot kill pkg: " +
5759                    pkg);
5760        }
5761    }
5762
5763    @Override
5764    public void closeSystemDialogs(String reason) {
5765        enforceNotIsolatedCaller("closeSystemDialogs");
5766
5767        final int pid = Binder.getCallingPid();
5768        final int uid = Binder.getCallingUid();
5769        final long origId = Binder.clearCallingIdentity();
5770        try {
5771            synchronized (this) {
5772                // Only allow this from foreground processes, so that background
5773                // applications can't abuse it to prevent system UI from being shown.
5774                if (uid >= Process.FIRST_APPLICATION_UID) {
5775                    ProcessRecord proc;
5776                    synchronized (mPidsSelfLocked) {
5777                        proc = mPidsSelfLocked.get(pid);
5778                    }
5779                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5780                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5781                                + " from background process " + proc);
5782                        return;
5783                    }
5784                }
5785                closeSystemDialogsLocked(reason);
5786            }
5787        } finally {
5788            Binder.restoreCallingIdentity(origId);
5789        }
5790    }
5791
5792    void closeSystemDialogsLocked(String reason) {
5793        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5794        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5795                | Intent.FLAG_RECEIVER_FOREGROUND);
5796        if (reason != null) {
5797            intent.putExtra("reason", reason);
5798        }
5799        mWindowManager.closeSystemDialogs(reason);
5800
5801        mStackSupervisor.closeSystemDialogsLocked();
5802
5803        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5804                AppOpsManager.OP_NONE, null, false, false,
5805                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5806    }
5807
5808    @Override
5809    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5810        enforceNotIsolatedCaller("getProcessMemoryInfo");
5811        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5812        for (int i=pids.length-1; i>=0; i--) {
5813            ProcessRecord proc;
5814            int oomAdj;
5815            synchronized (this) {
5816                synchronized (mPidsSelfLocked) {
5817                    proc = mPidsSelfLocked.get(pids[i]);
5818                    oomAdj = proc != null ? proc.setAdj : 0;
5819                }
5820            }
5821            infos[i] = new Debug.MemoryInfo();
5822            Debug.getMemoryInfo(pids[i], infos[i]);
5823            if (proc != null) {
5824                synchronized (this) {
5825                    if (proc.thread != null && proc.setAdj == oomAdj) {
5826                        // Record this for posterity if the process has been stable.
5827                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5828                                infos[i].getTotalUss(), false, proc.pkgList);
5829                    }
5830                }
5831            }
5832        }
5833        return infos;
5834    }
5835
5836    @Override
5837    public long[] getProcessPss(int[] pids) {
5838        enforceNotIsolatedCaller("getProcessPss");
5839        long[] pss = new long[pids.length];
5840        for (int i=pids.length-1; i>=0; i--) {
5841            ProcessRecord proc;
5842            int oomAdj;
5843            synchronized (this) {
5844                synchronized (mPidsSelfLocked) {
5845                    proc = mPidsSelfLocked.get(pids[i]);
5846                    oomAdj = proc != null ? proc.setAdj : 0;
5847                }
5848            }
5849            long[] tmpUss = new long[1];
5850            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5851            if (proc != null) {
5852                synchronized (this) {
5853                    if (proc.thread != null && proc.setAdj == oomAdj) {
5854                        // Record this for posterity if the process has been stable.
5855                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5856                    }
5857                }
5858            }
5859        }
5860        return pss;
5861    }
5862
5863    @Override
5864    public void killApplicationProcess(String processName, int uid) {
5865        if (processName == null) {
5866            return;
5867        }
5868
5869        int callerUid = Binder.getCallingUid();
5870        // Only the system server can kill an application
5871        if (callerUid == Process.SYSTEM_UID) {
5872            synchronized (this) {
5873                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5874                if (app != null && app.thread != null) {
5875                    try {
5876                        app.thread.scheduleSuicide();
5877                    } catch (RemoteException e) {
5878                        // If the other end already died, then our work here is done.
5879                    }
5880                } else {
5881                    Slog.w(TAG, "Process/uid not found attempting kill of "
5882                            + processName + " / " + uid);
5883                }
5884            }
5885        } else {
5886            throw new SecurityException(callerUid + " cannot kill app process: " +
5887                    processName);
5888        }
5889    }
5890
5891    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5892        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5893                false, true, false, false, UserHandle.getUserId(uid), reason);
5894    }
5895
5896    private void finishForceStopPackageLocked(final String packageName, int uid) {
5897        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5898                Uri.fromParts("package", packageName, null));
5899        if (!mProcessesReady) {
5900            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5901                    | Intent.FLAG_RECEIVER_FOREGROUND);
5902        }
5903        intent.putExtra(Intent.EXTRA_UID, uid);
5904        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5905        broadcastIntentLocked(null, null, intent,
5906                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5907                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5908    }
5909
5910
5911    private final boolean killPackageProcessesLocked(String packageName, int appId,
5912            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5913            boolean doit, boolean evenPersistent, String reason) {
5914        ArrayList<ProcessRecord> procs = new ArrayList<>();
5915
5916        // Remove all processes this package may have touched: all with the
5917        // same UID (except for the system or root user), and all whose name
5918        // matches the package name.
5919        final int NP = mProcessNames.getMap().size();
5920        for (int ip=0; ip<NP; ip++) {
5921            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5922            final int NA = apps.size();
5923            for (int ia=0; ia<NA; ia++) {
5924                ProcessRecord app = apps.valueAt(ia);
5925                if (app.persistent && !evenPersistent) {
5926                    // we don't kill persistent processes
5927                    continue;
5928                }
5929                if (app.removed) {
5930                    if (doit) {
5931                        procs.add(app);
5932                    }
5933                    continue;
5934                }
5935
5936                // Skip process if it doesn't meet our oom adj requirement.
5937                if (app.setAdj < minOomAdj) {
5938                    continue;
5939                }
5940
5941                // If no package is specified, we call all processes under the
5942                // give user id.
5943                if (packageName == null) {
5944                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5945                        continue;
5946                    }
5947                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5948                        continue;
5949                    }
5950                // Package has been specified, we want to hit all processes
5951                // that match it.  We need to qualify this by the processes
5952                // that are running under the specified app and user ID.
5953                } else {
5954                    final boolean isDep = app.pkgDeps != null
5955                            && app.pkgDeps.contains(packageName);
5956                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5957                        continue;
5958                    }
5959                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5960                        continue;
5961                    }
5962                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5963                        continue;
5964                    }
5965                }
5966
5967                // Process has passed all conditions, kill it!
5968                if (!doit) {
5969                    return true;
5970                }
5971                app.removed = true;
5972                procs.add(app);
5973            }
5974        }
5975
5976        int N = procs.size();
5977        for (int i=0; i<N; i++) {
5978            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5979        }
5980        updateOomAdjLocked();
5981        return N > 0;
5982    }
5983
5984    private void cleanupDisabledPackageComponentsLocked(
5985            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5986
5987        Set<String> disabledClasses = null;
5988        boolean packageDisabled = false;
5989        IPackageManager pm = AppGlobals.getPackageManager();
5990
5991        if (changedClasses == null) {
5992            // Nothing changed...
5993            return;
5994        }
5995
5996        // Determine enable/disable state of the package and its components.
5997        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5998        for (int i = changedClasses.length - 1; i >= 0; i--) {
5999            final String changedClass = changedClasses[i];
6000
6001            if (changedClass.equals(packageName)) {
6002                try {
6003                    // Entire package setting changed
6004                    enabled = pm.getApplicationEnabledSetting(packageName,
6005                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6006                } catch (Exception e) {
6007                    // No such package/component; probably racing with uninstall.  In any
6008                    // event it means we have nothing further to do here.
6009                    return;
6010                }
6011                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6012                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6013                if (packageDisabled) {
6014                    // Entire package is disabled.
6015                    // No need to continue to check component states.
6016                    disabledClasses = null;
6017                    break;
6018                }
6019            } else {
6020                try {
6021                    enabled = pm.getComponentEnabledSetting(
6022                            new ComponentName(packageName, changedClass),
6023                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6024                } catch (Exception e) {
6025                    // As above, probably racing with uninstall.
6026                    return;
6027                }
6028                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6029                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6030                    if (disabledClasses == null) {
6031                        disabledClasses = new ArraySet<>(changedClasses.length);
6032                    }
6033                    disabledClasses.add(changedClass);
6034                }
6035            }
6036        }
6037
6038        if (!packageDisabled && disabledClasses == null) {
6039            // Nothing to do here...
6040            return;
6041        }
6042
6043        // Clean-up disabled activities.
6044        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6045                packageName, disabledClasses, true, false, userId) && mBooted) {
6046            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6047            mStackSupervisor.scheduleIdleLocked();
6048        }
6049
6050        // Clean-up disabled tasks
6051        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6052
6053        // Clean-up disabled services.
6054        mServices.bringDownDisabledPackageServicesLocked(
6055                packageName, disabledClasses, userId, false, killProcess, true);
6056
6057        // Clean-up disabled providers.
6058        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6059        mProviderMap.collectPackageProvidersLocked(
6060                packageName, disabledClasses, true, false, userId, providers);
6061        for (int i = providers.size() - 1; i >= 0; i--) {
6062            removeDyingProviderLocked(null, providers.get(i), true);
6063        }
6064
6065        // Clean-up disabled broadcast receivers.
6066        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6067            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6068                    packageName, disabledClasses, userId, true);
6069        }
6070
6071    }
6072
6073    final boolean clearBroadcastQueueForUserLocked(int userId) {
6074        boolean didSomething = false;
6075        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6076            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6077                    null, null, userId, true);
6078        }
6079        return didSomething;
6080    }
6081
6082    final boolean forceStopPackageLocked(String packageName, int appId,
6083            boolean callerWillRestart, boolean purgeCache, boolean doit,
6084            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6085        int i;
6086
6087        if (userId == UserHandle.USER_ALL && packageName == null) {
6088            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6089        }
6090
6091        if (appId < 0 && packageName != null) {
6092            try {
6093                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6094                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6095            } catch (RemoteException e) {
6096            }
6097        }
6098
6099        if (doit) {
6100            if (packageName != null) {
6101                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6102                        + " user=" + userId + ": " + reason);
6103            } else {
6104                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6105            }
6106
6107            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6108        }
6109
6110        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6111                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6112                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6113
6114        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6115
6116        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6117                packageName, null, doit, evenPersistent, userId)) {
6118            if (!doit) {
6119                return true;
6120            }
6121            didSomething = true;
6122        }
6123
6124        if (mServices.bringDownDisabledPackageServicesLocked(
6125                packageName, null, userId, evenPersistent, true, doit)) {
6126            if (!doit) {
6127                return true;
6128            }
6129            didSomething = true;
6130        }
6131
6132        if (packageName == null) {
6133            // Remove all sticky broadcasts from this user.
6134            mStickyBroadcasts.remove(userId);
6135        }
6136
6137        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6138        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6139                userId, providers)) {
6140            if (!doit) {
6141                return true;
6142            }
6143            didSomething = true;
6144        }
6145        for (i = providers.size() - 1; i >= 0; i--) {
6146            removeDyingProviderLocked(null, providers.get(i), true);
6147        }
6148
6149        // Remove transient permissions granted from/to this package/user
6150        removeUriPermissionsForPackageLocked(packageName, userId, false);
6151
6152        if (doit) {
6153            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6154                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6155                        packageName, null, userId, doit);
6156            }
6157        }
6158
6159        if (packageName == null || uninstalling) {
6160            // Remove pending intents.  For now we only do this when force
6161            // stopping users, because we have some problems when doing this
6162            // for packages -- app widgets are not currently cleaned up for
6163            // such packages, so they can be left with bad pending intents.
6164            if (mIntentSenderRecords.size() > 0) {
6165                Iterator<WeakReference<PendingIntentRecord>> it
6166                        = mIntentSenderRecords.values().iterator();
6167                while (it.hasNext()) {
6168                    WeakReference<PendingIntentRecord> wpir = it.next();
6169                    if (wpir == null) {
6170                        it.remove();
6171                        continue;
6172                    }
6173                    PendingIntentRecord pir = wpir.get();
6174                    if (pir == null) {
6175                        it.remove();
6176                        continue;
6177                    }
6178                    if (packageName == null) {
6179                        // Stopping user, remove all objects for the user.
6180                        if (pir.key.userId != userId) {
6181                            // Not the same user, skip it.
6182                            continue;
6183                        }
6184                    } else {
6185                        if (UserHandle.getAppId(pir.uid) != appId) {
6186                            // Different app id, skip it.
6187                            continue;
6188                        }
6189                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6190                            // Different user, skip it.
6191                            continue;
6192                        }
6193                        if (!pir.key.packageName.equals(packageName)) {
6194                            // Different package, skip it.
6195                            continue;
6196                        }
6197                    }
6198                    if (!doit) {
6199                        return true;
6200                    }
6201                    didSomething = true;
6202                    it.remove();
6203                    pir.canceled = true;
6204                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6205                        pir.key.activity.pendingResults.remove(pir.ref);
6206                    }
6207                }
6208            }
6209        }
6210
6211        if (doit) {
6212            if (purgeCache && packageName != null) {
6213                AttributeCache ac = AttributeCache.instance();
6214                if (ac != null) {
6215                    ac.removePackage(packageName);
6216                }
6217            }
6218            if (mBooted) {
6219                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6220                mStackSupervisor.scheduleIdleLocked();
6221            }
6222        }
6223
6224        return didSomething;
6225    }
6226
6227    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6228        ProcessRecord old = mProcessNames.remove(name, uid);
6229        if (old != null) {
6230            old.uidRecord.numProcs--;
6231            if (old.uidRecord.numProcs == 0) {
6232                // No more processes using this uid, tell clients it is gone.
6233                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6234                        "No more processes in " + old.uidRecord);
6235                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6236                mActiveUids.remove(uid);
6237                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6238            }
6239            old.uidRecord = null;
6240        }
6241        mIsolatedProcesses.remove(uid);
6242        return old;
6243    }
6244
6245    private final void addProcessNameLocked(ProcessRecord proc) {
6246        // We shouldn't already have a process under this name, but just in case we
6247        // need to clean up whatever may be there now.
6248        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6249        if (old == proc && proc.persistent) {
6250            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6251            Slog.w(TAG, "Re-adding persistent process " + proc);
6252        } else if (old != null) {
6253            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6254        }
6255        UidRecord uidRec = mActiveUids.get(proc.uid);
6256        if (uidRec == null) {
6257            uidRec = new UidRecord(proc.uid);
6258            // This is the first appearance of the uid, report it now!
6259            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6260                    "Creating new process uid: " + uidRec);
6261            mActiveUids.put(proc.uid, uidRec);
6262            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6263            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6264        }
6265        proc.uidRecord = uidRec;
6266        uidRec.numProcs++;
6267        mProcessNames.put(proc.processName, proc.uid, proc);
6268        if (proc.isolated) {
6269            mIsolatedProcesses.put(proc.uid, proc);
6270        }
6271    }
6272
6273    boolean removeProcessLocked(ProcessRecord app,
6274            boolean callerWillRestart, boolean allowRestart, String reason) {
6275        final String name = app.processName;
6276        final int uid = app.uid;
6277        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6278            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6279
6280        ProcessRecord old = mProcessNames.get(name, uid);
6281        if (old != app) {
6282            // This process is no longer active, so nothing to do.
6283            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6284            return false;
6285        }
6286        removeProcessNameLocked(name, uid);
6287        if (mHeavyWeightProcess == app) {
6288            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6289                    mHeavyWeightProcess.userId, 0));
6290            mHeavyWeightProcess = null;
6291        }
6292        boolean needRestart = false;
6293        if (app.pid > 0 && app.pid != MY_PID) {
6294            int pid = app.pid;
6295            synchronized (mPidsSelfLocked) {
6296                mPidsSelfLocked.remove(pid);
6297                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6298            }
6299            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6300            if (app.isolated) {
6301                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6302            }
6303            boolean willRestart = false;
6304            if (app.persistent && !app.isolated) {
6305                if (!callerWillRestart) {
6306                    willRestart = true;
6307                } else {
6308                    needRestart = true;
6309                }
6310            }
6311            app.kill(reason, true);
6312            handleAppDiedLocked(app, willRestart, allowRestart);
6313            if (willRestart) {
6314                removeLruProcessLocked(app);
6315                addAppLocked(app.info, false, null /* ABI override */);
6316            }
6317        } else {
6318            mRemovedProcesses.add(app);
6319        }
6320
6321        return needRestart;
6322    }
6323
6324    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6325        cleanupAppInLaunchingProvidersLocked(app, true);
6326        removeProcessLocked(app, false, true, "timeout publishing content providers");
6327    }
6328
6329    private final void processStartTimedOutLocked(ProcessRecord app) {
6330        final int pid = app.pid;
6331        boolean gone = false;
6332        synchronized (mPidsSelfLocked) {
6333            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6334            if (knownApp != null && knownApp.thread == null) {
6335                mPidsSelfLocked.remove(pid);
6336                gone = true;
6337            }
6338        }
6339
6340        if (gone) {
6341            Slog.w(TAG, "Process " + app + " failed to attach");
6342            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6343                    pid, app.uid, app.processName);
6344            removeProcessNameLocked(app.processName, app.uid);
6345            if (mHeavyWeightProcess == app) {
6346                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6347                        mHeavyWeightProcess.userId, 0));
6348                mHeavyWeightProcess = null;
6349            }
6350            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6351            if (app.isolated) {
6352                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6353            }
6354            // Take care of any launching providers waiting for this process.
6355            cleanupAppInLaunchingProvidersLocked(app, true);
6356            // Take care of any services that are waiting for the process.
6357            mServices.processStartTimedOutLocked(app);
6358            app.kill("start timeout", true);
6359            removeLruProcessLocked(app);
6360            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6361                Slog.w(TAG, "Unattached app died before backup, skipping");
6362                mHandler.post(new Runnable() {
6363                @Override
6364                    public void run(){
6365                        try {
6366                            IBackupManager bm = IBackupManager.Stub.asInterface(
6367                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6368                            bm.agentDisconnected(app.info.packageName);
6369                        } catch (RemoteException e) {
6370                            // Can't happen; the backup manager is local
6371                        }
6372                    }
6373                });
6374            }
6375            if (isPendingBroadcastProcessLocked(pid)) {
6376                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6377                skipPendingBroadcastLocked(pid);
6378            }
6379        } else {
6380            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6381        }
6382    }
6383
6384    private final boolean attachApplicationLocked(IApplicationThread thread,
6385            int pid) {
6386
6387        // Find the application record that is being attached...  either via
6388        // the pid if we are running in multiple processes, or just pull the
6389        // next app record if we are emulating process with anonymous threads.
6390        ProcessRecord app;
6391        if (pid != MY_PID && pid >= 0) {
6392            synchronized (mPidsSelfLocked) {
6393                app = mPidsSelfLocked.get(pid);
6394            }
6395        } else {
6396            app = null;
6397        }
6398
6399        if (app == null) {
6400            Slog.w(TAG, "No pending application record for pid " + pid
6401                    + " (IApplicationThread " + thread + "); dropping process");
6402            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6403            if (pid > 0 && pid != MY_PID) {
6404                Process.killProcessQuiet(pid);
6405                //TODO: killProcessGroup(app.info.uid, pid);
6406            } else {
6407                try {
6408                    thread.scheduleExit();
6409                } catch (Exception e) {
6410                    // Ignore exceptions.
6411                }
6412            }
6413            return false;
6414        }
6415
6416        // If this application record is still attached to a previous
6417        // process, clean it up now.
6418        if (app.thread != null) {
6419            handleAppDiedLocked(app, true, true);
6420        }
6421
6422        // Tell the process all about itself.
6423
6424        if (DEBUG_ALL) Slog.v(
6425                TAG, "Binding process pid " + pid + " to record " + app);
6426
6427        final String processName = app.processName;
6428        try {
6429            AppDeathRecipient adr = new AppDeathRecipient(
6430                    app, pid, thread);
6431            thread.asBinder().linkToDeath(adr, 0);
6432            app.deathRecipient = adr;
6433        } catch (RemoteException e) {
6434            app.resetPackageList(mProcessStats);
6435            startProcessLocked(app, "link fail", processName);
6436            return false;
6437        }
6438
6439        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6440
6441        app.makeActive(thread, mProcessStats);
6442        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6443        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6444        app.forcingToForeground = null;
6445        updateProcessForegroundLocked(app, false, false);
6446        app.hasShownUi = false;
6447        app.debugging = false;
6448        app.cached = false;
6449        app.killedByAm = false;
6450        app.killed = false;
6451
6452
6453        // We carefully use the same state that PackageManager uses for
6454        // filtering, since we use this flag to decide if we need to install
6455        // providers when user is unlocked later
6456        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6457
6458        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6459
6460        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6461        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6462
6463        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6464            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6465            msg.obj = app;
6466            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6467        }
6468
6469        if (!normalMode) {
6470            Slog.i(TAG, "Launching preboot mode app: " + app);
6471        }
6472
6473        if (DEBUG_ALL) Slog.v(
6474            TAG, "New app record " + app
6475            + " thread=" + thread.asBinder() + " pid=" + pid);
6476        try {
6477            int testMode = IApplicationThread.DEBUG_OFF;
6478            if (mDebugApp != null && mDebugApp.equals(processName)) {
6479                testMode = mWaitForDebugger
6480                    ? IApplicationThread.DEBUG_WAIT
6481                    : IApplicationThread.DEBUG_ON;
6482                app.debugging = true;
6483                if (mDebugTransient) {
6484                    mDebugApp = mOrigDebugApp;
6485                    mWaitForDebugger = mOrigWaitForDebugger;
6486                }
6487            }
6488            String profileFile = app.instrumentationProfileFile;
6489            ParcelFileDescriptor profileFd = null;
6490            int samplingInterval = 0;
6491            boolean profileAutoStop = false;
6492            if (mProfileApp != null && mProfileApp.equals(processName)) {
6493                mProfileProc = app;
6494                profileFile = mProfileFile;
6495                profileFd = mProfileFd;
6496                samplingInterval = mSamplingInterval;
6497                profileAutoStop = mAutoStopProfiler;
6498            }
6499            boolean enableTrackAllocation = false;
6500            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6501                enableTrackAllocation = true;
6502                mTrackAllocationApp = null;
6503            }
6504
6505            // If the app is being launched for restore or full backup, set it up specially
6506            boolean isRestrictedBackupMode = false;
6507            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6508                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6509                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6510                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6511                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6512            }
6513
6514            if (app.instrumentationClass != null) {
6515                notifyPackageUse(app.instrumentationClass.getPackageName(),
6516                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6517            }
6518            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6519                    + processName + " with config " + mConfiguration);
6520            ApplicationInfo appInfo = app.instrumentationInfo != null
6521                    ? app.instrumentationInfo : app.info;
6522            app.compat = compatibilityInfoForPackageLocked(appInfo);
6523            if (profileFd != null) {
6524                profileFd = profileFd.dup();
6525            }
6526            ProfilerInfo profilerInfo = profileFile == null ? null
6527                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6528            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6529                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6530                    app.instrumentationUiAutomationConnection, testMode,
6531                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6532                    isRestrictedBackupMode || !normalMode, app.persistent,
6533                    new Configuration(mConfiguration), app.compat,
6534                    getCommonServicesLocked(app.isolated),
6535                    mCoreSettingsObserver.getCoreSettingsLocked());
6536            updateLruProcessLocked(app, false, null);
6537            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6538        } catch (Exception e) {
6539            // todo: Yikes!  What should we do?  For now we will try to
6540            // start another process, but that could easily get us in
6541            // an infinite loop of restarting processes...
6542            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6543
6544            app.resetPackageList(mProcessStats);
6545            app.unlinkDeathRecipient();
6546            startProcessLocked(app, "bind fail", processName);
6547            return false;
6548        }
6549
6550        // Remove this record from the list of starting applications.
6551        mPersistentStartingProcesses.remove(app);
6552        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6553                "Attach application locked removing on hold: " + app);
6554        mProcessesOnHold.remove(app);
6555
6556        boolean badApp = false;
6557        boolean didSomething = false;
6558
6559        // See if the top visible activity is waiting to run in this process...
6560        if (normalMode) {
6561            try {
6562                if (mStackSupervisor.attachApplicationLocked(app)) {
6563                    didSomething = true;
6564                }
6565            } catch (Exception e) {
6566                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6567                badApp = true;
6568            }
6569        }
6570
6571        // Find any services that should be running in this process...
6572        if (!badApp) {
6573            try {
6574                didSomething |= mServices.attachApplicationLocked(app, processName);
6575            } catch (Exception e) {
6576                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6577                badApp = true;
6578            }
6579        }
6580
6581        // Check if a next-broadcast receiver is in this process...
6582        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6583            try {
6584                didSomething |= sendPendingBroadcastsLocked(app);
6585            } catch (Exception e) {
6586                // If the app died trying to launch the receiver we declare it 'bad'
6587                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6588                badApp = true;
6589            }
6590        }
6591
6592        // Check whether the next backup agent is in this process...
6593        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6594            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6595                    "New app is backup target, launching agent for " + app);
6596            notifyPackageUse(mBackupTarget.appInfo.packageName,
6597                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6598            try {
6599                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6600                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6601                        mBackupTarget.backupMode);
6602            } catch (Exception e) {
6603                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6604                badApp = true;
6605            }
6606        }
6607
6608        if (badApp) {
6609            app.kill("error during init", true);
6610            handleAppDiedLocked(app, false, true);
6611            return false;
6612        }
6613
6614        if (!didSomething) {
6615            updateOomAdjLocked();
6616        }
6617
6618        return true;
6619    }
6620
6621    @Override
6622    public final void attachApplication(IApplicationThread thread) {
6623        synchronized (this) {
6624            int callingPid = Binder.getCallingPid();
6625            final long origId = Binder.clearCallingIdentity();
6626            attachApplicationLocked(thread, callingPid);
6627            Binder.restoreCallingIdentity(origId);
6628        }
6629    }
6630
6631    @Override
6632    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6633        final long origId = Binder.clearCallingIdentity();
6634        synchronized (this) {
6635            ActivityStack stack = ActivityRecord.getStackLocked(token);
6636            if (stack != null) {
6637                ActivityRecord r =
6638                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6639                if (stopProfiling) {
6640                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6641                        try {
6642                            mProfileFd.close();
6643                        } catch (IOException e) {
6644                        }
6645                        clearProfilerLocked();
6646                    }
6647                }
6648            }
6649        }
6650        Binder.restoreCallingIdentity(origId);
6651    }
6652
6653    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6654        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6655                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6656    }
6657
6658    void enableScreenAfterBoot() {
6659        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6660                SystemClock.uptimeMillis());
6661        mWindowManager.enableScreenAfterBoot();
6662
6663        synchronized (this) {
6664            updateEventDispatchingLocked();
6665        }
6666    }
6667
6668    @Override
6669    public void showBootMessage(final CharSequence msg, final boolean always) {
6670        if (Binder.getCallingUid() != Process.myUid()) {
6671            // These days only the core system can call this, so apps can't get in
6672            // the way of what we show about running them.
6673        }
6674        mWindowManager.showBootMessage(msg, always);
6675    }
6676
6677    @Override
6678    public void keyguardWaitingForActivityDrawn() {
6679        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6680        final long token = Binder.clearCallingIdentity();
6681        try {
6682            synchronized (this) {
6683                if (DEBUG_LOCKSCREEN) logLockScreen("");
6684                mWindowManager.keyguardWaitingForActivityDrawn();
6685                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6686                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6687                    updateSleepIfNeededLocked();
6688                }
6689            }
6690        } finally {
6691            Binder.restoreCallingIdentity(token);
6692        }
6693    }
6694
6695    @Override
6696    public void keyguardGoingAway(int flags) {
6697        enforceNotIsolatedCaller("keyguardGoingAway");
6698        final long token = Binder.clearCallingIdentity();
6699        try {
6700            synchronized (this) {
6701                if (DEBUG_LOCKSCREEN) logLockScreen("");
6702                mWindowManager.keyguardGoingAway(flags);
6703                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6704                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6705                    updateSleepIfNeededLocked();
6706
6707                    // Some stack visibility might change (e.g. docked stack)
6708                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6709                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6710                }
6711            }
6712        } finally {
6713            Binder.restoreCallingIdentity(token);
6714        }
6715    }
6716
6717    final void finishBooting() {
6718        synchronized (this) {
6719            if (!mBootAnimationComplete) {
6720                mCallFinishBooting = true;
6721                return;
6722            }
6723            mCallFinishBooting = false;
6724        }
6725
6726        ArraySet<String> completedIsas = new ArraySet<String>();
6727        for (String abi : Build.SUPPORTED_ABIS) {
6728            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6729            final String instructionSet = VMRuntime.getInstructionSet(abi);
6730            if (!completedIsas.contains(instructionSet)) {
6731                try {
6732                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6733                } catch (InstallerException e) {
6734                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6735                            e.getMessage() +")");
6736                }
6737                completedIsas.add(instructionSet);
6738            }
6739        }
6740
6741        IntentFilter pkgFilter = new IntentFilter();
6742        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6743        pkgFilter.addDataScheme("package");
6744        mContext.registerReceiver(new BroadcastReceiver() {
6745            @Override
6746            public void onReceive(Context context, Intent intent) {
6747                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6748                if (pkgs != null) {
6749                    for (String pkg : pkgs) {
6750                        synchronized (ActivityManagerService.this) {
6751                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6752                                    0, "query restart")) {
6753                                setResultCode(Activity.RESULT_OK);
6754                                return;
6755                            }
6756                        }
6757                    }
6758                }
6759            }
6760        }, pkgFilter);
6761
6762        IntentFilter dumpheapFilter = new IntentFilter();
6763        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6764        mContext.registerReceiver(new BroadcastReceiver() {
6765            @Override
6766            public void onReceive(Context context, Intent intent) {
6767                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6768                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6769                } else {
6770                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6771                }
6772            }
6773        }, dumpheapFilter);
6774
6775        // Let system services know.
6776        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6777
6778        synchronized (this) {
6779            // Ensure that any processes we had put on hold are now started
6780            // up.
6781            final int NP = mProcessesOnHold.size();
6782            if (NP > 0) {
6783                ArrayList<ProcessRecord> procs =
6784                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6785                for (int ip=0; ip<NP; ip++) {
6786                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6787                            + procs.get(ip));
6788                    startProcessLocked(procs.get(ip), "on-hold", null);
6789                }
6790            }
6791
6792            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6793                // Start looking for apps that are abusing wake locks.
6794                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6795                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6796                // Tell anyone interested that we are done booting!
6797                SystemProperties.set("sys.boot_completed", "1");
6798
6799                // And trigger dev.bootcomplete if we are not showing encryption progress
6800                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6801                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6802                    SystemProperties.set("dev.bootcomplete", "1");
6803                }
6804                mUserController.sendBootCompletedLocked(
6805                        new IIntentReceiver.Stub() {
6806                            @Override
6807                            public void performReceive(Intent intent, int resultCode,
6808                                    String data, Bundle extras, boolean ordered,
6809                                    boolean sticky, int sendingUser) {
6810                                synchronized (ActivityManagerService.this) {
6811                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6812                                            true, false);
6813                                }
6814                            }
6815                        });
6816                scheduleStartProfilesLocked();
6817            }
6818        }
6819    }
6820
6821    @Override
6822    public void bootAnimationComplete() {
6823        final boolean callFinishBooting;
6824        synchronized (this) {
6825            callFinishBooting = mCallFinishBooting;
6826            mBootAnimationComplete = true;
6827        }
6828        if (callFinishBooting) {
6829            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6830            finishBooting();
6831            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6832        }
6833    }
6834
6835    final void ensureBootCompleted() {
6836        boolean booting;
6837        boolean enableScreen;
6838        synchronized (this) {
6839            booting = mBooting;
6840            mBooting = false;
6841            enableScreen = !mBooted;
6842            mBooted = true;
6843        }
6844
6845        if (booting) {
6846            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6847            finishBooting();
6848            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6849        }
6850
6851        if (enableScreen) {
6852            enableScreenAfterBoot();
6853        }
6854    }
6855
6856    @Override
6857    public final void activityResumed(IBinder token) {
6858        final long origId = Binder.clearCallingIdentity();
6859        synchronized(this) {
6860            ActivityStack stack = ActivityRecord.getStackLocked(token);
6861            if (stack != null) {
6862                stack.activityResumedLocked(token);
6863            }
6864        }
6865        Binder.restoreCallingIdentity(origId);
6866    }
6867
6868    @Override
6869    public final void activityPaused(IBinder token) {
6870        final long origId = Binder.clearCallingIdentity();
6871        synchronized(this) {
6872            ActivityStack stack = ActivityRecord.getStackLocked(token);
6873            if (stack != null) {
6874                stack.activityPausedLocked(token, false);
6875            }
6876        }
6877        Binder.restoreCallingIdentity(origId);
6878    }
6879
6880    @Override
6881    public final void activityStopped(IBinder token, Bundle icicle,
6882            PersistableBundle persistentState, CharSequence description) {
6883        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6884
6885        // Refuse possible leaked file descriptors
6886        if (icicle != null && icicle.hasFileDescriptors()) {
6887            throw new IllegalArgumentException("File descriptors passed in Bundle");
6888        }
6889
6890        final long origId = Binder.clearCallingIdentity();
6891
6892        synchronized (this) {
6893            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6894            if (r != null) {
6895                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6896            }
6897        }
6898
6899        trimApplications();
6900
6901        Binder.restoreCallingIdentity(origId);
6902    }
6903
6904    @Override
6905    public final void activityDestroyed(IBinder token) {
6906        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6907        synchronized (this) {
6908            ActivityStack stack = ActivityRecord.getStackLocked(token);
6909            if (stack != null) {
6910                stack.activityDestroyedLocked(token, "activityDestroyed");
6911            }
6912        }
6913    }
6914
6915    @Override
6916    public final void activityRelaunched(IBinder token) {
6917        final long origId = Binder.clearCallingIdentity();
6918        synchronized (this) {
6919            mStackSupervisor.activityRelaunchedLocked(token);
6920        }
6921        Binder.restoreCallingIdentity(origId);
6922    }
6923
6924    @Override
6925    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6926            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6927        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6928                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6929        synchronized (this) {
6930            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6931            if (record == null) {
6932                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6933                        + "found for: " + token);
6934            }
6935            record.setSizeConfigurations(horizontalSizeConfiguration,
6936                    verticalSizeConfigurations, smallestSizeConfigurations);
6937        }
6938    }
6939
6940    @Override
6941    public final void backgroundResourcesReleased(IBinder token) {
6942        final long origId = Binder.clearCallingIdentity();
6943        try {
6944            synchronized (this) {
6945                ActivityStack stack = ActivityRecord.getStackLocked(token);
6946                if (stack != null) {
6947                    stack.backgroundResourcesReleased();
6948                }
6949            }
6950        } finally {
6951            Binder.restoreCallingIdentity(origId);
6952        }
6953    }
6954
6955    @Override
6956    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6957        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6958    }
6959
6960    @Override
6961    public final void notifyEnterAnimationComplete(IBinder token) {
6962        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6963    }
6964
6965    @Override
6966    public String getCallingPackage(IBinder token) {
6967        synchronized (this) {
6968            ActivityRecord r = getCallingRecordLocked(token);
6969            return r != null ? r.info.packageName : null;
6970        }
6971    }
6972
6973    @Override
6974    public ComponentName getCallingActivity(IBinder token) {
6975        synchronized (this) {
6976            ActivityRecord r = getCallingRecordLocked(token);
6977            return r != null ? r.intent.getComponent() : null;
6978        }
6979    }
6980
6981    private ActivityRecord getCallingRecordLocked(IBinder token) {
6982        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6983        if (r == null) {
6984            return null;
6985        }
6986        return r.resultTo;
6987    }
6988
6989    @Override
6990    public ComponentName getActivityClassForToken(IBinder token) {
6991        synchronized(this) {
6992            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6993            if (r == null) {
6994                return null;
6995            }
6996            return r.intent.getComponent();
6997        }
6998    }
6999
7000    @Override
7001    public String getPackageForToken(IBinder token) {
7002        synchronized(this) {
7003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7004            if (r == null) {
7005                return null;
7006            }
7007            return r.packageName;
7008        }
7009    }
7010
7011    @Override
7012    public boolean isRootVoiceInteraction(IBinder token) {
7013        synchronized(this) {
7014            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7015            if (r == null) {
7016                return false;
7017            }
7018            return r.rootVoiceInteraction;
7019        }
7020    }
7021
7022    @Override
7023    public IIntentSender getIntentSender(int type,
7024            String packageName, IBinder token, String resultWho,
7025            int requestCode, Intent[] intents, String[] resolvedTypes,
7026            int flags, Bundle bOptions, int userId) {
7027        enforceNotIsolatedCaller("getIntentSender");
7028        // Refuse possible leaked file descriptors
7029        if (intents != null) {
7030            if (intents.length < 1) {
7031                throw new IllegalArgumentException("Intents array length must be >= 1");
7032            }
7033            for (int i=0; i<intents.length; i++) {
7034                Intent intent = intents[i];
7035                if (intent != null) {
7036                    if (intent.hasFileDescriptors()) {
7037                        throw new IllegalArgumentException("File descriptors passed in Intent");
7038                    }
7039                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7040                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7041                        throw new IllegalArgumentException(
7042                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7043                    }
7044                    intents[i] = new Intent(intent);
7045                }
7046            }
7047            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7048                throw new IllegalArgumentException(
7049                        "Intent array length does not match resolvedTypes length");
7050            }
7051        }
7052        if (bOptions != null) {
7053            if (bOptions.hasFileDescriptors()) {
7054                throw new IllegalArgumentException("File descriptors passed in options");
7055            }
7056        }
7057
7058        synchronized(this) {
7059            int callingUid = Binder.getCallingUid();
7060            int origUserId = userId;
7061            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7062                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7063                    ALLOW_NON_FULL, "getIntentSender", null);
7064            if (origUserId == UserHandle.USER_CURRENT) {
7065                // We don't want to evaluate this until the pending intent is
7066                // actually executed.  However, we do want to always do the
7067                // security checking for it above.
7068                userId = UserHandle.USER_CURRENT;
7069            }
7070            try {
7071                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7072                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7073                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7074                    if (!UserHandle.isSameApp(callingUid, uid)) {
7075                        String msg = "Permission Denial: getIntentSender() from pid="
7076                            + Binder.getCallingPid()
7077                            + ", uid=" + Binder.getCallingUid()
7078                            + ", (need uid=" + uid + ")"
7079                            + " is not allowed to send as package " + packageName;
7080                        Slog.w(TAG, msg);
7081                        throw new SecurityException(msg);
7082                    }
7083                }
7084
7085                return getIntentSenderLocked(type, packageName, callingUid, userId,
7086                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7087
7088            } catch (RemoteException e) {
7089                throw new SecurityException(e);
7090            }
7091        }
7092    }
7093
7094    IIntentSender getIntentSenderLocked(int type, String packageName,
7095            int callingUid, int userId, IBinder token, String resultWho,
7096            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7097            Bundle bOptions) {
7098        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7099        ActivityRecord activity = null;
7100        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7101            activity = ActivityRecord.isInStackLocked(token);
7102            if (activity == null) {
7103                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7104                return null;
7105            }
7106            if (activity.finishing) {
7107                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7108                return null;
7109            }
7110        }
7111
7112        // We're going to be splicing together extras before sending, so we're
7113        // okay poking into any contained extras.
7114        if (intents != null) {
7115            for (int i = 0; i < intents.length; i++) {
7116                intents[i].setDefusable(true);
7117            }
7118        }
7119        Bundle.setDefusable(bOptions, true);
7120
7121        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7122        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7123        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7124        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7125                |PendingIntent.FLAG_UPDATE_CURRENT);
7126
7127        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7128                type, packageName, activity, resultWho,
7129                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7130        WeakReference<PendingIntentRecord> ref;
7131        ref = mIntentSenderRecords.get(key);
7132        PendingIntentRecord rec = ref != null ? ref.get() : null;
7133        if (rec != null) {
7134            if (!cancelCurrent) {
7135                if (updateCurrent) {
7136                    if (rec.key.requestIntent != null) {
7137                        rec.key.requestIntent.replaceExtras(intents != null ?
7138                                intents[intents.length - 1] : null);
7139                    }
7140                    if (intents != null) {
7141                        intents[intents.length-1] = rec.key.requestIntent;
7142                        rec.key.allIntents = intents;
7143                        rec.key.allResolvedTypes = resolvedTypes;
7144                    } else {
7145                        rec.key.allIntents = null;
7146                        rec.key.allResolvedTypes = null;
7147                    }
7148                }
7149                return rec;
7150            }
7151            rec.canceled = true;
7152            mIntentSenderRecords.remove(key);
7153        }
7154        if (noCreate) {
7155            return rec;
7156        }
7157        rec = new PendingIntentRecord(this, key, callingUid);
7158        mIntentSenderRecords.put(key, rec.ref);
7159        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7160            if (activity.pendingResults == null) {
7161                activity.pendingResults
7162                        = new HashSet<WeakReference<PendingIntentRecord>>();
7163            }
7164            activity.pendingResults.add(rec.ref);
7165        }
7166        return rec;
7167    }
7168
7169    @Override
7170    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7171            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7172        if (target instanceof PendingIntentRecord) {
7173            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7174                    finishedReceiver, requiredPermission, options);
7175        } else {
7176            if (intent == null) {
7177                // Weird case: someone has given us their own custom IIntentSender, and now
7178                // they have someone else trying to send to it but of course this isn't
7179                // really a PendingIntent, so there is no base Intent, and the caller isn't
7180                // supplying an Intent... but we never want to dispatch a null Intent to
7181                // a receiver, so um...  let's make something up.
7182                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7183                intent = new Intent(Intent.ACTION_MAIN);
7184            }
7185            try {
7186                target.send(code, intent, resolvedType, null, requiredPermission, options);
7187            } catch (RemoteException e) {
7188            }
7189            // Platform code can rely on getting a result back when the send is done, but if
7190            // this intent sender is from outside of the system we can't rely on it doing that.
7191            // So instead we don't give it the result receiver, and instead just directly
7192            // report the finish immediately.
7193            if (finishedReceiver != null) {
7194                try {
7195                    finishedReceiver.performReceive(intent, 0,
7196                            null, null, false, false, UserHandle.getCallingUserId());
7197                } catch (RemoteException e) {
7198                }
7199            }
7200            return 0;
7201        }
7202    }
7203
7204    /**
7205     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7206     *
7207     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7208     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7209     */
7210    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7211        if (DEBUG_WHITELISTS) {
7212            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7213                    + targetUid + ", " + duration + ")");
7214        }
7215        synchronized (mPidsSelfLocked) {
7216            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7217            if (pr == null) {
7218                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7219                return;
7220            }
7221            if (!pr.whitelistManager) {
7222                if (DEBUG_WHITELISTS) {
7223                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7224                            + callerPid + " is not allowed");
7225                }
7226                return;
7227            }
7228        }
7229
7230        final long token = Binder.clearCallingIdentity();
7231        try {
7232            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7233                    true, "pe from uid:" + callerUid);
7234        } finally {
7235            Binder.restoreCallingIdentity(token);
7236        }
7237    }
7238
7239    @Override
7240    public void cancelIntentSender(IIntentSender sender) {
7241        if (!(sender instanceof PendingIntentRecord)) {
7242            return;
7243        }
7244        synchronized(this) {
7245            PendingIntentRecord rec = (PendingIntentRecord)sender;
7246            try {
7247                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7248                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7249                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7250                    String msg = "Permission Denial: cancelIntentSender() from pid="
7251                        + Binder.getCallingPid()
7252                        + ", uid=" + Binder.getCallingUid()
7253                        + " is not allowed to cancel packges "
7254                        + rec.key.packageName;
7255                    Slog.w(TAG, msg);
7256                    throw new SecurityException(msg);
7257                }
7258            } catch (RemoteException e) {
7259                throw new SecurityException(e);
7260            }
7261            cancelIntentSenderLocked(rec, true);
7262        }
7263    }
7264
7265    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7266        rec.canceled = true;
7267        mIntentSenderRecords.remove(rec.key);
7268        if (cleanActivity && rec.key.activity != null) {
7269            rec.key.activity.pendingResults.remove(rec.ref);
7270        }
7271    }
7272
7273    @Override
7274    public String getPackageForIntentSender(IIntentSender pendingResult) {
7275        if (!(pendingResult instanceof PendingIntentRecord)) {
7276            return null;
7277        }
7278        try {
7279            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7280            return res.key.packageName;
7281        } catch (ClassCastException e) {
7282        }
7283        return null;
7284    }
7285
7286    @Override
7287    public int getUidForIntentSender(IIntentSender sender) {
7288        if (sender instanceof PendingIntentRecord) {
7289            try {
7290                PendingIntentRecord res = (PendingIntentRecord)sender;
7291                return res.uid;
7292            } catch (ClassCastException e) {
7293            }
7294        }
7295        return -1;
7296    }
7297
7298    @Override
7299    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7300        if (!(pendingResult instanceof PendingIntentRecord)) {
7301            return false;
7302        }
7303        try {
7304            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7305            if (res.key.allIntents == null) {
7306                return false;
7307            }
7308            for (int i=0; i<res.key.allIntents.length; i++) {
7309                Intent intent = res.key.allIntents[i];
7310                if (intent.getPackage() != null && intent.getComponent() != null) {
7311                    return false;
7312                }
7313            }
7314            return true;
7315        } catch (ClassCastException e) {
7316        }
7317        return false;
7318    }
7319
7320    @Override
7321    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7322        if (!(pendingResult instanceof PendingIntentRecord)) {
7323            return false;
7324        }
7325        try {
7326            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7327            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7328                return true;
7329            }
7330            return false;
7331        } catch (ClassCastException e) {
7332        }
7333        return false;
7334    }
7335
7336    @Override
7337    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7338        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7339                "getIntentForIntentSender()");
7340        if (!(pendingResult instanceof PendingIntentRecord)) {
7341            return null;
7342        }
7343        try {
7344            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7345            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7346        } catch (ClassCastException e) {
7347        }
7348        return null;
7349    }
7350
7351    @Override
7352    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7353        if (!(pendingResult instanceof PendingIntentRecord)) {
7354            return null;
7355        }
7356        try {
7357            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7358            synchronized (this) {
7359                return getTagForIntentSenderLocked(res, prefix);
7360            }
7361        } catch (ClassCastException e) {
7362        }
7363        return null;
7364    }
7365
7366    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7367        final Intent intent = res.key.requestIntent;
7368        if (intent != null) {
7369            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7370                    || res.lastTagPrefix.equals(prefix))) {
7371                return res.lastTag;
7372            }
7373            res.lastTagPrefix = prefix;
7374            final StringBuilder sb = new StringBuilder(128);
7375            if (prefix != null) {
7376                sb.append(prefix);
7377            }
7378            if (intent.getAction() != null) {
7379                sb.append(intent.getAction());
7380            } else if (intent.getComponent() != null) {
7381                intent.getComponent().appendShortString(sb);
7382            } else {
7383                sb.append("?");
7384            }
7385            return res.lastTag = sb.toString();
7386        }
7387        return null;
7388    }
7389
7390    @Override
7391    public void setProcessLimit(int max) {
7392        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7393                "setProcessLimit()");
7394        synchronized (this) {
7395            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7396            mProcessLimitOverride = max;
7397        }
7398        trimApplications();
7399    }
7400
7401    @Override
7402    public int getProcessLimit() {
7403        synchronized (this) {
7404            return mProcessLimitOverride;
7405        }
7406    }
7407
7408    void foregroundTokenDied(ForegroundToken token) {
7409        synchronized (ActivityManagerService.this) {
7410            synchronized (mPidsSelfLocked) {
7411                ForegroundToken cur
7412                    = mForegroundProcesses.get(token.pid);
7413                if (cur != token) {
7414                    return;
7415                }
7416                mForegroundProcesses.remove(token.pid);
7417                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7418                if (pr == null) {
7419                    return;
7420                }
7421                pr.forcingToForeground = null;
7422                updateProcessForegroundLocked(pr, false, false);
7423            }
7424            updateOomAdjLocked();
7425        }
7426    }
7427
7428    @Override
7429    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7430        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7431                "setProcessForeground()");
7432        synchronized(this) {
7433            boolean changed = false;
7434
7435            synchronized (mPidsSelfLocked) {
7436                ProcessRecord pr = mPidsSelfLocked.get(pid);
7437                if (pr == null && isForeground) {
7438                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7439                    return;
7440                }
7441                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7442                if (oldToken != null) {
7443                    oldToken.token.unlinkToDeath(oldToken, 0);
7444                    mForegroundProcesses.remove(pid);
7445                    if (pr != null) {
7446                        pr.forcingToForeground = null;
7447                    }
7448                    changed = true;
7449                }
7450                if (isForeground && token != null) {
7451                    ForegroundToken newToken = new ForegroundToken() {
7452                        @Override
7453                        public void binderDied() {
7454                            foregroundTokenDied(this);
7455                        }
7456                    };
7457                    newToken.pid = pid;
7458                    newToken.token = token;
7459                    try {
7460                        token.linkToDeath(newToken, 0);
7461                        mForegroundProcesses.put(pid, newToken);
7462                        pr.forcingToForeground = token;
7463                        changed = true;
7464                    } catch (RemoteException e) {
7465                        // If the process died while doing this, we will later
7466                        // do the cleanup with the process death link.
7467                    }
7468                }
7469            }
7470
7471            if (changed) {
7472                updateOomAdjLocked();
7473            }
7474        }
7475    }
7476
7477    @Override
7478    public boolean isAppForeground(int uid) throws RemoteException {
7479        synchronized (this) {
7480            UidRecord uidRec = mActiveUids.get(uid);
7481            if (uidRec == null || uidRec.idle) {
7482                return false;
7483            }
7484            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7485        }
7486    }
7487
7488    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7489    // be guarded by permission checking.
7490    int getUidState(int uid) {
7491        synchronized (this) {
7492            UidRecord uidRec = mActiveUids.get(uid);
7493            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7494        }
7495    }
7496
7497    @Override
7498    public boolean isInMultiWindowMode(IBinder token) {
7499        final long origId = Binder.clearCallingIdentity();
7500        try {
7501            synchronized(this) {
7502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7503                if (r == null) {
7504                    return false;
7505                }
7506                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7507                return !r.task.mFullscreen;
7508            }
7509        } finally {
7510            Binder.restoreCallingIdentity(origId);
7511        }
7512    }
7513
7514    @Override
7515    public boolean isInPictureInPictureMode(IBinder token) {
7516        final long origId = Binder.clearCallingIdentity();
7517        try {
7518            synchronized(this) {
7519                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7520                if (stack == null) {
7521                    return false;
7522                }
7523                return stack.mStackId == PINNED_STACK_ID;
7524            }
7525        } finally {
7526            Binder.restoreCallingIdentity(origId);
7527        }
7528    }
7529
7530    @Override
7531    public void enterPictureInPictureMode(IBinder token) {
7532        final long origId = Binder.clearCallingIdentity();
7533        try {
7534            synchronized(this) {
7535                if (!mSupportsPictureInPicture) {
7536                    throw new IllegalStateException("enterPictureInPictureMode: "
7537                            + "Device doesn't support picture-in-picture mode.");
7538                }
7539
7540                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7541
7542                if (r == null) {
7543                    throw new IllegalStateException("enterPictureInPictureMode: "
7544                            + "Can't find activity for token=" + token);
7545                }
7546
7547                if (!r.supportsPictureInPicture()) {
7548                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7549                            + "Picture-In-Picture not supported for r=" + r);
7550                }
7551
7552                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7553                // current bounds.
7554                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7555                final Rect bounds = (pinnedStack != null)
7556                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7557
7558                mStackSupervisor.moveActivityToPinnedStackLocked(
7559                        r, "enterPictureInPictureMode", bounds);
7560            }
7561        } finally {
7562            Binder.restoreCallingIdentity(origId);
7563        }
7564    }
7565
7566    // =========================================================
7567    // PROCESS INFO
7568    // =========================================================
7569
7570    static class ProcessInfoService extends IProcessInfoService.Stub {
7571        final ActivityManagerService mActivityManagerService;
7572        ProcessInfoService(ActivityManagerService activityManagerService) {
7573            mActivityManagerService = activityManagerService;
7574        }
7575
7576        @Override
7577        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7578            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7579                    /*in*/ pids, /*out*/ states, null);
7580        }
7581
7582        @Override
7583        public void getProcessStatesAndOomScoresFromPids(
7584                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7585            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7586                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7587        }
7588    }
7589
7590    /**
7591     * For each PID in the given input array, write the current process state
7592     * for that process into the states array, or -1 to indicate that no
7593     * process with the given PID exists. If scores array is provided, write
7594     * the oom score for the process into the scores array, with INVALID_ADJ
7595     * indicating the PID doesn't exist.
7596     */
7597    public void getProcessStatesAndOomScoresForPIDs(
7598            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7599        if (scores != null) {
7600            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7601                    "getProcessStatesAndOomScoresForPIDs()");
7602        }
7603
7604        if (pids == null) {
7605            throw new NullPointerException("pids");
7606        } else if (states == null) {
7607            throw new NullPointerException("states");
7608        } else if (pids.length != states.length) {
7609            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7610        } else if (scores != null && pids.length != scores.length) {
7611            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7612        }
7613
7614        synchronized (mPidsSelfLocked) {
7615            for (int i = 0; i < pids.length; i++) {
7616                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7617                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7618                        pr.curProcState;
7619                if (scores != null) {
7620                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7621                }
7622            }
7623        }
7624    }
7625
7626    // =========================================================
7627    // PERMISSIONS
7628    // =========================================================
7629
7630    static class PermissionController extends IPermissionController.Stub {
7631        ActivityManagerService mActivityManagerService;
7632        PermissionController(ActivityManagerService activityManagerService) {
7633            mActivityManagerService = activityManagerService;
7634        }
7635
7636        @Override
7637        public boolean checkPermission(String permission, int pid, int uid) {
7638            return mActivityManagerService.checkPermission(permission, pid,
7639                    uid) == PackageManager.PERMISSION_GRANTED;
7640        }
7641
7642        @Override
7643        public String[] getPackagesForUid(int uid) {
7644            return mActivityManagerService.mContext.getPackageManager()
7645                    .getPackagesForUid(uid);
7646        }
7647
7648        @Override
7649        public boolean isRuntimePermission(String permission) {
7650            try {
7651                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7652                        .getPermissionInfo(permission, 0);
7653                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7654            } catch (NameNotFoundException nnfe) {
7655                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7656            }
7657            return false;
7658        }
7659    }
7660
7661    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7662        @Override
7663        public int checkComponentPermission(String permission, int pid, int uid,
7664                int owningUid, boolean exported) {
7665            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7666                    owningUid, exported);
7667        }
7668
7669        @Override
7670        public Object getAMSLock() {
7671            return ActivityManagerService.this;
7672        }
7673    }
7674
7675    /**
7676     * This can be called with or without the global lock held.
7677     */
7678    int checkComponentPermission(String permission, int pid, int uid,
7679            int owningUid, boolean exported) {
7680        if (pid == MY_PID) {
7681            return PackageManager.PERMISSION_GRANTED;
7682        }
7683        return ActivityManager.checkComponentPermission(permission, uid,
7684                owningUid, exported);
7685    }
7686
7687    /**
7688     * As the only public entry point for permissions checking, this method
7689     * can enforce the semantic that requesting a check on a null global
7690     * permission is automatically denied.  (Internally a null permission
7691     * string is used when calling {@link #checkComponentPermission} in cases
7692     * when only uid-based security is needed.)
7693     *
7694     * This can be called with or without the global lock held.
7695     */
7696    @Override
7697    public int checkPermission(String permission, int pid, int uid) {
7698        if (permission == null) {
7699            return PackageManager.PERMISSION_DENIED;
7700        }
7701        return checkComponentPermission(permission, pid, uid, -1, true);
7702    }
7703
7704    @Override
7705    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7706        if (permission == null) {
7707            return PackageManager.PERMISSION_DENIED;
7708        }
7709
7710        // We might be performing an operation on behalf of an indirect binder
7711        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7712        // client identity accordingly before proceeding.
7713        Identity tlsIdentity = sCallerIdentity.get();
7714        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7715            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7716                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7717            uid = tlsIdentity.uid;
7718            pid = tlsIdentity.pid;
7719        }
7720
7721        return checkComponentPermission(permission, pid, uid, -1, true);
7722    }
7723
7724    /**
7725     * Binder IPC calls go through the public entry point.
7726     * This can be called with or without the global lock held.
7727     */
7728    int checkCallingPermission(String permission) {
7729        return checkPermission(permission,
7730                Binder.getCallingPid(),
7731                UserHandle.getAppId(Binder.getCallingUid()));
7732    }
7733
7734    /**
7735     * This can be called with or without the global lock held.
7736     */
7737    void enforceCallingPermission(String permission, String func) {
7738        if (checkCallingPermission(permission)
7739                == PackageManager.PERMISSION_GRANTED) {
7740            return;
7741        }
7742
7743        String msg = "Permission Denial: " + func + " from pid="
7744                + Binder.getCallingPid()
7745                + ", uid=" + Binder.getCallingUid()
7746                + " requires " + permission;
7747        Slog.w(TAG, msg);
7748        throw new SecurityException(msg);
7749    }
7750
7751    /**
7752     * Determine if UID is holding permissions required to access {@link Uri} in
7753     * the given {@link ProviderInfo}. Final permission checking is always done
7754     * in {@link ContentProvider}.
7755     */
7756    private final boolean checkHoldingPermissionsLocked(
7757            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7758        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7759                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7760        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7761            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7762                    != PERMISSION_GRANTED) {
7763                return false;
7764            }
7765        }
7766        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7767    }
7768
7769    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7770            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7771        if (pi.applicationInfo.uid == uid) {
7772            return true;
7773        } else if (!pi.exported) {
7774            return false;
7775        }
7776
7777        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7778        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7779        try {
7780            // check if target holds top-level <provider> permissions
7781            if (!readMet && pi.readPermission != null && considerUidPermissions
7782                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7783                readMet = true;
7784            }
7785            if (!writeMet && pi.writePermission != null && considerUidPermissions
7786                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7787                writeMet = true;
7788            }
7789
7790            // track if unprotected read/write is allowed; any denied
7791            // <path-permission> below removes this ability
7792            boolean allowDefaultRead = pi.readPermission == null;
7793            boolean allowDefaultWrite = pi.writePermission == null;
7794
7795            // check if target holds any <path-permission> that match uri
7796            final PathPermission[] pps = pi.pathPermissions;
7797            if (pps != null) {
7798                final String path = grantUri.uri.getPath();
7799                int i = pps.length;
7800                while (i > 0 && (!readMet || !writeMet)) {
7801                    i--;
7802                    PathPermission pp = pps[i];
7803                    if (pp.match(path)) {
7804                        if (!readMet) {
7805                            final String pprperm = pp.getReadPermission();
7806                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7807                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7808                                    + ": match=" + pp.match(path)
7809                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7810                            if (pprperm != null) {
7811                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7812                                        == PERMISSION_GRANTED) {
7813                                    readMet = true;
7814                                } else {
7815                                    allowDefaultRead = false;
7816                                }
7817                            }
7818                        }
7819                        if (!writeMet) {
7820                            final String ppwperm = pp.getWritePermission();
7821                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7822                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7823                                    + ": match=" + pp.match(path)
7824                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7825                            if (ppwperm != null) {
7826                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7827                                        == PERMISSION_GRANTED) {
7828                                    writeMet = true;
7829                                } else {
7830                                    allowDefaultWrite = false;
7831                                }
7832                            }
7833                        }
7834                    }
7835                }
7836            }
7837
7838            // grant unprotected <provider> read/write, if not blocked by
7839            // <path-permission> above
7840            if (allowDefaultRead) readMet = true;
7841            if (allowDefaultWrite) writeMet = true;
7842
7843        } catch (RemoteException e) {
7844            return false;
7845        }
7846
7847        return readMet && writeMet;
7848    }
7849
7850    public int getAppStartMode(int uid, String packageName) {
7851        synchronized (this) {
7852            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7853        }
7854    }
7855
7856    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7857            boolean allowWhenForeground) {
7858        UidRecord uidRec = mActiveUids.get(uid);
7859        if (!mLenientBackgroundCheck) {
7860            if (!allowWhenForeground || uidRec == null
7861                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7862                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7863                        packageName) != AppOpsManager.MODE_ALLOWED) {
7864                    return ActivityManager.APP_START_MODE_DELAYED;
7865                }
7866            }
7867
7868        } else if (uidRec == null || uidRec.idle) {
7869            if (callingPid >= 0) {
7870                ProcessRecord proc;
7871                synchronized (mPidsSelfLocked) {
7872                    proc = mPidsSelfLocked.get(callingPid);
7873                }
7874                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7875                    // Whoever is instigating this is in the foreground, so we will allow it
7876                    // to go through.
7877                    return ActivityManager.APP_START_MODE_NORMAL;
7878                }
7879            }
7880            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7881                    != AppOpsManager.MODE_ALLOWED) {
7882                return ActivityManager.APP_START_MODE_DELAYED;
7883            }
7884        }
7885        return ActivityManager.APP_START_MODE_NORMAL;
7886    }
7887
7888    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7889        ProviderInfo pi = null;
7890        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7891        if (cpr != null) {
7892            pi = cpr.info;
7893        } else {
7894            try {
7895                pi = AppGlobals.getPackageManager().resolveContentProvider(
7896                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7897                        userHandle);
7898            } catch (RemoteException ex) {
7899            }
7900        }
7901        return pi;
7902    }
7903
7904    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7905        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7906        if (targetUris != null) {
7907            return targetUris.get(grantUri);
7908        }
7909        return null;
7910    }
7911
7912    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7913            String targetPkg, int targetUid, GrantUri grantUri) {
7914        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7915        if (targetUris == null) {
7916            targetUris = Maps.newArrayMap();
7917            mGrantedUriPermissions.put(targetUid, targetUris);
7918        }
7919
7920        UriPermission perm = targetUris.get(grantUri);
7921        if (perm == null) {
7922            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7923            targetUris.put(grantUri, perm);
7924        }
7925
7926        return perm;
7927    }
7928
7929    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7930            final int modeFlags) {
7931        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7932        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7933                : UriPermission.STRENGTH_OWNED;
7934
7935        // Root gets to do everything.
7936        if (uid == 0) {
7937            return true;
7938        }
7939
7940        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7941        if (perms == null) return false;
7942
7943        // First look for exact match
7944        final UriPermission exactPerm = perms.get(grantUri);
7945        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7946            return true;
7947        }
7948
7949        // No exact match, look for prefixes
7950        final int N = perms.size();
7951        for (int i = 0; i < N; i++) {
7952            final UriPermission perm = perms.valueAt(i);
7953            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7954                    && perm.getStrength(modeFlags) >= minStrength) {
7955                return true;
7956            }
7957        }
7958
7959        return false;
7960    }
7961
7962    /**
7963     * @param uri This uri must NOT contain an embedded userId.
7964     * @param userId The userId in which the uri is to be resolved.
7965     */
7966    @Override
7967    public int checkUriPermission(Uri uri, int pid, int uid,
7968            final int modeFlags, int userId, IBinder callerToken) {
7969        enforceNotIsolatedCaller("checkUriPermission");
7970
7971        // Another redirected-binder-call permissions check as in
7972        // {@link checkPermissionWithToken}.
7973        Identity tlsIdentity = sCallerIdentity.get();
7974        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7975            uid = tlsIdentity.uid;
7976            pid = tlsIdentity.pid;
7977        }
7978
7979        // Our own process gets to do everything.
7980        if (pid == MY_PID) {
7981            return PackageManager.PERMISSION_GRANTED;
7982        }
7983        synchronized (this) {
7984            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7985                    ? PackageManager.PERMISSION_GRANTED
7986                    : PackageManager.PERMISSION_DENIED;
7987        }
7988    }
7989
7990    /**
7991     * Check if the targetPkg can be granted permission to access uri by
7992     * the callingUid using the given modeFlags.  Throws a security exception
7993     * if callingUid is not allowed to do this.  Returns the uid of the target
7994     * if the URI permission grant should be performed; returns -1 if it is not
7995     * needed (for example targetPkg already has permission to access the URI).
7996     * If you already know the uid of the target, you can supply it in
7997     * lastTargetUid else set that to -1.
7998     */
7999    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8000            final int modeFlags, int lastTargetUid) {
8001        if (!Intent.isAccessUriMode(modeFlags)) {
8002            return -1;
8003        }
8004
8005        if (targetPkg != null) {
8006            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8007                    "Checking grant " + targetPkg + " permission to " + grantUri);
8008        }
8009
8010        final IPackageManager pm = AppGlobals.getPackageManager();
8011
8012        // If this is not a content: uri, we can't do anything with it.
8013        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8014            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015                    "Can't grant URI permission for non-content URI: " + grantUri);
8016            return -1;
8017        }
8018
8019        final String authority = grantUri.uri.getAuthority();
8020        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8021                MATCH_DEBUG_TRIAGED_MISSING);
8022        if (pi == null) {
8023            Slog.w(TAG, "No content provider found for permission check: " +
8024                    grantUri.uri.toSafeString());
8025            return -1;
8026        }
8027
8028        int targetUid = lastTargetUid;
8029        if (targetUid < 0 && targetPkg != null) {
8030            try {
8031                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8032                        UserHandle.getUserId(callingUid));
8033                if (targetUid < 0) {
8034                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8035                            "Can't grant URI permission no uid for: " + targetPkg);
8036                    return -1;
8037                }
8038            } catch (RemoteException ex) {
8039                return -1;
8040            }
8041        }
8042
8043        if (targetUid >= 0) {
8044            // First...  does the target actually need this permission?
8045            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8046                // No need to grant the target this permission.
8047                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8048                        "Target " + targetPkg + " already has full permission to " + grantUri);
8049                return -1;
8050            }
8051        } else {
8052            // First...  there is no target package, so can anyone access it?
8053            boolean allowed = pi.exported;
8054            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8055                if (pi.readPermission != null) {
8056                    allowed = false;
8057                }
8058            }
8059            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8060                if (pi.writePermission != null) {
8061                    allowed = false;
8062                }
8063            }
8064            if (allowed) {
8065                return -1;
8066            }
8067        }
8068
8069        /* There is a special cross user grant if:
8070         * - The target is on another user.
8071         * - Apps on the current user can access the uri without any uid permissions.
8072         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8073         * grant uri permissions.
8074         */
8075        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8076                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8077                modeFlags, false /*without considering the uid permissions*/);
8078
8079        // Second...  is the provider allowing granting of URI permissions?
8080        if (!specialCrossUserGrant) {
8081            if (!pi.grantUriPermissions) {
8082                throw new SecurityException("Provider " + pi.packageName
8083                        + "/" + pi.name
8084                        + " does not allow granting of Uri permissions (uri "
8085                        + grantUri + ")");
8086            }
8087            if (pi.uriPermissionPatterns != null) {
8088                final int N = pi.uriPermissionPatterns.length;
8089                boolean allowed = false;
8090                for (int i=0; i<N; i++) {
8091                    if (pi.uriPermissionPatterns[i] != null
8092                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8093                        allowed = true;
8094                        break;
8095                    }
8096                }
8097                if (!allowed) {
8098                    throw new SecurityException("Provider " + pi.packageName
8099                            + "/" + pi.name
8100                            + " does not allow granting of permission to path of Uri "
8101                            + grantUri);
8102                }
8103            }
8104        }
8105
8106        // Third...  does the caller itself have permission to access
8107        // this uri?
8108        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8109            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8110                // Require they hold a strong enough Uri permission
8111                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8112                    throw new SecurityException("Uid " + callingUid
8113                            + " does not have permission to uri " + grantUri);
8114                }
8115            }
8116        }
8117        return targetUid;
8118    }
8119
8120    /**
8121     * @param uri This uri must NOT contain an embedded userId.
8122     * @param userId The userId in which the uri is to be resolved.
8123     */
8124    @Override
8125    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8126            final int modeFlags, int userId) {
8127        enforceNotIsolatedCaller("checkGrantUriPermission");
8128        synchronized(this) {
8129            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8130                    new GrantUri(userId, uri, false), modeFlags, -1);
8131        }
8132    }
8133
8134    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8135            final int modeFlags, UriPermissionOwner owner) {
8136        if (!Intent.isAccessUriMode(modeFlags)) {
8137            return;
8138        }
8139
8140        // So here we are: the caller has the assumed permission
8141        // to the uri, and the target doesn't.  Let's now give this to
8142        // the target.
8143
8144        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8145                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8146
8147        final String authority = grantUri.uri.getAuthority();
8148        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8149                MATCH_DEBUG_TRIAGED_MISSING);
8150        if (pi == null) {
8151            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8152            return;
8153        }
8154
8155        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8156            grantUri.prefix = true;
8157        }
8158        final UriPermission perm = findOrCreateUriPermissionLocked(
8159                pi.packageName, targetPkg, targetUid, grantUri);
8160        perm.grantModes(modeFlags, owner);
8161    }
8162
8163    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8164            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8165        if (targetPkg == null) {
8166            throw new NullPointerException("targetPkg");
8167        }
8168        int targetUid;
8169        final IPackageManager pm = AppGlobals.getPackageManager();
8170        try {
8171            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8172        } catch (RemoteException ex) {
8173            return;
8174        }
8175
8176        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8177                targetUid);
8178        if (targetUid < 0) {
8179            return;
8180        }
8181
8182        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8183                owner);
8184    }
8185
8186    static class NeededUriGrants extends ArrayList<GrantUri> {
8187        final String targetPkg;
8188        final int targetUid;
8189        final int flags;
8190
8191        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8192            this.targetPkg = targetPkg;
8193            this.targetUid = targetUid;
8194            this.flags = flags;
8195        }
8196    }
8197
8198    /**
8199     * Like checkGrantUriPermissionLocked, but takes an Intent.
8200     */
8201    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8202            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8203        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8204                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8205                + " clip=" + (intent != null ? intent.getClipData() : null)
8206                + " from " + intent + "; flags=0x"
8207                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8208
8209        if (targetPkg == null) {
8210            throw new NullPointerException("targetPkg");
8211        }
8212
8213        if (intent == null) {
8214            return null;
8215        }
8216        Uri data = intent.getData();
8217        ClipData clip = intent.getClipData();
8218        if (data == null && clip == null) {
8219            return null;
8220        }
8221        // Default userId for uris in the intent (if they don't specify it themselves)
8222        int contentUserHint = intent.getContentUserHint();
8223        if (contentUserHint == UserHandle.USER_CURRENT) {
8224            contentUserHint = UserHandle.getUserId(callingUid);
8225        }
8226        final IPackageManager pm = AppGlobals.getPackageManager();
8227        int targetUid;
8228        if (needed != null) {
8229            targetUid = needed.targetUid;
8230        } else {
8231            try {
8232                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8233                        targetUserId);
8234            } catch (RemoteException ex) {
8235                return null;
8236            }
8237            if (targetUid < 0) {
8238                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8239                        "Can't grant URI permission no uid for: " + targetPkg
8240                        + " on user " + targetUserId);
8241                return null;
8242            }
8243        }
8244        if (data != null) {
8245            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8246            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8247                    targetUid);
8248            if (targetUid > 0) {
8249                if (needed == null) {
8250                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8251                }
8252                needed.add(grantUri);
8253            }
8254        }
8255        if (clip != null) {
8256            for (int i=0; i<clip.getItemCount(); i++) {
8257                Uri uri = clip.getItemAt(i).getUri();
8258                if (uri != null) {
8259                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8260                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8261                            targetUid);
8262                    if (targetUid > 0) {
8263                        if (needed == null) {
8264                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8265                        }
8266                        needed.add(grantUri);
8267                    }
8268                } else {
8269                    Intent clipIntent = clip.getItemAt(i).getIntent();
8270                    if (clipIntent != null) {
8271                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8272                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8273                        if (newNeeded != null) {
8274                            needed = newNeeded;
8275                        }
8276                    }
8277                }
8278            }
8279        }
8280
8281        return needed;
8282    }
8283
8284    /**
8285     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8286     */
8287    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8288            UriPermissionOwner owner) {
8289        if (needed != null) {
8290            for (int i=0; i<needed.size(); i++) {
8291                GrantUri grantUri = needed.get(i);
8292                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8293                        grantUri, needed.flags, owner);
8294            }
8295        }
8296    }
8297
8298    void grantUriPermissionFromIntentLocked(int callingUid,
8299            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8300        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8301                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8302        if (needed == null) {
8303            return;
8304        }
8305
8306        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8307    }
8308
8309    /**
8310     * @param uri This uri must NOT contain an embedded userId.
8311     * @param userId The userId in which the uri is to be resolved.
8312     */
8313    @Override
8314    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8315            final int modeFlags, int userId) {
8316        enforceNotIsolatedCaller("grantUriPermission");
8317        GrantUri grantUri = new GrantUri(userId, uri, false);
8318        synchronized(this) {
8319            final ProcessRecord r = getRecordForAppLocked(caller);
8320            if (r == null) {
8321                throw new SecurityException("Unable to find app for caller "
8322                        + caller
8323                        + " when granting permission to uri " + grantUri);
8324            }
8325            if (targetPkg == null) {
8326                throw new IllegalArgumentException("null target");
8327            }
8328            if (grantUri == null) {
8329                throw new IllegalArgumentException("null uri");
8330            }
8331
8332            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8333                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8334                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8335                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8336
8337            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8338                    UserHandle.getUserId(r.uid));
8339        }
8340    }
8341
8342    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8343        if (perm.modeFlags == 0) {
8344            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8345                    perm.targetUid);
8346            if (perms != null) {
8347                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8349
8350                perms.remove(perm.uri);
8351                if (perms.isEmpty()) {
8352                    mGrantedUriPermissions.remove(perm.targetUid);
8353                }
8354            }
8355        }
8356    }
8357
8358    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8359        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8360                "Revoking all granted permissions to " + grantUri);
8361
8362        final IPackageManager pm = AppGlobals.getPackageManager();
8363        final String authority = grantUri.uri.getAuthority();
8364        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8365                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8366        if (pi == null) {
8367            Slog.w(TAG, "No content provider found for permission revoke: "
8368                    + grantUri.toSafeString());
8369            return;
8370        }
8371
8372        // Does the caller have this permission on the URI?
8373        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8374            // If they don't have direct access to the URI, then revoke any
8375            // ownerless URI permissions that have been granted to them.
8376            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8377            if (perms != null) {
8378                boolean persistChanged = false;
8379                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8380                    final UriPermission perm = it.next();
8381                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8382                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8383                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8384                                "Revoking non-owned " + perm.targetUid
8385                                + " permission to " + perm.uri);
8386                        persistChanged |= perm.revokeModes(
8387                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8388                        if (perm.modeFlags == 0) {
8389                            it.remove();
8390                        }
8391                    }
8392                }
8393                if (perms.isEmpty()) {
8394                    mGrantedUriPermissions.remove(callingUid);
8395                }
8396                if (persistChanged) {
8397                    schedulePersistUriGrants();
8398                }
8399            }
8400            return;
8401        }
8402
8403        boolean persistChanged = false;
8404
8405        // Go through all of the permissions and remove any that match.
8406        int N = mGrantedUriPermissions.size();
8407        for (int i = 0; i < N; i++) {
8408            final int targetUid = mGrantedUriPermissions.keyAt(i);
8409            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8410
8411            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8412                final UriPermission perm = it.next();
8413                if (perm.uri.sourceUserId == grantUri.sourceUserId
8414                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8415                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8416                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8417                    persistChanged |= perm.revokeModes(
8418                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8419                    if (perm.modeFlags == 0) {
8420                        it.remove();
8421                    }
8422                }
8423            }
8424
8425            if (perms.isEmpty()) {
8426                mGrantedUriPermissions.remove(targetUid);
8427                N--;
8428                i--;
8429            }
8430        }
8431
8432        if (persistChanged) {
8433            schedulePersistUriGrants();
8434        }
8435    }
8436
8437    /**
8438     * @param uri This uri must NOT contain an embedded userId.
8439     * @param userId The userId in which the uri is to be resolved.
8440     */
8441    @Override
8442    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8443            int userId) {
8444        enforceNotIsolatedCaller("revokeUriPermission");
8445        synchronized(this) {
8446            final ProcessRecord r = getRecordForAppLocked(caller);
8447            if (r == null) {
8448                throw new SecurityException("Unable to find app for caller "
8449                        + caller
8450                        + " when revoking permission to uri " + uri);
8451            }
8452            if (uri == null) {
8453                Slog.w(TAG, "revokeUriPermission: null uri");
8454                return;
8455            }
8456
8457            if (!Intent.isAccessUriMode(modeFlags)) {
8458                return;
8459            }
8460
8461            final String authority = uri.getAuthority();
8462            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8463                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8464            if (pi == null) {
8465                Slog.w(TAG, "No content provider found for permission revoke: "
8466                        + uri.toSafeString());
8467                return;
8468            }
8469
8470            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8471        }
8472    }
8473
8474    /**
8475     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8476     * given package.
8477     *
8478     * @param packageName Package name to match, or {@code null} to apply to all
8479     *            packages.
8480     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8481     *            to all users.
8482     * @param persistable If persistable grants should be removed.
8483     */
8484    private void removeUriPermissionsForPackageLocked(
8485            String packageName, int userHandle, boolean persistable) {
8486        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8487            throw new IllegalArgumentException("Must narrow by either package or user");
8488        }
8489
8490        boolean persistChanged = false;
8491
8492        int N = mGrantedUriPermissions.size();
8493        for (int i = 0; i < N; i++) {
8494            final int targetUid = mGrantedUriPermissions.keyAt(i);
8495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8496
8497            // Only inspect grants matching user
8498            if (userHandle == UserHandle.USER_ALL
8499                    || userHandle == UserHandle.getUserId(targetUid)) {
8500                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8501                    final UriPermission perm = it.next();
8502
8503                    // Only inspect grants matching package
8504                    if (packageName == null || perm.sourcePkg.equals(packageName)
8505                            || perm.targetPkg.equals(packageName)) {
8506                        persistChanged |= perm.revokeModes(persistable
8507                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8508
8509                        // Only remove when no modes remain; any persisted grants
8510                        // will keep this alive.
8511                        if (perm.modeFlags == 0) {
8512                            it.remove();
8513                        }
8514                    }
8515                }
8516
8517                if (perms.isEmpty()) {
8518                    mGrantedUriPermissions.remove(targetUid);
8519                    N--;
8520                    i--;
8521                }
8522            }
8523        }
8524
8525        if (persistChanged) {
8526            schedulePersistUriGrants();
8527        }
8528    }
8529
8530    @Override
8531    public IBinder newUriPermissionOwner(String name) {
8532        enforceNotIsolatedCaller("newUriPermissionOwner");
8533        synchronized(this) {
8534            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8535            return owner.getExternalTokenLocked();
8536        }
8537    }
8538
8539    @Override
8540    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8541        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8542        synchronized(this) {
8543            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8544            if (r == null) {
8545                throw new IllegalArgumentException("Activity does not exist; token="
8546                        + activityToken);
8547            }
8548            return r.getUriPermissionsLocked().getExternalTokenLocked();
8549        }
8550    }
8551    /**
8552     * @param uri This uri must NOT contain an embedded userId.
8553     * @param sourceUserId The userId in which the uri is to be resolved.
8554     * @param targetUserId The userId of the app that receives the grant.
8555     */
8556    @Override
8557    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8558            final int modeFlags, int sourceUserId, int targetUserId) {
8559        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8560                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8561                "grantUriPermissionFromOwner", null);
8562        synchronized(this) {
8563            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8564            if (owner == null) {
8565                throw new IllegalArgumentException("Unknown owner: " + token);
8566            }
8567            if (fromUid != Binder.getCallingUid()) {
8568                if (Binder.getCallingUid() != Process.myUid()) {
8569                    // Only system code can grant URI permissions on behalf
8570                    // of other users.
8571                    throw new SecurityException("nice try");
8572                }
8573            }
8574            if (targetPkg == null) {
8575                throw new IllegalArgumentException("null target");
8576            }
8577            if (uri == null) {
8578                throw new IllegalArgumentException("null uri");
8579            }
8580
8581            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8582                    modeFlags, owner, targetUserId);
8583        }
8584    }
8585
8586    /**
8587     * @param uri This uri must NOT contain an embedded userId.
8588     * @param userId The userId in which the uri is to be resolved.
8589     */
8590    @Override
8591    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8592        synchronized(this) {
8593            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8594            if (owner == null) {
8595                throw new IllegalArgumentException("Unknown owner: " + token);
8596            }
8597
8598            if (uri == null) {
8599                owner.removeUriPermissionsLocked(mode);
8600            } else {
8601                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8602            }
8603        }
8604    }
8605
8606    private void schedulePersistUriGrants() {
8607        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8608            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8609                    10 * DateUtils.SECOND_IN_MILLIS);
8610        }
8611    }
8612
8613    private void writeGrantedUriPermissions() {
8614        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8615
8616        // Snapshot permissions so we can persist without lock
8617        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8618        synchronized (this) {
8619            final int size = mGrantedUriPermissions.size();
8620            for (int i = 0; i < size; i++) {
8621                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8622                for (UriPermission perm : perms.values()) {
8623                    if (perm.persistedModeFlags != 0) {
8624                        persist.add(perm.snapshot());
8625                    }
8626                }
8627            }
8628        }
8629
8630        FileOutputStream fos = null;
8631        try {
8632            fos = mGrantFile.startWrite();
8633
8634            XmlSerializer out = new FastXmlSerializer();
8635            out.setOutput(fos, StandardCharsets.UTF_8.name());
8636            out.startDocument(null, true);
8637            out.startTag(null, TAG_URI_GRANTS);
8638            for (UriPermission.Snapshot perm : persist) {
8639                out.startTag(null, TAG_URI_GRANT);
8640                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8641                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8642                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8643                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8644                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8645                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8646                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8647                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8648                out.endTag(null, TAG_URI_GRANT);
8649            }
8650            out.endTag(null, TAG_URI_GRANTS);
8651            out.endDocument();
8652
8653            mGrantFile.finishWrite(fos);
8654        } catch (IOException e) {
8655            if (fos != null) {
8656                mGrantFile.failWrite(fos);
8657            }
8658        }
8659    }
8660
8661    private void readGrantedUriPermissionsLocked() {
8662        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8663
8664        final long now = System.currentTimeMillis();
8665
8666        FileInputStream fis = null;
8667        try {
8668            fis = mGrantFile.openRead();
8669            final XmlPullParser in = Xml.newPullParser();
8670            in.setInput(fis, StandardCharsets.UTF_8.name());
8671
8672            int type;
8673            while ((type = in.next()) != END_DOCUMENT) {
8674                final String tag = in.getName();
8675                if (type == START_TAG) {
8676                    if (TAG_URI_GRANT.equals(tag)) {
8677                        final int sourceUserId;
8678                        final int targetUserId;
8679                        final int userHandle = readIntAttribute(in,
8680                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8681                        if (userHandle != UserHandle.USER_NULL) {
8682                            // For backwards compatibility.
8683                            sourceUserId = userHandle;
8684                            targetUserId = userHandle;
8685                        } else {
8686                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8687                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8688                        }
8689                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8690                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8691                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8692                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8693                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8694                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8695
8696                        // Sanity check that provider still belongs to source package
8697                        // Both direct boot aware and unaware packages are fine as we
8698                        // will do filtering at query time to avoid multiple parsing.
8699                        final ProviderInfo pi = getProviderInfoLocked(
8700                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8701                                        | MATCH_DIRECT_BOOT_UNAWARE);
8702                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8703                            int targetUid = -1;
8704                            try {
8705                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8706                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8707                            } catch (RemoteException e) {
8708                            }
8709                            if (targetUid != -1) {
8710                                final UriPermission perm = findOrCreateUriPermissionLocked(
8711                                        sourcePkg, targetPkg, targetUid,
8712                                        new GrantUri(sourceUserId, uri, prefix));
8713                                perm.initPersistedModes(modeFlags, createdTime);
8714                            }
8715                        } else {
8716                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8717                                    + " but instead found " + pi);
8718                        }
8719                    }
8720                }
8721            }
8722        } catch (FileNotFoundException e) {
8723            // Missing grants is okay
8724        } catch (IOException e) {
8725            Slog.wtf(TAG, "Failed reading Uri grants", e);
8726        } catch (XmlPullParserException e) {
8727            Slog.wtf(TAG, "Failed reading Uri grants", e);
8728        } finally {
8729            IoUtils.closeQuietly(fis);
8730        }
8731    }
8732
8733    /**
8734     * @param uri This uri must NOT contain an embedded userId.
8735     * @param userId The userId in which the uri is to be resolved.
8736     */
8737    @Override
8738    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8739        enforceNotIsolatedCaller("takePersistableUriPermission");
8740
8741        Preconditions.checkFlagsArgument(modeFlags,
8742                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8743
8744        synchronized (this) {
8745            final int callingUid = Binder.getCallingUid();
8746            boolean persistChanged = false;
8747            GrantUri grantUri = new GrantUri(userId, uri, false);
8748
8749            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8750                    new GrantUri(userId, uri, false));
8751            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8752                    new GrantUri(userId, uri, true));
8753
8754            final boolean exactValid = (exactPerm != null)
8755                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8756            final boolean prefixValid = (prefixPerm != null)
8757                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8758
8759            if (!(exactValid || prefixValid)) {
8760                throw new SecurityException("No persistable permission grants found for UID "
8761                        + callingUid + " and Uri " + grantUri.toSafeString());
8762            }
8763
8764            if (exactValid) {
8765                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8766            }
8767            if (prefixValid) {
8768                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8769            }
8770
8771            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8772
8773            if (persistChanged) {
8774                schedulePersistUriGrants();
8775            }
8776        }
8777    }
8778
8779    /**
8780     * @param uri This uri must NOT contain an embedded userId.
8781     * @param userId The userId in which the uri is to be resolved.
8782     */
8783    @Override
8784    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8785        enforceNotIsolatedCaller("releasePersistableUriPermission");
8786
8787        Preconditions.checkFlagsArgument(modeFlags,
8788                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8789
8790        synchronized (this) {
8791            final int callingUid = Binder.getCallingUid();
8792            boolean persistChanged = false;
8793
8794            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8795                    new GrantUri(userId, uri, false));
8796            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8797                    new GrantUri(userId, uri, true));
8798            if (exactPerm == null && prefixPerm == null) {
8799                throw new SecurityException("No permission grants found for UID " + callingUid
8800                        + " and Uri " + uri.toSafeString());
8801            }
8802
8803            if (exactPerm != null) {
8804                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8805                removeUriPermissionIfNeededLocked(exactPerm);
8806            }
8807            if (prefixPerm != null) {
8808                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8809                removeUriPermissionIfNeededLocked(prefixPerm);
8810            }
8811
8812            if (persistChanged) {
8813                schedulePersistUriGrants();
8814            }
8815        }
8816    }
8817
8818    /**
8819     * Prune any older {@link UriPermission} for the given UID until outstanding
8820     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8821     *
8822     * @return if any mutations occured that require persisting.
8823     */
8824    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8825        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8826        if (perms == null) return false;
8827        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8828
8829        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8830        for (UriPermission perm : perms.values()) {
8831            if (perm.persistedModeFlags != 0) {
8832                persisted.add(perm);
8833            }
8834        }
8835
8836        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8837        if (trimCount <= 0) return false;
8838
8839        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8840        for (int i = 0; i < trimCount; i++) {
8841            final UriPermission perm = persisted.get(i);
8842
8843            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                    "Trimming grant created at " + perm.persistedCreateTime);
8845
8846            perm.releasePersistableModes(~0);
8847            removeUriPermissionIfNeededLocked(perm);
8848        }
8849
8850        return true;
8851    }
8852
8853    @Override
8854    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8855            String packageName, boolean incoming) {
8856        enforceNotIsolatedCaller("getPersistedUriPermissions");
8857        Preconditions.checkNotNull(packageName, "packageName");
8858
8859        final int callingUid = Binder.getCallingUid();
8860        final int callingUserId = UserHandle.getUserId(callingUid);
8861        final IPackageManager pm = AppGlobals.getPackageManager();
8862        try {
8863            final int packageUid = pm.getPackageUid(packageName,
8864                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8865            if (packageUid != callingUid) {
8866                throw new SecurityException(
8867                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8868            }
8869        } catch (RemoteException e) {
8870            throw new SecurityException("Failed to verify package name ownership");
8871        }
8872
8873        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8874        synchronized (this) {
8875            if (incoming) {
8876                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8877                        callingUid);
8878                if (perms == null) {
8879                    Slog.w(TAG, "No permission grants found for " + packageName);
8880                } else {
8881                    for (UriPermission perm : perms.values()) {
8882                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8883                            result.add(perm.buildPersistedPublicApiObject());
8884                        }
8885                    }
8886                }
8887            } else {
8888                final int size = mGrantedUriPermissions.size();
8889                for (int i = 0; i < size; i++) {
8890                    final ArrayMap<GrantUri, UriPermission> perms =
8891                            mGrantedUriPermissions.valueAt(i);
8892                    for (UriPermission perm : perms.values()) {
8893                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8894                            result.add(perm.buildPersistedPublicApiObject());
8895                        }
8896                    }
8897                }
8898            }
8899        }
8900        return new ParceledListSlice<android.content.UriPermission>(result);
8901    }
8902
8903    @Override
8904    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8905            String packageName, int userId) {
8906        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8907                "getGrantedUriPermissions");
8908
8909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8910        synchronized (this) {
8911            final int size = mGrantedUriPermissions.size();
8912            for (int i = 0; i < size; i++) {
8913                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8914                for (UriPermission perm : perms.values()) {
8915                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8916                            && perm.persistedModeFlags != 0) {
8917                        result.add(perm.buildPersistedPublicApiObject());
8918                    }
8919                }
8920            }
8921        }
8922        return new ParceledListSlice<android.content.UriPermission>(result);
8923    }
8924
8925    @Override
8926    public void clearGrantedUriPermissions(String packageName, int userId) {
8927        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8928                "clearGrantedUriPermissions");
8929        removeUriPermissionsForPackageLocked(packageName, userId, true);
8930    }
8931
8932    @Override
8933    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8934        synchronized (this) {
8935            ProcessRecord app =
8936                who != null ? getRecordForAppLocked(who) : null;
8937            if (app == null) return;
8938
8939            Message msg = Message.obtain();
8940            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8941            msg.obj = app;
8942            msg.arg1 = waiting ? 1 : 0;
8943            mUiHandler.sendMessage(msg);
8944        }
8945    }
8946
8947    @Override
8948    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8949        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8950        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8951        outInfo.availMem = Process.getFreeMemory();
8952        outInfo.totalMem = Process.getTotalMemory();
8953        outInfo.threshold = homeAppMem;
8954        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8955        outInfo.hiddenAppThreshold = cachedAppMem;
8956        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8957                ProcessList.SERVICE_ADJ);
8958        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8959                ProcessList.VISIBLE_APP_ADJ);
8960        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8961                ProcessList.FOREGROUND_APP_ADJ);
8962    }
8963
8964    // =========================================================
8965    // TASK MANAGEMENT
8966    // =========================================================
8967
8968    @Override
8969    public List<IAppTask> getAppTasks(String callingPackage) {
8970        int callingUid = Binder.getCallingUid();
8971        long ident = Binder.clearCallingIdentity();
8972
8973        synchronized(this) {
8974            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8975            try {
8976                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8977
8978                final int N = mRecentTasks.size();
8979                for (int i = 0; i < N; i++) {
8980                    TaskRecord tr = mRecentTasks.get(i);
8981                    // Skip tasks that do not match the caller.  We don't need to verify
8982                    // callingPackage, because we are also limiting to callingUid and know
8983                    // that will limit to the correct security sandbox.
8984                    if (tr.effectiveUid != callingUid) {
8985                        continue;
8986                    }
8987                    Intent intent = tr.getBaseIntent();
8988                    if (intent == null ||
8989                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8990                        continue;
8991                    }
8992                    ActivityManager.RecentTaskInfo taskInfo =
8993                            createRecentTaskInfoFromTaskRecord(tr);
8994                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8995                    list.add(taskImpl);
8996                }
8997            } finally {
8998                Binder.restoreCallingIdentity(ident);
8999            }
9000            return list;
9001        }
9002    }
9003
9004    @Override
9005    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9006        final int callingUid = Binder.getCallingUid();
9007        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9008
9009        synchronized(this) {
9010            if (DEBUG_ALL) Slog.v(
9011                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9012
9013            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9014                    callingUid);
9015
9016            // TODO: Improve with MRU list from all ActivityStacks.
9017            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9018        }
9019
9020        return list;
9021    }
9022
9023    /**
9024     * Creates a new RecentTaskInfo from a TaskRecord.
9025     */
9026    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9027        // Update the task description to reflect any changes in the task stack
9028        tr.updateTaskDescription();
9029
9030        // Compose the recent task info
9031        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9032        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9033        rti.persistentId = tr.taskId;
9034        rti.baseIntent = new Intent(tr.getBaseIntent());
9035        rti.origActivity = tr.origActivity;
9036        rti.realActivity = tr.realActivity;
9037        rti.description = tr.lastDescription;
9038        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9039        rti.userId = tr.userId;
9040        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9041        rti.firstActiveTime = tr.firstActiveTime;
9042        rti.lastActiveTime = tr.lastActiveTime;
9043        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9044        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9045        rti.numActivities = 0;
9046        if (tr.mBounds != null) {
9047            rti.bounds = new Rect(tr.mBounds);
9048        }
9049        rti.isDockable = tr.canGoInDockedStack();
9050        rti.resizeMode = tr.mResizeMode;
9051
9052        ActivityRecord base = null;
9053        ActivityRecord top = null;
9054        ActivityRecord tmp;
9055
9056        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9057            tmp = tr.mActivities.get(i);
9058            if (tmp.finishing) {
9059                continue;
9060            }
9061            base = tmp;
9062            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9063                top = base;
9064            }
9065            rti.numActivities++;
9066        }
9067
9068        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9069        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9070
9071        return rti;
9072    }
9073
9074    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9075        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9076                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9077        if (!allowed) {
9078            if (checkPermission(android.Manifest.permission.GET_TASKS,
9079                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9080                // Temporary compatibility: some existing apps on the system image may
9081                // still be requesting the old permission and not switched to the new
9082                // one; if so, we'll still allow them full access.  This means we need
9083                // to see if they are holding the old permission and are a system app.
9084                try {
9085                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9086                        allowed = true;
9087                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9088                                + " is using old GET_TASKS but privileged; allowing");
9089                    }
9090                } catch (RemoteException e) {
9091                }
9092            }
9093        }
9094        if (!allowed) {
9095            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9096                    + " does not hold REAL_GET_TASKS; limiting output");
9097        }
9098        return allowed;
9099    }
9100
9101    @Override
9102    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9103        final int callingUid = Binder.getCallingUid();
9104        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9105                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9106
9107        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9108        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9109        synchronized (this) {
9110            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9111                    callingUid);
9112            final boolean detailed = checkCallingPermission(
9113                    android.Manifest.permission.GET_DETAILED_TASKS)
9114                    == PackageManager.PERMISSION_GRANTED;
9115
9116            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9117                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9118                return Collections.emptyList();
9119            }
9120            mRecentTasks.loadUserRecentsLocked(userId);
9121
9122            final int recentsCount = mRecentTasks.size();
9123            ArrayList<ActivityManager.RecentTaskInfo> res =
9124                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9125
9126            final Set<Integer> includedUsers;
9127            if (includeProfiles) {
9128                includedUsers = mUserController.getProfileIds(userId);
9129            } else {
9130                includedUsers = new HashSet<>();
9131            }
9132            includedUsers.add(Integer.valueOf(userId));
9133
9134            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9135                TaskRecord tr = mRecentTasks.get(i);
9136                // Only add calling user or related users recent tasks
9137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9138                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9139                    continue;
9140                }
9141
9142                if (tr.realActivitySuspended) {
9143                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9144                    continue;
9145                }
9146
9147                // Return the entry if desired by the caller.  We always return
9148                // the first entry, because callers always expect this to be the
9149                // foreground app.  We may filter others if the caller has
9150                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9151                // we should exclude the entry.
9152
9153                if (i == 0
9154                        || withExcluded
9155                        || (tr.intent == null)
9156                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9157                                == 0)) {
9158                    if (!allowed) {
9159                        // If the caller doesn't have the GET_TASKS permission, then only
9160                        // allow them to see a small subset of tasks -- their own and home.
9161                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9163                            continue;
9164                        }
9165                    }
9166                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9167                        if (tr.stack != null && tr.stack.isHomeStack()) {
9168                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                    "Skipping, home stack task: " + tr);
9170                            continue;
9171                        }
9172                    }
9173                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9174                        final ActivityStack stack = tr.stack;
9175                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9176                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9177                                    "Skipping, top task in docked stack: " + tr);
9178                            continue;
9179                        }
9180                    }
9181                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9182                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9183                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                    "Skipping, pinned stack task: " + tr);
9185                            continue;
9186                        }
9187                    }
9188                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9189                        // Don't include auto remove tasks that are finished or finishing.
9190                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9191                                "Skipping, auto-remove without activity: " + tr);
9192                        continue;
9193                    }
9194                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9195                            && !tr.isAvailable) {
9196                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197                                "Skipping, unavail real act: " + tr);
9198                        continue;
9199                    }
9200
9201                    if (!tr.mUserSetupComplete) {
9202                        // Don't include task launched while user is not done setting-up.
9203                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9204                                "Skipping, user setup not complete: " + tr);
9205                        continue;
9206                    }
9207
9208                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9209                    if (!detailed) {
9210                        rti.baseIntent.replaceExtras((Bundle)null);
9211                    }
9212
9213                    res.add(rti);
9214                    maxNum--;
9215                }
9216            }
9217            return res;
9218        }
9219    }
9220
9221    @Override
9222    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9223        synchronized (this) {
9224            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9225                    "getTaskThumbnail()");
9226            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9227                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9228            if (tr != null) {
9229                return tr.getTaskThumbnailLocked();
9230            }
9231        }
9232        return null;
9233    }
9234
9235    @Override
9236    public int addAppTask(IBinder activityToken, Intent intent,
9237            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9238        final int callingUid = Binder.getCallingUid();
9239        final long callingIdent = Binder.clearCallingIdentity();
9240
9241        try {
9242            synchronized (this) {
9243                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9244                if (r == null) {
9245                    throw new IllegalArgumentException("Activity does not exist; token="
9246                            + activityToken);
9247                }
9248                ComponentName comp = intent.getComponent();
9249                if (comp == null) {
9250                    throw new IllegalArgumentException("Intent " + intent
9251                            + " must specify explicit component");
9252                }
9253                if (thumbnail.getWidth() != mThumbnailWidth
9254                        || thumbnail.getHeight() != mThumbnailHeight) {
9255                    throw new IllegalArgumentException("Bad thumbnail size: got "
9256                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9257                            + mThumbnailWidth + "x" + mThumbnailHeight);
9258                }
9259                if (intent.getSelector() != null) {
9260                    intent.setSelector(null);
9261                }
9262                if (intent.getSourceBounds() != null) {
9263                    intent.setSourceBounds(null);
9264                }
9265                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9266                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9267                        // The caller has added this as an auto-remove task...  that makes no
9268                        // sense, so turn off auto-remove.
9269                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9270                    }
9271                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9272                    // Must be a new task.
9273                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9274                }
9275                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9276                    mLastAddedTaskActivity = null;
9277                }
9278                ActivityInfo ainfo = mLastAddedTaskActivity;
9279                if (ainfo == null) {
9280                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9281                            comp, 0, UserHandle.getUserId(callingUid));
9282                    if (ainfo.applicationInfo.uid != callingUid) {
9283                        throw new SecurityException(
9284                                "Can't add task for another application: target uid="
9285                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9286                    }
9287                }
9288
9289                // Use the full screen as the context for the task thumbnail
9290                final Point displaySize = new Point();
9291                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9292                r.task.stack.getDisplaySize(displaySize);
9293                thumbnailInfo.taskWidth = displaySize.x;
9294                thumbnailInfo.taskHeight = displaySize.y;
9295                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9296
9297                TaskRecord task = new TaskRecord(this,
9298                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9299                        ainfo, intent, description, thumbnailInfo);
9300
9301                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9302                if (trimIdx >= 0) {
9303                    // If this would have caused a trim, then we'll abort because that
9304                    // means it would be added at the end of the list but then just removed.
9305                    return INVALID_TASK_ID;
9306                }
9307
9308                final int N = mRecentTasks.size();
9309                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9310                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9311                    tr.removedFromRecents();
9312                }
9313
9314                task.inRecents = true;
9315                mRecentTasks.add(task);
9316                r.task.stack.addTask(task, false, "addAppTask");
9317
9318                task.setLastThumbnailLocked(thumbnail);
9319                task.freeLastThumbnail();
9320
9321                return task.taskId;
9322            }
9323        } finally {
9324            Binder.restoreCallingIdentity(callingIdent);
9325        }
9326    }
9327
9328    @Override
9329    public Point getAppTaskThumbnailSize() {
9330        synchronized (this) {
9331            return new Point(mThumbnailWidth,  mThumbnailHeight);
9332        }
9333    }
9334
9335    @Override
9336    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9337        synchronized (this) {
9338            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9339            if (r != null) {
9340                r.setTaskDescription(td);
9341                r.task.updateTaskDescription();
9342            }
9343        }
9344    }
9345
9346    @Override
9347    public void setTaskResizeable(int taskId, int resizeableMode) {
9348        synchronized (this) {
9349            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351            if (task == null) {
9352                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9353                return;
9354            }
9355            if (task.mResizeMode != resizeableMode) {
9356                task.mResizeMode = resizeableMode;
9357                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9358                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9359                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9360            }
9361        }
9362    }
9363
9364    @Override
9365    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9367        long ident = Binder.clearCallingIdentity();
9368        try {
9369            synchronized (this) {
9370                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9371                if (task == null) {
9372                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9373                    return;
9374                }
9375                int stackId = task.stack.mStackId;
9376                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9377                // in crop windows resize mode or if the task size is affected by the docked stack
9378                // changing size. No need to update configuration.
9379                if (bounds != null && task.inCropWindowsResizeMode()
9380                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9381                    mWindowManager.scrollTask(task.taskId, bounds);
9382                    return;
9383                }
9384
9385                // Place the task in the right stack if it isn't there already based on
9386                // the requested bounds.
9387                // The stack transition logic is:
9388                // - a null bounds on a freeform task moves that task to fullscreen
9389                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9390                //   that task to freeform
9391                // - otherwise the task is not moved
9392                if (!StackId.isTaskResizeAllowed(stackId)) {
9393                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9394                }
9395                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9396                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9397                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9398                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9399                }
9400                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9401                if (stackId != task.stack.mStackId) {
9402                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9403                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9404                    preserveWindow = false;
9405                }
9406
9407                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9408                        false /* deferResume */);
9409            }
9410        } finally {
9411            Binder.restoreCallingIdentity(ident);
9412        }
9413    }
9414
9415    @Override
9416    public Rect getTaskBounds(int taskId) {
9417        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9418        long ident = Binder.clearCallingIdentity();
9419        Rect rect = new Rect();
9420        try {
9421            synchronized (this) {
9422                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9423                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9424                if (task == null) {
9425                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9426                    return rect;
9427                }
9428                if (task.stack != null) {
9429                    // Return the bounds from window manager since it will be adjusted for various
9430                    // things like the presense of a docked stack for tasks that aren't resizeable.
9431                    mWindowManager.getTaskBounds(task.taskId, rect);
9432                } else {
9433                    // Task isn't in window manager yet since it isn't associated with a stack.
9434                    // Return the persist value from activity manager
9435                    if (task.mBounds != null) {
9436                        rect.set(task.mBounds);
9437                    } else if (task.mLastNonFullscreenBounds != null) {
9438                        rect.set(task.mLastNonFullscreenBounds);
9439                    }
9440                }
9441            }
9442        } finally {
9443            Binder.restoreCallingIdentity(ident);
9444        }
9445        return rect;
9446    }
9447
9448    @Override
9449    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9450        if (userId != UserHandle.getCallingUserId()) {
9451            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9452                    "getTaskDescriptionIcon");
9453        }
9454        final File passedIconFile = new File(filePath);
9455        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9456                passedIconFile.getName());
9457        if (!legitIconFile.getPath().equals(filePath)
9458                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9459            throw new IllegalArgumentException("Bad file path: " + filePath
9460                    + " passed for userId " + userId);
9461        }
9462        return mRecentTasks.getTaskDescriptionIcon(filePath);
9463    }
9464
9465    @Override
9466    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9467            throws RemoteException {
9468        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9469                opts.getCustomInPlaceResId() == 0) {
9470            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9471                    "with valid animation");
9472        }
9473        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9474        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9475                opts.getCustomInPlaceResId());
9476        mWindowManager.executeAppTransition();
9477    }
9478
9479    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9480            boolean removeFromRecents) {
9481        if (removeFromRecents) {
9482            mRecentTasks.remove(tr);
9483            tr.removedFromRecents();
9484        }
9485        ComponentName component = tr.getBaseIntent().getComponent();
9486        if (component == null) {
9487            Slog.w(TAG, "No component for base intent of task: " + tr);
9488            return;
9489        }
9490
9491        // Find any running services associated with this app and stop if needed.
9492        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9493
9494        if (!killProcess) {
9495            return;
9496        }
9497
9498        // Determine if the process(es) for this task should be killed.
9499        final String pkg = component.getPackageName();
9500        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9501        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9502        for (int i = 0; i < pmap.size(); i++) {
9503
9504            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9505            for (int j = 0; j < uids.size(); j++) {
9506                ProcessRecord proc = uids.valueAt(j);
9507                if (proc.userId != tr.userId) {
9508                    // Don't kill process for a different user.
9509                    continue;
9510                }
9511                if (proc == mHomeProcess) {
9512                    // Don't kill the home process along with tasks from the same package.
9513                    continue;
9514                }
9515                if (!proc.pkgList.containsKey(pkg)) {
9516                    // Don't kill process that is not associated with this task.
9517                    continue;
9518                }
9519
9520                for (int k = 0; k < proc.activities.size(); k++) {
9521                    TaskRecord otherTask = proc.activities.get(k).task;
9522                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9523                        // Don't kill process(es) that has an activity in a different task that is
9524                        // also in recents.
9525                        return;
9526                    }
9527                }
9528
9529                if (proc.foregroundServices) {
9530                    // Don't kill process(es) with foreground service.
9531                    return;
9532                }
9533
9534                // Add process to kill list.
9535                procsToKill.add(proc);
9536            }
9537        }
9538
9539        // Kill the running processes.
9540        for (int i = 0; i < procsToKill.size(); i++) {
9541            ProcessRecord pr = procsToKill.get(i);
9542            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9543                    && pr.curReceivers.isEmpty()) {
9544                pr.kill("remove task", true);
9545            } else {
9546                // We delay killing processes that are not in the background or running a receiver.
9547                pr.waitingToKill = "remove task";
9548            }
9549        }
9550    }
9551
9552    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9553        // Remove all tasks with activities in the specified package from the list of recent tasks
9554        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9555            TaskRecord tr = mRecentTasks.get(i);
9556            if (tr.userId != userId) continue;
9557
9558            ComponentName cn = tr.intent.getComponent();
9559            if (cn != null && cn.getPackageName().equals(packageName)) {
9560                // If the package name matches, remove the task.
9561                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9562            }
9563        }
9564    }
9565
9566    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9567            int userId) {
9568
9569        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9570            TaskRecord tr = mRecentTasks.get(i);
9571            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9572                continue;
9573            }
9574
9575            ComponentName cn = tr.intent.getComponent();
9576            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9577                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9578            if (sameComponent) {
9579                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9580            }
9581        }
9582    }
9583
9584    /**
9585     * Removes the task with the specified task id.
9586     *
9587     * @param taskId Identifier of the task to be removed.
9588     * @param killProcess Kill any process associated with the task if possible.
9589     * @param removeFromRecents Whether to also remove the task from recents.
9590     * @return Returns true if the given task was found and removed.
9591     */
9592    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9593            boolean removeFromRecents) {
9594        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9595                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9596        if (tr != null) {
9597            tr.removeTaskActivitiesLocked();
9598            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9599            if (tr.isPersistable) {
9600                notifyTaskPersisterLocked(null, true);
9601            }
9602            return true;
9603        }
9604        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9605        return false;
9606    }
9607
9608    @Override
9609    public void removeStack(int stackId) {
9610        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9611        if (stackId == HOME_STACK_ID) {
9612            throw new IllegalArgumentException("Removing home stack is not allowed.");
9613        }
9614
9615        synchronized (this) {
9616            final long ident = Binder.clearCallingIdentity();
9617            try {
9618                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9619                if (stack == null) {
9620                    return;
9621                }
9622                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9623                for (int i = tasks.size() - 1; i >= 0; i--) {
9624                    removeTaskByIdLocked(
9625                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9626                }
9627            } finally {
9628                Binder.restoreCallingIdentity(ident);
9629            }
9630        }
9631    }
9632
9633    @Override
9634    public boolean removeTask(int taskId) {
9635        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9636        synchronized (this) {
9637            final long ident = Binder.clearCallingIdentity();
9638            try {
9639                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9640            } finally {
9641                Binder.restoreCallingIdentity(ident);
9642            }
9643        }
9644    }
9645
9646    /**
9647     * TODO: Add mController hook
9648     */
9649    @Override
9650    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9651        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9652
9653        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9654        synchronized(this) {
9655            moveTaskToFrontLocked(taskId, flags, bOptions);
9656        }
9657    }
9658
9659    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9660        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9661
9662        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9663                Binder.getCallingUid(), -1, -1, "Task to front")) {
9664            ActivityOptions.abort(options);
9665            return;
9666        }
9667        final long origId = Binder.clearCallingIdentity();
9668        try {
9669            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9670            if (task == null) {
9671                Slog.d(TAG, "Could not find task for id: "+ taskId);
9672                return;
9673            }
9674            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9675                mStackSupervisor.showLockTaskToast();
9676                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9677                return;
9678            }
9679            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9680            if (prev != null && prev.isRecentsActivity()) {
9681                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9682            }
9683            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9684                    false /* forceNonResizable */);
9685        } finally {
9686            Binder.restoreCallingIdentity(origId);
9687        }
9688        ActivityOptions.abort(options);
9689    }
9690
9691    /**
9692     * Moves an activity, and all of the other activities within the same task, to the bottom
9693     * of the history stack.  The activity's order within the task is unchanged.
9694     *
9695     * @param token A reference to the activity we wish to move
9696     * @param nonRoot If false then this only works if the activity is the root
9697     *                of a task; if true it will work for any activity in a task.
9698     * @return Returns true if the move completed, false if not.
9699     */
9700    @Override
9701    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9702        enforceNotIsolatedCaller("moveActivityTaskToBack");
9703        synchronized(this) {
9704            final long origId = Binder.clearCallingIdentity();
9705            try {
9706                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9707                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9708                if (task != null) {
9709                    if (mStackSupervisor.isLockedTask(task)) {
9710                        mStackSupervisor.showLockTaskToast();
9711                        return false;
9712                    }
9713                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9714                }
9715            } finally {
9716                Binder.restoreCallingIdentity(origId);
9717            }
9718        }
9719        return false;
9720    }
9721
9722    @Override
9723    public void moveTaskBackwards(int task) {
9724        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9725                "moveTaskBackwards()");
9726
9727        synchronized(this) {
9728            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9729                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9730                return;
9731            }
9732            final long origId = Binder.clearCallingIdentity();
9733            moveTaskBackwardsLocked(task);
9734            Binder.restoreCallingIdentity(origId);
9735        }
9736    }
9737
9738    private final void moveTaskBackwardsLocked(int task) {
9739        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9740    }
9741
9742    @Override
9743    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9744            IActivityContainerCallback callback) throws RemoteException {
9745        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9746        synchronized (this) {
9747            if (parentActivityToken == null) {
9748                throw new IllegalArgumentException("parent token must not be null");
9749            }
9750            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9751            if (r == null) {
9752                return null;
9753            }
9754            if (callback == null) {
9755                throw new IllegalArgumentException("callback must not be null");
9756            }
9757            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9758        }
9759    }
9760
9761    @Override
9762    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9764        synchronized (this) {
9765            mStackSupervisor.deleteActivityContainer(container);
9766        }
9767    }
9768
9769    @Override
9770    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9771        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9772        synchronized (this) {
9773            final int stackId = mStackSupervisor.getNextStackId();
9774            final ActivityStack stack =
9775                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9776            if (stack == null) {
9777                return null;
9778            }
9779            return stack.mActivityContainer;
9780        }
9781    }
9782
9783    @Override
9784    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9785        synchronized (this) {
9786            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9787            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9788                return stack.mActivityContainer.getDisplayId();
9789            }
9790            return Display.DEFAULT_DISPLAY;
9791        }
9792    }
9793
9794    @Override
9795    public int getActivityStackId(IBinder token) throws RemoteException {
9796        synchronized (this) {
9797            ActivityStack stack = ActivityRecord.getStackLocked(token);
9798            if (stack == null) {
9799                return INVALID_STACK_ID;
9800            }
9801            return stack.mStackId;
9802        }
9803    }
9804
9805    @Override
9806    public void exitFreeformMode(IBinder token) throws RemoteException {
9807        synchronized (this) {
9808            long ident = Binder.clearCallingIdentity();
9809            try {
9810                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9811                if (r == null) {
9812                    throw new IllegalArgumentException(
9813                            "exitFreeformMode: No activity record matching token=" + token);
9814                }
9815                final ActivityStack stack = r.getStackLocked(token);
9816                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9817                    throw new IllegalStateException(
9818                            "exitFreeformMode: You can only go fullscreen from freeform.");
9819                }
9820                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9821                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9822                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9823            } finally {
9824                Binder.restoreCallingIdentity(ident);
9825            }
9826        }
9827    }
9828
9829    @Override
9830    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9831        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9832        if (stackId == HOME_STACK_ID) {
9833            throw new IllegalArgumentException(
9834                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9835        }
9836        synchronized (this) {
9837            long ident = Binder.clearCallingIdentity();
9838            try {
9839                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9840                        + " to stackId=" + stackId + " toTop=" + toTop);
9841                if (stackId == DOCKED_STACK_ID) {
9842                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9843                            null /* initialBounds */);
9844                }
9845                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9846                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9847                if (result && stackId == DOCKED_STACK_ID) {
9848                    // If task moved to docked stack - show recents if needed.
9849                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9850                            "moveTaskToDockedStack");
9851                }
9852            } finally {
9853                Binder.restoreCallingIdentity(ident);
9854            }
9855        }
9856    }
9857
9858    @Override
9859    public void swapDockedAndFullscreenStack() throws RemoteException {
9860        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9861        synchronized (this) {
9862            long ident = Binder.clearCallingIdentity();
9863            try {
9864                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9865                        FULLSCREEN_WORKSPACE_STACK_ID);
9866                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9867                        : null;
9868                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9869                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9870                        : null;
9871                if (topTask == null || tasks == null || tasks.size() == 0) {
9872                    Slog.w(TAG,
9873                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9874                    return;
9875                }
9876
9877                // TODO: App transition
9878                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9879
9880                // Defer the resume so resume/pausing while moving stacks is dangerous.
9881                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9882                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9883                        ANIMATE, true /* deferResume */);
9884                final int size = tasks.size();
9885                for (int i = 0; i < size; i++) {
9886                    final int id = tasks.get(i).taskId;
9887                    if (id == topTask.taskId) {
9888                        continue;
9889                    }
9890                    mStackSupervisor.moveTaskToStackLocked(id,
9891                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9892                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9893                }
9894
9895                // Because we deferred the resume, to avoid conflicts with stack switches while
9896                // resuming, we need to do it after all the tasks are moved.
9897                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9898                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9899
9900                mWindowManager.executeAppTransition();
9901            } finally {
9902                Binder.restoreCallingIdentity(ident);
9903            }
9904        }
9905    }
9906
9907    /**
9908     * Moves the input task to the docked stack.
9909     *
9910     * @param taskId Id of task to move.
9911     * @param createMode The mode the docked stack should be created in if it doesn't exist
9912     *                   already. See
9913     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9914     *                   and
9915     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9916     * @param toTop If the task and stack should be moved to the top.
9917     * @param animate Whether we should play an animation for the moving the task
9918     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9919     *                      docked stack. Pass {@code null} to use default bounds.
9920     */
9921    @Override
9922    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9923            Rect initialBounds, boolean moveHomeStackFront) {
9924        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9925        synchronized (this) {
9926            long ident = Binder.clearCallingIdentity();
9927            try {
9928                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9929                        + " to createMode=" + createMode + " toTop=" + toTop);
9930                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9931                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9932                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9933                        animate, DEFER_RESUME);
9934                if (moved) {
9935                    if (moveHomeStackFront) {
9936                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9937                    }
9938                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9939                }
9940                return moved;
9941            } finally {
9942                Binder.restoreCallingIdentity(ident);
9943            }
9944        }
9945    }
9946
9947    /**
9948     * Moves the top activity in the input stackId to the pinned stack.
9949     *
9950     * @param stackId Id of stack to move the top activity to pinned stack.
9951     * @param bounds Bounds to use for pinned stack.
9952     *
9953     * @return True if the top activity of the input stack was successfully moved to the pinned
9954     *          stack.
9955     */
9956    @Override
9957    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9958        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9959        synchronized (this) {
9960            if (!mSupportsPictureInPicture) {
9961                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9962                        + "Device doesn't support picture-in-pciture mode");
9963            }
9964
9965            long ident = Binder.clearCallingIdentity();
9966            try {
9967                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9968            } finally {
9969                Binder.restoreCallingIdentity(ident);
9970            }
9971        }
9972    }
9973
9974    @Override
9975    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9976            boolean preserveWindows, boolean animate, int animationDuration) {
9977        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9978        long ident = Binder.clearCallingIdentity();
9979        try {
9980            synchronized (this) {
9981                if (animate) {
9982                    if (stackId == PINNED_STACK_ID) {
9983                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9984                    } else {
9985                        throw new IllegalArgumentException("Stack: " + stackId
9986                                + " doesn't support animated resize.");
9987                    }
9988                } else {
9989                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9990                            null /* tempTaskInsetBounds */, preserveWindows,
9991                            allowResizeInDockedMode, !DEFER_RESUME);
9992                }
9993            }
9994        } finally {
9995            Binder.restoreCallingIdentity(ident);
9996        }
9997    }
9998
9999    @Override
10000    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10001            Rect tempDockedTaskInsetBounds,
10002            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10003        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10004                "resizeDockedStack()");
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            synchronized (this) {
10008                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10009                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10010                        PRESERVE_WINDOWS);
10011            }
10012        } finally {
10013            Binder.restoreCallingIdentity(ident);
10014        }
10015    }
10016
10017    @Override
10018    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10019        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10020                "resizePinnedStack()");
10021        final long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public void positionTaskInStack(int taskId, int stackId, int position) {
10033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10034        if (stackId == HOME_STACK_ID) {
10035            throw new IllegalArgumentException(
10036                    "positionTaskInStack: Attempt to change the position of task "
10037                    + taskId + " in/to home stack");
10038        }
10039        synchronized (this) {
10040            long ident = Binder.clearCallingIdentity();
10041            try {
10042                if (DEBUG_STACK) Slog.d(TAG_STACK,
10043                        "positionTaskInStack: positioning task=" + taskId
10044                        + " in stackId=" + stackId + " at position=" + position);
10045                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10046            } finally {
10047                Binder.restoreCallingIdentity(ident);
10048            }
10049        }
10050    }
10051
10052    @Override
10053    public List<StackInfo> getAllStackInfos() {
10054        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10055        long ident = Binder.clearCallingIdentity();
10056        try {
10057            synchronized (this) {
10058                return mStackSupervisor.getAllStackInfosLocked();
10059            }
10060        } finally {
10061            Binder.restoreCallingIdentity(ident);
10062        }
10063    }
10064
10065    @Override
10066    public StackInfo getStackInfo(int stackId) {
10067        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10068        long ident = Binder.clearCallingIdentity();
10069        try {
10070            synchronized (this) {
10071                return mStackSupervisor.getStackInfoLocked(stackId);
10072            }
10073        } finally {
10074            Binder.restoreCallingIdentity(ident);
10075        }
10076    }
10077
10078    @Override
10079    public boolean isInHomeStack(int taskId) {
10080        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10081        long ident = Binder.clearCallingIdentity();
10082        try {
10083            synchronized (this) {
10084                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10085                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10086                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10087            }
10088        } finally {
10089            Binder.restoreCallingIdentity(ident);
10090        }
10091    }
10092
10093    @Override
10094    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10095        synchronized(this) {
10096            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10097        }
10098    }
10099
10100    @Override
10101    public void updateDeviceOwner(String packageName) {
10102        final int callingUid = Binder.getCallingUid();
10103        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10104            throw new SecurityException("updateDeviceOwner called from non-system process");
10105        }
10106        synchronized (this) {
10107            mDeviceOwnerName = packageName;
10108        }
10109    }
10110
10111    @Override
10112    public void updateLockTaskPackages(int userId, String[] packages) {
10113        final int callingUid = Binder.getCallingUid();
10114        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10115            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10116                    "updateLockTaskPackages()");
10117        }
10118        synchronized (this) {
10119            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10120                    Arrays.toString(packages));
10121            mLockTaskPackages.put(userId, packages);
10122            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10123        }
10124    }
10125
10126
10127    void startLockTaskModeLocked(TaskRecord task) {
10128        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10129        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10130            return;
10131        }
10132
10133        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10134        // is initiated by system after the pinning request was shown and locked mode is initiated
10135        // by an authorized app directly
10136        final int callingUid = Binder.getCallingUid();
10137        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10138        long ident = Binder.clearCallingIdentity();
10139        try {
10140            if (!isSystemInitiated) {
10141                task.mLockTaskUid = callingUid;
10142                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10143                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10144                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10145                    StatusBarManagerInternal statusBarManager =
10146                            LocalServices.getService(StatusBarManagerInternal.class);
10147                    if (statusBarManager != null) {
10148                        statusBarManager.showScreenPinningRequest(task.taskId);
10149                    }
10150                    return;
10151                }
10152
10153                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10154                if (stack == null || task != stack.topTask()) {
10155                    throw new IllegalArgumentException("Invalid task, not in foreground");
10156                }
10157            }
10158            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10159                    "Locking fully");
10160            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10161                    ActivityManager.LOCK_TASK_MODE_PINNED :
10162                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10163                    "startLockTask", true);
10164        } finally {
10165            Binder.restoreCallingIdentity(ident);
10166        }
10167    }
10168
10169    @Override
10170    public void startLockTaskMode(int taskId) {
10171        synchronized (this) {
10172            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10173            if (task != null) {
10174                startLockTaskModeLocked(task);
10175            }
10176        }
10177    }
10178
10179    @Override
10180    public void startLockTaskMode(IBinder token) {
10181        synchronized (this) {
10182            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10183            if (r == null) {
10184                return;
10185            }
10186            final TaskRecord task = r.task;
10187            if (task != null) {
10188                startLockTaskModeLocked(task);
10189            }
10190        }
10191    }
10192
10193    @Override
10194    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10195        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10196        // This makes inner call to look as if it was initiated by system.
10197        long ident = Binder.clearCallingIdentity();
10198        try {
10199            synchronized (this) {
10200                startLockTaskMode(taskId);
10201            }
10202        } finally {
10203            Binder.restoreCallingIdentity(ident);
10204        }
10205    }
10206
10207    @Override
10208    public void stopLockTaskMode() {
10209        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10210        if (lockTask == null) {
10211            // Our work here is done.
10212            return;
10213        }
10214
10215        final int callingUid = Binder.getCallingUid();
10216        final int lockTaskUid = lockTask.mLockTaskUid;
10217        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10218        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10219            // Done.
10220            return;
10221        } else {
10222            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10223            // It is possible lockTaskMode was started by the system process because
10224            // android:lockTaskMode is set to a locking value in the application manifest
10225            // instead of the app calling startLockTaskMode. In this case
10226            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10227            // {@link TaskRecord.effectiveUid} instead. Also caller with
10228            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10229            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10230                    && callingUid != lockTaskUid
10231                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10232                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10233                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10234            }
10235        }
10236        long ident = Binder.clearCallingIdentity();
10237        try {
10238            Log.d(TAG, "stopLockTaskMode");
10239            // Stop lock task
10240            synchronized (this) {
10241                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10242                        "stopLockTask", true);
10243            }
10244            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10245            if (tm != null) {
10246                tm.showInCallScreen(false);
10247            }
10248        } finally {
10249            Binder.restoreCallingIdentity(ident);
10250        }
10251    }
10252
10253    /**
10254     * This API should be called by SystemUI only when user perform certain action to dismiss
10255     * lock task mode. We should only dismiss pinned lock task mode in this case.
10256     */
10257    @Override
10258    public void stopSystemLockTaskMode() throws RemoteException {
10259        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10260            stopLockTaskMode();
10261        } else {
10262            mStackSupervisor.showLockTaskToast();
10263        }
10264    }
10265
10266    @Override
10267    public boolean isInLockTaskMode() {
10268        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10269    }
10270
10271    @Override
10272    public int getLockTaskModeState() {
10273        synchronized (this) {
10274            return mStackSupervisor.getLockTaskModeState();
10275        }
10276    }
10277
10278    @Override
10279    public void showLockTaskEscapeMessage(IBinder token) {
10280        synchronized (this) {
10281            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10282            if (r == null) {
10283                return;
10284            }
10285            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10286        }
10287    }
10288
10289    // =========================================================
10290    // CONTENT PROVIDERS
10291    // =========================================================
10292
10293    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10294        List<ProviderInfo> providers = null;
10295        try {
10296            providers = AppGlobals.getPackageManager()
10297                    .queryContentProviders(app.processName, app.uid,
10298                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10299                                    | MATCH_DEBUG_TRIAGED_MISSING)
10300                    .getList();
10301        } catch (RemoteException ex) {
10302        }
10303        if (DEBUG_MU) Slog.v(TAG_MU,
10304                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10305        int userId = app.userId;
10306        if (providers != null) {
10307            int N = providers.size();
10308            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10309            for (int i=0; i<N; i++) {
10310                // TODO: keep logic in sync with installEncryptionUnawareProviders
10311                ProviderInfo cpi =
10312                    (ProviderInfo)providers.get(i);
10313                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10314                        cpi.name, cpi.flags);
10315                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10316                    // This is a singleton provider, but a user besides the
10317                    // default user is asking to initialize a process it runs
10318                    // in...  well, no, it doesn't actually run in this process,
10319                    // it runs in the process of the default user.  Get rid of it.
10320                    providers.remove(i);
10321                    N--;
10322                    i--;
10323                    continue;
10324                }
10325
10326                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10327                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10328                if (cpr == null) {
10329                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10330                    mProviderMap.putProviderByClass(comp, cpr);
10331                }
10332                if (DEBUG_MU) Slog.v(TAG_MU,
10333                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10334                app.pubProviders.put(cpi.name, cpr);
10335                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10336                    // Don't add this if it is a platform component that is marked
10337                    // to run in multiple processes, because this is actually
10338                    // part of the framework so doesn't make sense to track as a
10339                    // separate apk in the process.
10340                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10341                            mProcessStats);
10342                }
10343                notifyPackageUse(cpi.applicationInfo.packageName,
10344                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10345            }
10346        }
10347        return providers;
10348    }
10349
10350    /**
10351     * Check if {@link ProcessRecord} has a possible chance at accessing the
10352     * given {@link ProviderInfo}. Final permission checking is always done
10353     * in {@link ContentProvider}.
10354     */
10355    private final String checkContentProviderPermissionLocked(
10356            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10357        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10358        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10359        boolean checkedGrants = false;
10360        if (checkUser) {
10361            // Looking for cross-user grants before enforcing the typical cross-users permissions
10362            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10363            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10364                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10365                    return null;
10366                }
10367                checkedGrants = true;
10368            }
10369            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10370                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10371            if (userId != tmpTargetUserId) {
10372                // When we actually went to determine the final targer user ID, this ended
10373                // up different than our initial check for the authority.  This is because
10374                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10375                // SELF.  So we need to re-check the grants again.
10376                checkedGrants = false;
10377            }
10378        }
10379        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10380                cpi.applicationInfo.uid, cpi.exported)
10381                == PackageManager.PERMISSION_GRANTED) {
10382            return null;
10383        }
10384        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10385                cpi.applicationInfo.uid, cpi.exported)
10386                == PackageManager.PERMISSION_GRANTED) {
10387            return null;
10388        }
10389
10390        PathPermission[] pps = cpi.pathPermissions;
10391        if (pps != null) {
10392            int i = pps.length;
10393            while (i > 0) {
10394                i--;
10395                PathPermission pp = pps[i];
10396                String pprperm = pp.getReadPermission();
10397                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10398                        cpi.applicationInfo.uid, cpi.exported)
10399                        == PackageManager.PERMISSION_GRANTED) {
10400                    return null;
10401                }
10402                String ppwperm = pp.getWritePermission();
10403                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10404                        cpi.applicationInfo.uid, cpi.exported)
10405                        == PackageManager.PERMISSION_GRANTED) {
10406                    return null;
10407                }
10408            }
10409        }
10410        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10411            return null;
10412        }
10413
10414        String msg;
10415        if (!cpi.exported) {
10416            msg = "Permission Denial: opening provider " + cpi.name
10417                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10418                    + ", uid=" + callingUid + ") that is not exported from uid "
10419                    + cpi.applicationInfo.uid;
10420        } else {
10421            msg = "Permission Denial: opening provider " + cpi.name
10422                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10423                    + ", uid=" + callingUid + ") requires "
10424                    + cpi.readPermission + " or " + cpi.writePermission;
10425        }
10426        Slog.w(TAG, msg);
10427        return msg;
10428    }
10429
10430    /**
10431     * Returns if the ContentProvider has granted a uri to callingUid
10432     */
10433    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10434        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10435        if (perms != null) {
10436            for (int i=perms.size()-1; i>=0; i--) {
10437                GrantUri grantUri = perms.keyAt(i);
10438                if (grantUri.sourceUserId == userId || !checkUser) {
10439                    if (matchesProvider(grantUri.uri, cpi)) {
10440                        return true;
10441                    }
10442                }
10443            }
10444        }
10445        return false;
10446    }
10447
10448    /**
10449     * Returns true if the uri authority is one of the authorities specified in the provider.
10450     */
10451    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10452        String uriAuth = uri.getAuthority();
10453        String cpiAuth = cpi.authority;
10454        if (cpiAuth.indexOf(';') == -1) {
10455            return cpiAuth.equals(uriAuth);
10456        }
10457        String[] cpiAuths = cpiAuth.split(";");
10458        int length = cpiAuths.length;
10459        for (int i = 0; i < length; i++) {
10460            if (cpiAuths[i].equals(uriAuth)) return true;
10461        }
10462        return false;
10463    }
10464
10465    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10466            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10467        if (r != null) {
10468            for (int i=0; i<r.conProviders.size(); i++) {
10469                ContentProviderConnection conn = r.conProviders.get(i);
10470                if (conn.provider == cpr) {
10471                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10472                            "Adding provider requested by "
10473                            + r.processName + " from process "
10474                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10475                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10476                    if (stable) {
10477                        conn.stableCount++;
10478                        conn.numStableIncs++;
10479                    } else {
10480                        conn.unstableCount++;
10481                        conn.numUnstableIncs++;
10482                    }
10483                    return conn;
10484                }
10485            }
10486            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10487            if (stable) {
10488                conn.stableCount = 1;
10489                conn.numStableIncs = 1;
10490            } else {
10491                conn.unstableCount = 1;
10492                conn.numUnstableIncs = 1;
10493            }
10494            cpr.connections.add(conn);
10495            r.conProviders.add(conn);
10496            startAssociationLocked(r.uid, r.processName, r.curProcState,
10497                    cpr.uid, cpr.name, cpr.info.processName);
10498            return conn;
10499        }
10500        cpr.addExternalProcessHandleLocked(externalProcessToken);
10501        return null;
10502    }
10503
10504    boolean decProviderCountLocked(ContentProviderConnection conn,
10505            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10506        if (conn != null) {
10507            cpr = conn.provider;
10508            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10509                    "Removing provider requested by "
10510                    + conn.client.processName + " from process "
10511                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10512                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10513            if (stable) {
10514                conn.stableCount--;
10515            } else {
10516                conn.unstableCount--;
10517            }
10518            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10519                cpr.connections.remove(conn);
10520                conn.client.conProviders.remove(conn);
10521                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10522                    // The client is more important than last activity -- note the time this
10523                    // is happening, so we keep the old provider process around a bit as last
10524                    // activity to avoid thrashing it.
10525                    if (cpr.proc != null) {
10526                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10527                    }
10528                }
10529                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10530                return true;
10531            }
10532            return false;
10533        }
10534        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10535        return false;
10536    }
10537
10538    private void checkTime(long startTime, String where) {
10539        long now = SystemClock.uptimeMillis();
10540        if ((now-startTime) > 50) {
10541            // If we are taking more than 50ms, log about it.
10542            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10543        }
10544    }
10545
10546    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10547            PROC_SPACE_TERM,
10548            PROC_SPACE_TERM|PROC_PARENS,
10549            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10550    };
10551
10552    private final long[] mProcessStateStatsLongs = new long[1];
10553
10554    boolean isProcessAliveLocked(ProcessRecord proc) {
10555        if (proc.procStatFile == null) {
10556            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10557        }
10558        mProcessStateStatsLongs[0] = 0;
10559        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10560                mProcessStateStatsLongs, null)) {
10561            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10562            return false;
10563        }
10564        final long state = mProcessStateStatsLongs[0];
10565        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10566                + (char)state);
10567        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10568    }
10569
10570    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10571            String name, IBinder token, boolean stable, int userId) {
10572        ContentProviderRecord cpr;
10573        ContentProviderConnection conn = null;
10574        ProviderInfo cpi = null;
10575
10576        synchronized(this) {
10577            long startTime = SystemClock.uptimeMillis();
10578
10579            ProcessRecord r = null;
10580            if (caller != null) {
10581                r = getRecordForAppLocked(caller);
10582                if (r == null) {
10583                    throw new SecurityException(
10584                            "Unable to find app for caller " + caller
10585                          + " (pid=" + Binder.getCallingPid()
10586                          + ") when getting content provider " + name);
10587                }
10588            }
10589
10590            boolean checkCrossUser = true;
10591
10592            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10593
10594            // First check if this content provider has been published...
10595            cpr = mProviderMap.getProviderByName(name, userId);
10596            // If that didn't work, check if it exists for user 0 and then
10597            // verify that it's a singleton provider before using it.
10598            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10599                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10600                if (cpr != null) {
10601                    cpi = cpr.info;
10602                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10603                            cpi.name, cpi.flags)
10604                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10605                        userId = UserHandle.USER_SYSTEM;
10606                        checkCrossUser = false;
10607                    } else {
10608                        cpr = null;
10609                        cpi = null;
10610                    }
10611                }
10612            }
10613
10614            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10615            if (providerRunning) {
10616                cpi = cpr.info;
10617                String msg;
10618                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10619                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10620                        != null) {
10621                    throw new SecurityException(msg);
10622                }
10623                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10624
10625                if (r != null && cpr.canRunHere(r)) {
10626                    // This provider has been published or is in the process
10627                    // of being published...  but it is also allowed to run
10628                    // in the caller's process, so don't make a connection
10629                    // and just let the caller instantiate its own instance.
10630                    ContentProviderHolder holder = cpr.newHolder(null);
10631                    // don't give caller the provider object, it needs
10632                    // to make its own.
10633                    holder.provider = null;
10634                    return holder;
10635                }
10636
10637                final long origId = Binder.clearCallingIdentity();
10638
10639                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10640
10641                // In this case the provider instance already exists, so we can
10642                // return it right away.
10643                conn = incProviderCountLocked(r, cpr, token, stable);
10644                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10645                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10646                        // If this is a perceptible app accessing the provider,
10647                        // make sure to count it as being accessed and thus
10648                        // back up on the LRU list.  This is good because
10649                        // content providers are often expensive to start.
10650                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10651                        updateLruProcessLocked(cpr.proc, false, null);
10652                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10653                    }
10654                }
10655
10656                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10657                final int verifiedAdj = cpr.proc.verifiedAdj;
10658                boolean success = updateOomAdjLocked(cpr.proc);
10659                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10660                // if the process has been successfully adjusted.  So to reduce races with
10661                // it, we will check whether the process still exists.  Note that this doesn't
10662                // completely get rid of races with LMK killing the process, but should make
10663                // them much smaller.
10664                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10665                    success = false;
10666                }
10667                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10668                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10669                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10670                // NOTE: there is still a race here where a signal could be
10671                // pending on the process even though we managed to update its
10672                // adj level.  Not sure what to do about this, but at least
10673                // the race is now smaller.
10674                if (!success) {
10675                    // Uh oh...  it looks like the provider's process
10676                    // has been killed on us.  We need to wait for a new
10677                    // process to be started, and make sure its death
10678                    // doesn't kill our process.
10679                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10680                            + " is crashing; detaching " + r);
10681                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10682                    checkTime(startTime, "getContentProviderImpl: before appDied");
10683                    appDiedLocked(cpr.proc);
10684                    checkTime(startTime, "getContentProviderImpl: after appDied");
10685                    if (!lastRef) {
10686                        // This wasn't the last ref our process had on
10687                        // the provider...  we have now been killed, bail.
10688                        return null;
10689                    }
10690                    providerRunning = false;
10691                    conn = null;
10692                } else {
10693                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10694                }
10695
10696                Binder.restoreCallingIdentity(origId);
10697            }
10698
10699            if (!providerRunning) {
10700                try {
10701                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10702                    cpi = AppGlobals.getPackageManager().
10703                        resolveContentProvider(name,
10704                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10705                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10706                } catch (RemoteException ex) {
10707                }
10708                if (cpi == null) {
10709                    return null;
10710                }
10711                // If the provider is a singleton AND
10712                // (it's a call within the same user || the provider is a
10713                // privileged app)
10714                // Then allow connecting to the singleton provider
10715                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10716                        cpi.name, cpi.flags)
10717                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10718                if (singleton) {
10719                    userId = UserHandle.USER_SYSTEM;
10720                }
10721                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10722                checkTime(startTime, "getContentProviderImpl: got app info for user");
10723
10724                String msg;
10725                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10726                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10727                        != null) {
10728                    throw new SecurityException(msg);
10729                }
10730                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10731
10732                if (!mProcessesReady
10733                        && !cpi.processName.equals("system")) {
10734                    // If this content provider does not run in the system
10735                    // process, and the system is not yet ready to run other
10736                    // processes, then fail fast instead of hanging.
10737                    throw new IllegalArgumentException(
10738                            "Attempt to launch content provider before system ready");
10739                }
10740
10741                // Make sure that the user who owns this provider is running.  If not,
10742                // we don't want to allow it to run.
10743                if (!mUserController.isUserRunningLocked(userId, 0)) {
10744                    Slog.w(TAG, "Unable to launch app "
10745                            + cpi.applicationInfo.packageName + "/"
10746                            + cpi.applicationInfo.uid + " for provider "
10747                            + name + ": user " + userId + " is stopped");
10748                    return null;
10749                }
10750
10751                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10752                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10753                cpr = mProviderMap.getProviderByClass(comp, userId);
10754                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10755                final boolean firstClass = cpr == null;
10756                if (firstClass) {
10757                    final long ident = Binder.clearCallingIdentity();
10758
10759                    // If permissions need a review before any of the app components can run,
10760                    // we return no provider and launch a review activity if the calling app
10761                    // is in the foreground.
10762                    if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10763                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10764                            return null;
10765                        }
10766                    }
10767
10768                    try {
10769                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10770                        ApplicationInfo ai =
10771                            AppGlobals.getPackageManager().
10772                                getApplicationInfo(
10773                                        cpi.applicationInfo.packageName,
10774                                        STOCK_PM_FLAGS, userId);
10775                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10776                        if (ai == null) {
10777                            Slog.w(TAG, "No package info for content provider "
10778                                    + cpi.name);
10779                            return null;
10780                        }
10781                        ai = getAppInfoForUser(ai, userId);
10782                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10783                    } catch (RemoteException ex) {
10784                        // pm is in same process, this will never happen.
10785                    } finally {
10786                        Binder.restoreCallingIdentity(ident);
10787                    }
10788                }
10789
10790                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10791
10792                if (r != null && cpr.canRunHere(r)) {
10793                    // If this is a multiprocess provider, then just return its
10794                    // info and allow the caller to instantiate it.  Only do
10795                    // this if the provider is the same user as the caller's
10796                    // process, or can run as root (so can be in any process).
10797                    return cpr.newHolder(null);
10798                }
10799
10800                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10801                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10802                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10803
10804                // This is single process, and our app is now connecting to it.
10805                // See if we are already in the process of launching this
10806                // provider.
10807                final int N = mLaunchingProviders.size();
10808                int i;
10809                for (i = 0; i < N; i++) {
10810                    if (mLaunchingProviders.get(i) == cpr) {
10811                        break;
10812                    }
10813                }
10814
10815                // If the provider is not already being launched, then get it
10816                // started.
10817                if (i >= N) {
10818                    final long origId = Binder.clearCallingIdentity();
10819
10820                    try {
10821                        // Content provider is now in use, its package can't be stopped.
10822                        try {
10823                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10824                            AppGlobals.getPackageManager().setPackageStoppedState(
10825                                    cpr.appInfo.packageName, false, userId);
10826                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10827                        } catch (RemoteException e) {
10828                        } catch (IllegalArgumentException e) {
10829                            Slog.w(TAG, "Failed trying to unstop package "
10830                                    + cpr.appInfo.packageName + ": " + e);
10831                        }
10832
10833                        // Use existing process if already started
10834                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10835                        ProcessRecord proc = getProcessRecordLocked(
10836                                cpi.processName, cpr.appInfo.uid, false);
10837                        if (proc != null && proc.thread != null && !proc.killed) {
10838                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10839                                    "Installing in existing process " + proc);
10840                            if (!proc.pubProviders.containsKey(cpi.name)) {
10841                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10842                                proc.pubProviders.put(cpi.name, cpr);
10843                                try {
10844                                    proc.thread.scheduleInstallProvider(cpi);
10845                                } catch (RemoteException e) {
10846                                }
10847                            }
10848                        } else {
10849                            checkTime(startTime, "getContentProviderImpl: before start process");
10850                            proc = startProcessLocked(cpi.processName,
10851                                    cpr.appInfo, false, 0, "content provider",
10852                                    new ComponentName(cpi.applicationInfo.packageName,
10853                                            cpi.name), false, false, false);
10854                            checkTime(startTime, "getContentProviderImpl: after start process");
10855                            if (proc == null) {
10856                                Slog.w(TAG, "Unable to launch app "
10857                                        + cpi.applicationInfo.packageName + "/"
10858                                        + cpi.applicationInfo.uid + " for provider "
10859                                        + name + ": process is bad");
10860                                return null;
10861                            }
10862                        }
10863                        cpr.launchingApp = proc;
10864                        mLaunchingProviders.add(cpr);
10865                    } finally {
10866                        Binder.restoreCallingIdentity(origId);
10867                    }
10868                }
10869
10870                checkTime(startTime, "getContentProviderImpl: updating data structures");
10871
10872                // Make sure the provider is published (the same provider class
10873                // may be published under multiple names).
10874                if (firstClass) {
10875                    mProviderMap.putProviderByClass(comp, cpr);
10876                }
10877
10878                mProviderMap.putProviderByName(name, cpr);
10879                conn = incProviderCountLocked(r, cpr, token, stable);
10880                if (conn != null) {
10881                    conn.waiting = true;
10882                }
10883            }
10884            checkTime(startTime, "getContentProviderImpl: done!");
10885        }
10886
10887        // Wait for the provider to be published...
10888        synchronized (cpr) {
10889            while (cpr.provider == null) {
10890                if (cpr.launchingApp == null) {
10891                    Slog.w(TAG, "Unable to launch app "
10892                            + cpi.applicationInfo.packageName + "/"
10893                            + cpi.applicationInfo.uid + " for provider "
10894                            + name + ": launching app became null");
10895                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10896                            UserHandle.getUserId(cpi.applicationInfo.uid),
10897                            cpi.applicationInfo.packageName,
10898                            cpi.applicationInfo.uid, name);
10899                    return null;
10900                }
10901                try {
10902                    if (DEBUG_MU) Slog.v(TAG_MU,
10903                            "Waiting to start provider " + cpr
10904                            + " launchingApp=" + cpr.launchingApp);
10905                    if (conn != null) {
10906                        conn.waiting = true;
10907                    }
10908                    cpr.wait();
10909                } catch (InterruptedException ex) {
10910                } finally {
10911                    if (conn != null) {
10912                        conn.waiting = false;
10913                    }
10914                }
10915            }
10916        }
10917        return cpr != null ? cpr.newHolder(conn) : null;
10918    }
10919
10920    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10921            ProcessRecord r, final int userId) {
10922        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10923                cpi.packageName, userId)) {
10924
10925            final boolean callerForeground = r == null || r.setSchedGroup
10926                    != ProcessList.SCHED_GROUP_BACKGROUND;
10927
10928            // Show a permission review UI only for starting from a foreground app
10929            if (!callerForeground) {
10930                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10931                        + cpi.packageName + " requires a permissions review");
10932                return false;
10933            }
10934
10935            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10936            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10937                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10938            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10939
10940            if (DEBUG_PERMISSIONS_REVIEW) {
10941                Slog.i(TAG, "u" + userId + " Launching permission review "
10942                        + "for package " + cpi.packageName);
10943            }
10944
10945            final UserHandle userHandle = new UserHandle(userId);
10946            mHandler.post(new Runnable() {
10947                @Override
10948                public void run() {
10949                    mContext.startActivityAsUser(intent, userHandle);
10950                }
10951            });
10952
10953            return false;
10954        }
10955
10956        return true;
10957    }
10958
10959    PackageManagerInternal getPackageManagerInternalLocked() {
10960        if (mPackageManagerInt == null) {
10961            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10962        }
10963        return mPackageManagerInt;
10964    }
10965
10966    @Override
10967    public final ContentProviderHolder getContentProvider(
10968            IApplicationThread caller, String name, int userId, boolean stable) {
10969        enforceNotIsolatedCaller("getContentProvider");
10970        if (caller == null) {
10971            String msg = "null IApplicationThread when getting content provider "
10972                    + name;
10973            Slog.w(TAG, msg);
10974            throw new SecurityException(msg);
10975        }
10976        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10977        // with cross-user grant.
10978        return getContentProviderImpl(caller, name, null, stable, userId);
10979    }
10980
10981    public ContentProviderHolder getContentProviderExternal(
10982            String name, int userId, IBinder token) {
10983        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10984            "Do not have permission in call getContentProviderExternal()");
10985        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10986                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10987        return getContentProviderExternalUnchecked(name, token, userId);
10988    }
10989
10990    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10991            IBinder token, int userId) {
10992        return getContentProviderImpl(null, name, token, true, userId);
10993    }
10994
10995    /**
10996     * Drop a content provider from a ProcessRecord's bookkeeping
10997     */
10998    public void removeContentProvider(IBinder connection, boolean stable) {
10999        enforceNotIsolatedCaller("removeContentProvider");
11000        long ident = Binder.clearCallingIdentity();
11001        try {
11002            synchronized (this) {
11003                ContentProviderConnection conn;
11004                try {
11005                    conn = (ContentProviderConnection)connection;
11006                } catch (ClassCastException e) {
11007                    String msg ="removeContentProvider: " + connection
11008                            + " not a ContentProviderConnection";
11009                    Slog.w(TAG, msg);
11010                    throw new IllegalArgumentException(msg);
11011                }
11012                if (conn == null) {
11013                    throw new NullPointerException("connection is null");
11014                }
11015                if (decProviderCountLocked(conn, null, null, stable)) {
11016                    updateOomAdjLocked();
11017                }
11018            }
11019        } finally {
11020            Binder.restoreCallingIdentity(ident);
11021        }
11022    }
11023
11024    public void removeContentProviderExternal(String name, IBinder token) {
11025        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11026            "Do not have permission in call removeContentProviderExternal()");
11027        int userId = UserHandle.getCallingUserId();
11028        long ident = Binder.clearCallingIdentity();
11029        try {
11030            removeContentProviderExternalUnchecked(name, token, userId);
11031        } finally {
11032            Binder.restoreCallingIdentity(ident);
11033        }
11034    }
11035
11036    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11037        synchronized (this) {
11038            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11039            if(cpr == null) {
11040                //remove from mProvidersByClass
11041                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11042                return;
11043            }
11044
11045            //update content provider record entry info
11046            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11047            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11048            if (localCpr.hasExternalProcessHandles()) {
11049                if (localCpr.removeExternalProcessHandleLocked(token)) {
11050                    updateOomAdjLocked();
11051                } else {
11052                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11053                            + " with no external reference for token: "
11054                            + token + ".");
11055                }
11056            } else {
11057                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11058                        + " with no external references.");
11059            }
11060        }
11061    }
11062
11063    public final void publishContentProviders(IApplicationThread caller,
11064            List<ContentProviderHolder> providers) {
11065        if (providers == null) {
11066            return;
11067        }
11068
11069        enforceNotIsolatedCaller("publishContentProviders");
11070        synchronized (this) {
11071            final ProcessRecord r = getRecordForAppLocked(caller);
11072            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11073            if (r == null) {
11074                throw new SecurityException(
11075                        "Unable to find app for caller " + caller
11076                      + " (pid=" + Binder.getCallingPid()
11077                      + ") when publishing content providers");
11078            }
11079
11080            final long origId = Binder.clearCallingIdentity();
11081
11082            final int N = providers.size();
11083            for (int i = 0; i < N; i++) {
11084                ContentProviderHolder src = providers.get(i);
11085                if (src == null || src.info == null || src.provider == null) {
11086                    continue;
11087                }
11088                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11089                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11090                if (dst != null) {
11091                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11092                    mProviderMap.putProviderByClass(comp, dst);
11093                    String names[] = dst.info.authority.split(";");
11094                    for (int j = 0; j < names.length; j++) {
11095                        mProviderMap.putProviderByName(names[j], dst);
11096                    }
11097
11098                    int launchingCount = mLaunchingProviders.size();
11099                    int j;
11100                    boolean wasInLaunchingProviders = false;
11101                    for (j = 0; j < launchingCount; j++) {
11102                        if (mLaunchingProviders.get(j) == dst) {
11103                            mLaunchingProviders.remove(j);
11104                            wasInLaunchingProviders = true;
11105                            j--;
11106                            launchingCount--;
11107                        }
11108                    }
11109                    if (wasInLaunchingProviders) {
11110                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11111                    }
11112                    synchronized (dst) {
11113                        dst.provider = src.provider;
11114                        dst.proc = r;
11115                        dst.notifyAll();
11116                    }
11117                    updateOomAdjLocked(r);
11118                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11119                            src.info.authority);
11120                }
11121            }
11122
11123            Binder.restoreCallingIdentity(origId);
11124        }
11125    }
11126
11127    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11128        ContentProviderConnection conn;
11129        try {
11130            conn = (ContentProviderConnection)connection;
11131        } catch (ClassCastException e) {
11132            String msg ="refContentProvider: " + connection
11133                    + " not a ContentProviderConnection";
11134            Slog.w(TAG, msg);
11135            throw new IllegalArgumentException(msg);
11136        }
11137        if (conn == null) {
11138            throw new NullPointerException("connection is null");
11139        }
11140
11141        synchronized (this) {
11142            if (stable > 0) {
11143                conn.numStableIncs += stable;
11144            }
11145            stable = conn.stableCount + stable;
11146            if (stable < 0) {
11147                throw new IllegalStateException("stableCount < 0: " + stable);
11148            }
11149
11150            if (unstable > 0) {
11151                conn.numUnstableIncs += unstable;
11152            }
11153            unstable = conn.unstableCount + unstable;
11154            if (unstable < 0) {
11155                throw new IllegalStateException("unstableCount < 0: " + unstable);
11156            }
11157
11158            if ((stable+unstable) <= 0) {
11159                throw new IllegalStateException("ref counts can't go to zero here: stable="
11160                        + stable + " unstable=" + unstable);
11161            }
11162            conn.stableCount = stable;
11163            conn.unstableCount = unstable;
11164            return !conn.dead;
11165        }
11166    }
11167
11168    public void unstableProviderDied(IBinder connection) {
11169        ContentProviderConnection conn;
11170        try {
11171            conn = (ContentProviderConnection)connection;
11172        } catch (ClassCastException e) {
11173            String msg ="refContentProvider: " + connection
11174                    + " not a ContentProviderConnection";
11175            Slog.w(TAG, msg);
11176            throw new IllegalArgumentException(msg);
11177        }
11178        if (conn == null) {
11179            throw new NullPointerException("connection is null");
11180        }
11181
11182        // Safely retrieve the content provider associated with the connection.
11183        IContentProvider provider;
11184        synchronized (this) {
11185            provider = conn.provider.provider;
11186        }
11187
11188        if (provider == null) {
11189            // Um, yeah, we're way ahead of you.
11190            return;
11191        }
11192
11193        // Make sure the caller is being honest with us.
11194        if (provider.asBinder().pingBinder()) {
11195            // Er, no, still looks good to us.
11196            synchronized (this) {
11197                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11198                        + " says " + conn + " died, but we don't agree");
11199                return;
11200            }
11201        }
11202
11203        // Well look at that!  It's dead!
11204        synchronized (this) {
11205            if (conn.provider.provider != provider) {
11206                // But something changed...  good enough.
11207                return;
11208            }
11209
11210            ProcessRecord proc = conn.provider.proc;
11211            if (proc == null || proc.thread == null) {
11212                // Seems like the process is already cleaned up.
11213                return;
11214            }
11215
11216            // As far as we're concerned, this is just like receiving a
11217            // death notification...  just a bit prematurely.
11218            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11219                    + ") early provider death");
11220            final long ident = Binder.clearCallingIdentity();
11221            try {
11222                appDiedLocked(proc);
11223            } finally {
11224                Binder.restoreCallingIdentity(ident);
11225            }
11226        }
11227    }
11228
11229    @Override
11230    public void appNotRespondingViaProvider(IBinder connection) {
11231        enforceCallingPermission(
11232                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11233
11234        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11235        if (conn == null) {
11236            Slog.w(TAG, "ContentProviderConnection is null");
11237            return;
11238        }
11239
11240        final ProcessRecord host = conn.provider.proc;
11241        if (host == null) {
11242            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11243            return;
11244        }
11245
11246        mHandler.post(new Runnable() {
11247            @Override
11248            public void run() {
11249                mAppErrors.appNotResponding(host, null, null, false,
11250                        "ContentProvider not responding");
11251            }
11252        });
11253    }
11254
11255    public final void installSystemProviders() {
11256        List<ProviderInfo> providers;
11257        synchronized (this) {
11258            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11259            providers = generateApplicationProvidersLocked(app);
11260            if (providers != null) {
11261                for (int i=providers.size()-1; i>=0; i--) {
11262                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11263                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11264                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11265                                + ": not system .apk");
11266                        providers.remove(i);
11267                    }
11268                }
11269            }
11270        }
11271        if (providers != null) {
11272            mSystemThread.installSystemProviders(providers);
11273        }
11274
11275        mCoreSettingsObserver = new CoreSettingsObserver(this);
11276        mFontScaleSettingObserver = new FontScaleSettingObserver();
11277
11278        //mUsageStatsService.monitorPackages();
11279    }
11280
11281    private void startPersistentApps(int matchFlags) {
11282        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11283
11284        synchronized (this) {
11285            try {
11286                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11287                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11288                for (ApplicationInfo app : apps) {
11289                    if (!"android".equals(app.packageName)) {
11290                        addAppLocked(app, false, null /* ABI override */);
11291                    }
11292                }
11293            } catch (RemoteException ex) {
11294            }
11295        }
11296    }
11297
11298    /**
11299     * When a user is unlocked, we need to install encryption-unaware providers
11300     * belonging to any running apps.
11301     */
11302    private void installEncryptionUnawareProviders(int userId) {
11303        // We're only interested in providers that are encryption unaware, and
11304        // we don't care about uninstalled apps, since there's no way they're
11305        // running at this point.
11306        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11307
11308        synchronized (this) {
11309            final int NP = mProcessNames.getMap().size();
11310            for (int ip = 0; ip < NP; ip++) {
11311                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11312                final int NA = apps.size();
11313                for (int ia = 0; ia < NA; ia++) {
11314                    final ProcessRecord app = apps.valueAt(ia);
11315                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11316
11317                    final int NG = app.pkgList.size();
11318                    for (int ig = 0; ig < NG; ig++) {
11319                        try {
11320                            final String pkgName = app.pkgList.keyAt(ig);
11321                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11322                                    .getPackageInfo(pkgName, matchFlags, userId);
11323                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11324                                for (ProviderInfo pi : pkgInfo.providers) {
11325                                    // TODO: keep in sync with generateApplicationProvidersLocked
11326                                    final boolean processMatch = Objects.equals(pi.processName,
11327                                            app.processName) || pi.multiprocess;
11328                                    final boolean userMatch = isSingleton(pi.processName,
11329                                            pi.applicationInfo, pi.name, pi.flags)
11330                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11331                                    if (processMatch && userMatch) {
11332                                        Log.v(TAG, "Installing " + pi);
11333                                        app.thread.scheduleInstallProvider(pi);
11334                                    } else {
11335                                        Log.v(TAG, "Skipping " + pi);
11336                                    }
11337                                }
11338                            }
11339                        } catch (RemoteException ignored) {
11340                        }
11341                    }
11342                }
11343            }
11344        }
11345    }
11346
11347    /**
11348     * Allows apps to retrieve the MIME type of a URI.
11349     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11350     * users, then it does not need permission to access the ContentProvider.
11351     * Either, it needs cross-user uri grants.
11352     *
11353     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11354     *
11355     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11356     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11357     */
11358    public String getProviderMimeType(Uri uri, int userId) {
11359        enforceNotIsolatedCaller("getProviderMimeType");
11360        final String name = uri.getAuthority();
11361        int callingUid = Binder.getCallingUid();
11362        int callingPid = Binder.getCallingPid();
11363        long ident = 0;
11364        boolean clearedIdentity = false;
11365        synchronized (this) {
11366            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11367        }
11368        if (canClearIdentity(callingPid, callingUid, userId)) {
11369            clearedIdentity = true;
11370            ident = Binder.clearCallingIdentity();
11371        }
11372        ContentProviderHolder holder = null;
11373        try {
11374            holder = getContentProviderExternalUnchecked(name, null, userId);
11375            if (holder != null) {
11376                return holder.provider.getType(uri);
11377            }
11378        } catch (RemoteException e) {
11379            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11380            return null;
11381        } catch (Exception e) {
11382            Log.w(TAG, "Exception while determining type of " + uri, e);
11383            return null;
11384        } finally {
11385            // We need to clear the identity to call removeContentProviderExternalUnchecked
11386            if (!clearedIdentity) {
11387                ident = Binder.clearCallingIdentity();
11388            }
11389            try {
11390                if (holder != null) {
11391                    removeContentProviderExternalUnchecked(name, null, userId);
11392                }
11393            } finally {
11394                Binder.restoreCallingIdentity(ident);
11395            }
11396        }
11397
11398        return null;
11399    }
11400
11401    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11402        if (UserHandle.getUserId(callingUid) == userId) {
11403            return true;
11404        }
11405        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11406                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11407                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11408                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11409                return true;
11410        }
11411        return false;
11412    }
11413
11414    // =========================================================
11415    // GLOBAL MANAGEMENT
11416    // =========================================================
11417
11418    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11419            boolean isolated, int isolatedUid) {
11420        String proc = customProcess != null ? customProcess : info.processName;
11421        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11422        final int userId = UserHandle.getUserId(info.uid);
11423        int uid = info.uid;
11424        if (isolated) {
11425            if (isolatedUid == 0) {
11426                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11427                while (true) {
11428                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11429                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11430                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11431                    }
11432                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11433                    mNextIsolatedProcessUid++;
11434                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11435                        // No process for this uid, use it.
11436                        break;
11437                    }
11438                    stepsLeft--;
11439                    if (stepsLeft <= 0) {
11440                        return null;
11441                    }
11442                }
11443            } else {
11444                // Special case for startIsolatedProcess (internal only), where
11445                // the uid of the isolated process is specified by the caller.
11446                uid = isolatedUid;
11447            }
11448        }
11449        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11450        if (!mBooted && !mBooting
11451                && userId == UserHandle.USER_SYSTEM
11452                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11453            r.persistent = true;
11454            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11455        }
11456        addProcessNameLocked(r);
11457        return r;
11458    }
11459
11460    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11461            String abiOverride) {
11462        ProcessRecord app;
11463        if (!isolated) {
11464            app = getProcessRecordLocked(info.processName, info.uid, true);
11465        } else {
11466            app = null;
11467        }
11468
11469        if (app == null) {
11470            app = newProcessRecordLocked(info, null, isolated, 0);
11471            updateLruProcessLocked(app, false, null);
11472            updateOomAdjLocked();
11473        }
11474
11475        // This package really, really can not be stopped.
11476        try {
11477            AppGlobals.getPackageManager().setPackageStoppedState(
11478                    info.packageName, false, UserHandle.getUserId(app.uid));
11479        } catch (RemoteException e) {
11480        } catch (IllegalArgumentException e) {
11481            Slog.w(TAG, "Failed trying to unstop package "
11482                    + info.packageName + ": " + e);
11483        }
11484
11485        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11486            app.persistent = true;
11487            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11488        }
11489        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11490            mPersistentStartingProcesses.add(app);
11491            startProcessLocked(app, "added application", app.processName, abiOverride,
11492                    null /* entryPoint */, null /* entryPointArgs */);
11493        }
11494
11495        return app;
11496    }
11497
11498    public void unhandledBack() {
11499        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11500                "unhandledBack()");
11501
11502        synchronized(this) {
11503            final long origId = Binder.clearCallingIdentity();
11504            try {
11505                getFocusedStack().unhandledBackLocked();
11506            } finally {
11507                Binder.restoreCallingIdentity(origId);
11508            }
11509        }
11510    }
11511
11512    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11513        enforceNotIsolatedCaller("openContentUri");
11514        final int userId = UserHandle.getCallingUserId();
11515        String name = uri.getAuthority();
11516        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11517        ParcelFileDescriptor pfd = null;
11518        if (cph != null) {
11519            // We record the binder invoker's uid in thread-local storage before
11520            // going to the content provider to open the file.  Later, in the code
11521            // that handles all permissions checks, we look for this uid and use
11522            // that rather than the Activity Manager's own uid.  The effect is that
11523            // we do the check against the caller's permissions even though it looks
11524            // to the content provider like the Activity Manager itself is making
11525            // the request.
11526            Binder token = new Binder();
11527            sCallerIdentity.set(new Identity(
11528                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11529            try {
11530                pfd = cph.provider.openFile(null, uri, "r", null, token);
11531            } catch (FileNotFoundException e) {
11532                // do nothing; pfd will be returned null
11533            } finally {
11534                // Ensure that whatever happens, we clean up the identity state
11535                sCallerIdentity.remove();
11536                // Ensure we're done with the provider.
11537                removeContentProviderExternalUnchecked(name, null, userId);
11538            }
11539        } else {
11540            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11541        }
11542        return pfd;
11543    }
11544
11545    // Actually is sleeping or shutting down or whatever else in the future
11546    // is an inactive state.
11547    boolean isSleepingOrShuttingDownLocked() {
11548        return isSleepingLocked() || mShuttingDown;
11549    }
11550
11551    boolean isShuttingDownLocked() {
11552        return mShuttingDown;
11553    }
11554
11555    boolean isSleepingLocked() {
11556        return mSleeping;
11557    }
11558
11559    void onWakefulnessChanged(int wakefulness) {
11560        synchronized(this) {
11561            mWakefulness = wakefulness;
11562            updateSleepIfNeededLocked();
11563        }
11564    }
11565
11566    void finishRunningVoiceLocked() {
11567        if (mRunningVoice != null) {
11568            mRunningVoice = null;
11569            mVoiceWakeLock.release();
11570            updateSleepIfNeededLocked();
11571        }
11572    }
11573
11574    void startTimeTrackingFocusedActivityLocked() {
11575        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11576            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11577        }
11578    }
11579
11580    void updateSleepIfNeededLocked() {
11581        if (mSleeping && !shouldSleepLocked()) {
11582            mSleeping = false;
11583            startTimeTrackingFocusedActivityLocked();
11584            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11585            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11586            updateOomAdjLocked();
11587        } else if (!mSleeping && shouldSleepLocked()) {
11588            mSleeping = true;
11589            if (mCurAppTimeTracker != null) {
11590                mCurAppTimeTracker.stop();
11591            }
11592            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11593            mStackSupervisor.goingToSleepLocked();
11594            updateOomAdjLocked();
11595
11596            // Initialize the wake times of all processes.
11597            checkExcessivePowerUsageLocked(false);
11598            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11599            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11600            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11601        }
11602    }
11603
11604    private boolean shouldSleepLocked() {
11605        // Resume applications while running a voice interactor.
11606        if (mRunningVoice != null) {
11607            return false;
11608        }
11609
11610        // TODO: Transform the lock screen state into a sleep token instead.
11611        switch (mWakefulness) {
11612            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11613            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11614            case PowerManagerInternal.WAKEFULNESS_DOZING:
11615                // Pause applications whenever the lock screen is shown or any sleep
11616                // tokens have been acquired.
11617                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11618            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11619            default:
11620                // If we're asleep then pause applications unconditionally.
11621                return true;
11622        }
11623    }
11624
11625    /** Pokes the task persister. */
11626    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11627        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11628    }
11629
11630    /** Notifies all listeners when the task stack has changed. */
11631    void notifyTaskStackChangedLocked() {
11632        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11633        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11634        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11635        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11636    }
11637
11638    /** Notifies all listeners when an Activity is pinned. */
11639    void notifyActivityPinnedLocked() {
11640        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11641        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11642    }
11643
11644    /**
11645     * Notifies all listeners when an attempt was made to start an an activity that is already
11646     * running in the pinned stack and the activity was not actually started, but the task is
11647     * either brought to the front or a new Intent is delivered to it.
11648     */
11649    void notifyPinnedActivityRestartAttemptLocked() {
11650        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11651        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11652    }
11653
11654    /** Notifies all listeners when the pinned stack animation ends. */
11655    @Override
11656    public void notifyPinnedStackAnimationEnded() {
11657        synchronized (this) {
11658            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11659            mHandler.obtainMessage(
11660                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11661        }
11662    }
11663
11664    @Override
11665    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11666        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11667    }
11668
11669    @Override
11670    public boolean shutdown(int timeout) {
11671        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11672                != PackageManager.PERMISSION_GRANTED) {
11673            throw new SecurityException("Requires permission "
11674                    + android.Manifest.permission.SHUTDOWN);
11675        }
11676
11677        boolean timedout = false;
11678
11679        synchronized(this) {
11680            mShuttingDown = true;
11681            updateEventDispatchingLocked();
11682            timedout = mStackSupervisor.shutdownLocked(timeout);
11683        }
11684
11685        mAppOpsService.shutdown();
11686        if (mUsageStatsService != null) {
11687            mUsageStatsService.prepareShutdown();
11688        }
11689        mBatteryStatsService.shutdown();
11690        synchronized (this) {
11691            mProcessStats.shutdownLocked();
11692            notifyTaskPersisterLocked(null, true);
11693        }
11694
11695        return timedout;
11696    }
11697
11698    public final void activitySlept(IBinder token) {
11699        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11700
11701        final long origId = Binder.clearCallingIdentity();
11702
11703        synchronized (this) {
11704            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11705            if (r != null) {
11706                mStackSupervisor.activitySleptLocked(r);
11707            }
11708        }
11709
11710        Binder.restoreCallingIdentity(origId);
11711    }
11712
11713    private String lockScreenShownToString() {
11714        switch (mLockScreenShown) {
11715            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11716            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11717            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11718            default: return "Unknown=" + mLockScreenShown;
11719        }
11720    }
11721
11722    void logLockScreen(String msg) {
11723        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11724                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11725                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11726                + " mSleeping=" + mSleeping);
11727    }
11728
11729    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11730        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11731        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11732        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11733            boolean wasRunningVoice = mRunningVoice != null;
11734            mRunningVoice = session;
11735            if (!wasRunningVoice) {
11736                mVoiceWakeLock.acquire();
11737                updateSleepIfNeededLocked();
11738            }
11739        }
11740    }
11741
11742    private void updateEventDispatchingLocked() {
11743        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11744    }
11745
11746    public void setLockScreenShown(boolean showing, boolean occluded) {
11747        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11748                != PackageManager.PERMISSION_GRANTED) {
11749            throw new SecurityException("Requires permission "
11750                    + android.Manifest.permission.DEVICE_POWER);
11751        }
11752
11753        synchronized(this) {
11754            long ident = Binder.clearCallingIdentity();
11755            try {
11756                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11757                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11758                if (showing && occluded) {
11759                    // The lock screen is currently showing, but is occluded by a window that can
11760                    // show on top of the lock screen. In this can we want to dismiss the docked
11761                    // stack since it will be complicated/risky to try to put the activity on top
11762                    // of the lock screen in the right fullscreen configuration.
11763                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11764                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11765                }
11766
11767                updateSleepIfNeededLocked();
11768            } finally {
11769                Binder.restoreCallingIdentity(ident);
11770            }
11771        }
11772    }
11773
11774    @Override
11775    public void notifyLockedProfile(@UserIdInt int userId) {
11776        try {
11777            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11778                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11779            }
11780        } catch (RemoteException ex) {
11781            throw new SecurityException("Fail to check is caller a privileged app", ex);
11782        }
11783
11784        synchronized (this) {
11785            if (mStackSupervisor.isUserLockedProfile(userId)) {
11786                final long ident = Binder.clearCallingIdentity();
11787                try {
11788                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11789                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11790                        // If there is no device lock, we will show the profile's credential page.
11791                        mActivityStarter.showConfirmDeviceCredential(userId);
11792                    } else {
11793                        // Showing launcher to avoid user entering credential twice.
11794                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11795                    }
11796                } finally {
11797                    Binder.restoreCallingIdentity(ident);
11798                }
11799            }
11800        }
11801    }
11802
11803    @Override
11804    public void startConfirmDeviceCredentialIntent(Intent intent) {
11805        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11806        synchronized (this) {
11807            final long ident = Binder.clearCallingIdentity();
11808            try {
11809                mActivityStarter.startConfirmCredentialIntent(intent);
11810            } finally {
11811                Binder.restoreCallingIdentity(ident);
11812            }
11813        }
11814    }
11815
11816    @Override
11817    public void stopAppSwitches() {
11818        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11819                != PackageManager.PERMISSION_GRANTED) {
11820            throw new SecurityException("viewquires permission "
11821                    + android.Manifest.permission.STOP_APP_SWITCHES);
11822        }
11823
11824        synchronized(this) {
11825            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11826                    + APP_SWITCH_DELAY_TIME;
11827            mDidAppSwitch = false;
11828            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11829            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11830            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11831        }
11832    }
11833
11834    public void resumeAppSwitches() {
11835        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11836                != PackageManager.PERMISSION_GRANTED) {
11837            throw new SecurityException("Requires permission "
11838                    + android.Manifest.permission.STOP_APP_SWITCHES);
11839        }
11840
11841        synchronized(this) {
11842            // Note that we don't execute any pending app switches... we will
11843            // let those wait until either the timeout, or the next start
11844            // activity request.
11845            mAppSwitchesAllowedTime = 0;
11846        }
11847    }
11848
11849    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11850            int callingPid, int callingUid, String name) {
11851        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11852            return true;
11853        }
11854
11855        int perm = checkComponentPermission(
11856                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11857                sourceUid, -1, true);
11858        if (perm == PackageManager.PERMISSION_GRANTED) {
11859            return true;
11860        }
11861
11862        // If the actual IPC caller is different from the logical source, then
11863        // also see if they are allowed to control app switches.
11864        if (callingUid != -1 && callingUid != sourceUid) {
11865            perm = checkComponentPermission(
11866                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11867                    callingUid, -1, true);
11868            if (perm == PackageManager.PERMISSION_GRANTED) {
11869                return true;
11870            }
11871        }
11872
11873        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11874        return false;
11875    }
11876
11877    public void setDebugApp(String packageName, boolean waitForDebugger,
11878            boolean persistent) {
11879        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11880                "setDebugApp()");
11881
11882        long ident = Binder.clearCallingIdentity();
11883        try {
11884            // Note that this is not really thread safe if there are multiple
11885            // callers into it at the same time, but that's not a situation we
11886            // care about.
11887            if (persistent) {
11888                final ContentResolver resolver = mContext.getContentResolver();
11889                Settings.Global.putString(
11890                    resolver, Settings.Global.DEBUG_APP,
11891                    packageName);
11892                Settings.Global.putInt(
11893                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11894                    waitForDebugger ? 1 : 0);
11895            }
11896
11897            synchronized (this) {
11898                if (!persistent) {
11899                    mOrigDebugApp = mDebugApp;
11900                    mOrigWaitForDebugger = mWaitForDebugger;
11901                }
11902                mDebugApp = packageName;
11903                mWaitForDebugger = waitForDebugger;
11904                mDebugTransient = !persistent;
11905                if (packageName != null) {
11906                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11907                            false, UserHandle.USER_ALL, "set debug app");
11908                }
11909            }
11910        } finally {
11911            Binder.restoreCallingIdentity(ident);
11912        }
11913    }
11914
11915    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11916        synchronized (this) {
11917            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11918            if (!isDebuggable) {
11919                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11920                    throw new SecurityException("Process not debuggable: " + app.packageName);
11921                }
11922            }
11923
11924            mTrackAllocationApp = processName;
11925        }
11926    }
11927
11928    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11929        synchronized (this) {
11930            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11931            if (!isDebuggable) {
11932                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11933                    throw new SecurityException("Process not debuggable: " + app.packageName);
11934                }
11935            }
11936            mProfileApp = processName;
11937            mProfileFile = profilerInfo.profileFile;
11938            if (mProfileFd != null) {
11939                try {
11940                    mProfileFd.close();
11941                } catch (IOException e) {
11942                }
11943                mProfileFd = null;
11944            }
11945            mProfileFd = profilerInfo.profileFd;
11946            mSamplingInterval = profilerInfo.samplingInterval;
11947            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11948            mProfileType = 0;
11949        }
11950    }
11951
11952    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11953        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11954        if (!isDebuggable) {
11955            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11956                throw new SecurityException("Process not debuggable: " + app.packageName);
11957            }
11958        }
11959        mNativeDebuggingApp = processName;
11960    }
11961
11962    @Override
11963    public void setAlwaysFinish(boolean enabled) {
11964        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11965                "setAlwaysFinish()");
11966
11967        long ident = Binder.clearCallingIdentity();
11968        try {
11969            Settings.Global.putInt(
11970                    mContext.getContentResolver(),
11971                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11972
11973            synchronized (this) {
11974                mAlwaysFinishActivities = enabled;
11975            }
11976        } finally {
11977            Binder.restoreCallingIdentity(ident);
11978        }
11979    }
11980
11981    @Override
11982    public void setLenientBackgroundCheck(boolean enabled) {
11983        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11984                "setLenientBackgroundCheck()");
11985
11986        long ident = Binder.clearCallingIdentity();
11987        try {
11988            Settings.Global.putInt(
11989                    mContext.getContentResolver(),
11990                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11991
11992            synchronized (this) {
11993                mLenientBackgroundCheck = enabled;
11994            }
11995        } finally {
11996            Binder.restoreCallingIdentity(ident);
11997        }
11998    }
11999
12000    @Override
12001    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12002        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12003                "setActivityController()");
12004        synchronized (this) {
12005            mController = controller;
12006            mControllerIsAMonkey = imAMonkey;
12007            Watchdog.getInstance().setActivityController(controller);
12008        }
12009    }
12010
12011    @Override
12012    public void setUserIsMonkey(boolean userIsMonkey) {
12013        synchronized (this) {
12014            synchronized (mPidsSelfLocked) {
12015                final int callingPid = Binder.getCallingPid();
12016                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12017                if (precessRecord == null) {
12018                    throw new SecurityException("Unknown process: " + callingPid);
12019                }
12020                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12021                    throw new SecurityException("Only an instrumentation process "
12022                            + "with a UiAutomation can call setUserIsMonkey");
12023                }
12024            }
12025            mUserIsMonkey = userIsMonkey;
12026        }
12027    }
12028
12029    @Override
12030    public boolean isUserAMonkey() {
12031        synchronized (this) {
12032            // If there is a controller also implies the user is a monkey.
12033            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12034        }
12035    }
12036
12037    public void requestBugReport(int bugreportType) {
12038        String service = null;
12039        switch (bugreportType) {
12040            case ActivityManager.BUGREPORT_OPTION_FULL:
12041                service = "bugreport";
12042                break;
12043            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12044                service = "bugreportplus";
12045                break;
12046            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12047                service = "bugreportremote";
12048                break;
12049        }
12050        if (service == null) {
12051            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12052                    + bugreportType);
12053        }
12054        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12055        SystemProperties.set("ctl.start", service);
12056    }
12057
12058    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12059        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12060    }
12061
12062    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12063        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12064            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12065        }
12066        return KEY_DISPATCHING_TIMEOUT;
12067    }
12068
12069    @Override
12070    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12071        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12072                != PackageManager.PERMISSION_GRANTED) {
12073            throw new SecurityException("Requires permission "
12074                    + android.Manifest.permission.FILTER_EVENTS);
12075        }
12076        ProcessRecord proc;
12077        long timeout;
12078        synchronized (this) {
12079            synchronized (mPidsSelfLocked) {
12080                proc = mPidsSelfLocked.get(pid);
12081            }
12082            timeout = getInputDispatchingTimeoutLocked(proc);
12083        }
12084
12085        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12086            return -1;
12087        }
12088
12089        return timeout;
12090    }
12091
12092    /**
12093     * Handle input dispatching timeouts.
12094     * Returns whether input dispatching should be aborted or not.
12095     */
12096    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12097            final ActivityRecord activity, final ActivityRecord parent,
12098            final boolean aboveSystem, String reason) {
12099        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12100                != PackageManager.PERMISSION_GRANTED) {
12101            throw new SecurityException("Requires permission "
12102                    + android.Manifest.permission.FILTER_EVENTS);
12103        }
12104
12105        final String annotation;
12106        if (reason == null) {
12107            annotation = "Input dispatching timed out";
12108        } else {
12109            annotation = "Input dispatching timed out (" + reason + ")";
12110        }
12111
12112        if (proc != null) {
12113            synchronized (this) {
12114                if (proc.debugging) {
12115                    return false;
12116                }
12117
12118                if (mDidDexOpt) {
12119                    // Give more time since we were dexopting.
12120                    mDidDexOpt = false;
12121                    return false;
12122                }
12123
12124                if (proc.instrumentationClass != null) {
12125                    Bundle info = new Bundle();
12126                    info.putString("shortMsg", "keyDispatchingTimedOut");
12127                    info.putString("longMsg", annotation);
12128                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12129                    return true;
12130                }
12131            }
12132            mHandler.post(new Runnable() {
12133                @Override
12134                public void run() {
12135                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12136                }
12137            });
12138        }
12139
12140        return true;
12141    }
12142
12143    @Override
12144    public Bundle getAssistContextExtras(int requestType) {
12145        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12146                null, null, true /* focused */, true /* newSessionId */,
12147                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12148        if (pae == null) {
12149            return null;
12150        }
12151        synchronized (pae) {
12152            while (!pae.haveResult) {
12153                try {
12154                    pae.wait();
12155                } catch (InterruptedException e) {
12156                }
12157            }
12158        }
12159        synchronized (this) {
12160            buildAssistBundleLocked(pae, pae.result);
12161            mPendingAssistExtras.remove(pae);
12162            mUiHandler.removeCallbacks(pae);
12163        }
12164        return pae.extras;
12165    }
12166
12167    @Override
12168    public boolean isAssistDataAllowedOnCurrentActivity() {
12169        int userId;
12170        synchronized (this) {
12171            userId = mUserController.getCurrentUserIdLocked();
12172            ActivityRecord activity = getFocusedStack().topActivity();
12173            if (activity == null) {
12174                return false;
12175            }
12176            userId = activity.userId;
12177        }
12178        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12179                Context.DEVICE_POLICY_SERVICE);
12180        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12181    }
12182
12183    @Override
12184    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12185        long ident = Binder.clearCallingIdentity();
12186        try {
12187            synchronized (this) {
12188                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12189                ActivityRecord top = getFocusedStack().topActivity();
12190                if (top != caller) {
12191                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12192                            + " is not current top " + top);
12193                    return false;
12194                }
12195                if (!top.nowVisible) {
12196                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12197                            + " is not visible");
12198                    return false;
12199                }
12200            }
12201            AssistUtils utils = new AssistUtils(mContext);
12202            return utils.showSessionForActiveService(args,
12203                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12204        } finally {
12205            Binder.restoreCallingIdentity(ident);
12206        }
12207    }
12208
12209    @Override
12210    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12211            Bundle receiverExtras,
12212            IBinder activityToken, boolean focused, boolean newSessionId) {
12213        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12214                activityToken, focused, newSessionId,
12215                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12216                != null;
12217    }
12218
12219    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12220            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12221            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12222        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12223                "enqueueAssistContext()");
12224        synchronized (this) {
12225            ActivityRecord activity = getFocusedStack().topActivity();
12226            if (activity == null) {
12227                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12228                return null;
12229            }
12230            if (activity.app == null || activity.app.thread == null) {
12231                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12232                return null;
12233            }
12234            if (focused) {
12235                if (activityToken != null) {
12236                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12237                    if (activity != caller) {
12238                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12239                                + " is not current top " + activity);
12240                        return null;
12241                    }
12242                }
12243            } else {
12244                activity = ActivityRecord.forTokenLocked(activityToken);
12245                if (activity == null) {
12246                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12247                            + " couldn't be found");
12248                    return null;
12249                }
12250            }
12251
12252            PendingAssistExtras pae;
12253            Bundle extras = new Bundle();
12254            if (args != null) {
12255                extras.putAll(args);
12256            }
12257            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12258            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12259            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12260                    userHandle);
12261            // Increment the sessionId if necessary
12262            if (newSessionId) {
12263                mViSessionId++;
12264            }
12265            try {
12266                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12267                        requestType, mViSessionId);
12268                mPendingAssistExtras.add(pae);
12269                mUiHandler.postDelayed(pae, timeout);
12270            } catch (RemoteException e) {
12271                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12272                return null;
12273            }
12274            return pae;
12275        }
12276    }
12277
12278    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12279        IResultReceiver receiver;
12280        synchronized (this) {
12281            mPendingAssistExtras.remove(pae);
12282            receiver = pae.receiver;
12283        }
12284        if (receiver != null) {
12285            // Caller wants result sent back to them.
12286            Bundle sendBundle = new Bundle();
12287            // At least return the receiver extras
12288            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12289                    pae.receiverExtras);
12290            try {
12291                pae.receiver.send(0, sendBundle);
12292            } catch (RemoteException e) {
12293            }
12294        }
12295    }
12296
12297    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12298        if (result != null) {
12299            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12300        }
12301        if (pae.hint != null) {
12302            pae.extras.putBoolean(pae.hint, true);
12303        }
12304    }
12305
12306    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12307            AssistContent content, Uri referrer) {
12308        PendingAssistExtras pae = (PendingAssistExtras)token;
12309        synchronized (pae) {
12310            pae.result = extras;
12311            pae.structure = structure;
12312            pae.content = content;
12313            if (referrer != null) {
12314                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12315            }
12316            pae.haveResult = true;
12317            pae.notifyAll();
12318            if (pae.intent == null && pae.receiver == null) {
12319                // Caller is just waiting for the result.
12320                return;
12321            }
12322        }
12323
12324        // We are now ready to launch the assist activity.
12325        IResultReceiver sendReceiver = null;
12326        Bundle sendBundle = null;
12327        synchronized (this) {
12328            buildAssistBundleLocked(pae, extras);
12329            boolean exists = mPendingAssistExtras.remove(pae);
12330            mUiHandler.removeCallbacks(pae);
12331            if (!exists) {
12332                // Timed out.
12333                return;
12334            }
12335            if ((sendReceiver=pae.receiver) != null) {
12336                // Caller wants result sent back to them.
12337                sendBundle = new Bundle();
12338                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12339                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12340                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12341                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12342                        pae.receiverExtras);
12343            }
12344        }
12345        if (sendReceiver != null) {
12346            try {
12347                sendReceiver.send(0, sendBundle);
12348            } catch (RemoteException e) {
12349            }
12350            return;
12351        }
12352
12353        long ident = Binder.clearCallingIdentity();
12354        try {
12355            pae.intent.replaceExtras(pae.extras);
12356            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12357                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12358                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12359            closeSystemDialogs("assist");
12360            try {
12361                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12362            } catch (ActivityNotFoundException e) {
12363                Slog.w(TAG, "No activity to handle assist action.", e);
12364            }
12365        } finally {
12366            Binder.restoreCallingIdentity(ident);
12367        }
12368    }
12369
12370    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12371            Bundle args) {
12372        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12373                true /* focused */, true /* newSessionId */,
12374                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12375    }
12376
12377    public void registerProcessObserver(IProcessObserver observer) {
12378        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12379                "registerProcessObserver()");
12380        synchronized (this) {
12381            mProcessObservers.register(observer);
12382        }
12383    }
12384
12385    @Override
12386    public void unregisterProcessObserver(IProcessObserver observer) {
12387        synchronized (this) {
12388            mProcessObservers.unregister(observer);
12389        }
12390    }
12391
12392    @Override
12393    public void registerUidObserver(IUidObserver observer, int which) {
12394        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12395                "registerUidObserver()");
12396        synchronized (this) {
12397            mUidObservers.register(observer, which);
12398        }
12399    }
12400
12401    @Override
12402    public void unregisterUidObserver(IUidObserver observer) {
12403        synchronized (this) {
12404            mUidObservers.unregister(observer);
12405        }
12406    }
12407
12408    @Override
12409    public boolean convertFromTranslucent(IBinder token) {
12410        final long origId = Binder.clearCallingIdentity();
12411        try {
12412            synchronized (this) {
12413                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12414                if (r == null) {
12415                    return false;
12416                }
12417                final boolean translucentChanged = r.changeWindowTranslucency(true);
12418                if (translucentChanged) {
12419                    r.task.stack.releaseBackgroundResources(r);
12420                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12421                }
12422                mWindowManager.setAppFullscreen(token, true);
12423                return translucentChanged;
12424            }
12425        } finally {
12426            Binder.restoreCallingIdentity(origId);
12427        }
12428    }
12429
12430    @Override
12431    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12432        final long origId = Binder.clearCallingIdentity();
12433        try {
12434            synchronized (this) {
12435                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12436                if (r == null) {
12437                    return false;
12438                }
12439                int index = r.task.mActivities.lastIndexOf(r);
12440                if (index > 0) {
12441                    ActivityRecord under = r.task.mActivities.get(index - 1);
12442                    under.returningOptions = options;
12443                }
12444                final boolean translucentChanged = r.changeWindowTranslucency(false);
12445                if (translucentChanged) {
12446                    r.task.stack.convertActivityToTranslucent(r);
12447                }
12448                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12449                mWindowManager.setAppFullscreen(token, false);
12450                return translucentChanged;
12451            }
12452        } finally {
12453            Binder.restoreCallingIdentity(origId);
12454        }
12455    }
12456
12457    @Override
12458    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12459        final long origId = Binder.clearCallingIdentity();
12460        try {
12461            synchronized (this) {
12462                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12463                if (r != null) {
12464                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12465                }
12466            }
12467            return false;
12468        } finally {
12469            Binder.restoreCallingIdentity(origId);
12470        }
12471    }
12472
12473    @Override
12474    public boolean isBackgroundVisibleBehind(IBinder token) {
12475        final long origId = Binder.clearCallingIdentity();
12476        try {
12477            synchronized (this) {
12478                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12479                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12480                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12481                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12482                return visible;
12483            }
12484        } finally {
12485            Binder.restoreCallingIdentity(origId);
12486        }
12487    }
12488
12489    @Override
12490    public ActivityOptions getActivityOptions(IBinder token) {
12491        final long origId = Binder.clearCallingIdentity();
12492        try {
12493            synchronized (this) {
12494                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12495                if (r != null) {
12496                    final ActivityOptions activityOptions = r.pendingOptions;
12497                    r.pendingOptions = null;
12498                    return activityOptions;
12499                }
12500                return null;
12501            }
12502        } finally {
12503            Binder.restoreCallingIdentity(origId);
12504        }
12505    }
12506
12507    @Override
12508    public void setImmersive(IBinder token, boolean immersive) {
12509        synchronized(this) {
12510            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12511            if (r == null) {
12512                throw new IllegalArgumentException();
12513            }
12514            r.immersive = immersive;
12515
12516            // update associated state if we're frontmost
12517            if (r == mFocusedActivity) {
12518                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12519                applyUpdateLockStateLocked(r);
12520            }
12521        }
12522    }
12523
12524    @Override
12525    public boolean isImmersive(IBinder token) {
12526        synchronized (this) {
12527            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12528            if (r == null) {
12529                throw new IllegalArgumentException();
12530            }
12531            return r.immersive;
12532        }
12533    }
12534
12535    @Override
12536    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12537        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12538            throw new UnsupportedOperationException("VR mode not supported on this device!");
12539        }
12540
12541        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12542
12543        ActivityRecord r;
12544        synchronized (this) {
12545            r = ActivityRecord.isInStackLocked(token);
12546        }
12547
12548        if (r == null) {
12549            throw new IllegalArgumentException();
12550        }
12551
12552        int err;
12553        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12554                VrManagerInternal.NO_ERROR) {
12555            return err;
12556        }
12557
12558        synchronized(this) {
12559            r.requestedVrComponent = (enabled) ? packageName : null;
12560
12561            // Update associated state if this activity is currently focused
12562            if (r == mFocusedActivity) {
12563                applyUpdateVrModeLocked(r);
12564            }
12565            return 0;
12566        }
12567    }
12568
12569    @Override
12570    public boolean isVrModePackageEnabled(ComponentName packageName) {
12571        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12572            throw new UnsupportedOperationException("VR mode not supported on this device!");
12573        }
12574
12575        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12576
12577        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12578                VrManagerInternal.NO_ERROR;
12579    }
12580
12581    public boolean isTopActivityImmersive() {
12582        enforceNotIsolatedCaller("startActivity");
12583        synchronized (this) {
12584            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12585            return (r != null) ? r.immersive : false;
12586        }
12587    }
12588
12589    @Override
12590    public boolean isTopOfTask(IBinder token) {
12591        synchronized (this) {
12592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12593            if (r == null) {
12594                throw new IllegalArgumentException();
12595            }
12596            return r.task.getTopActivity() == r;
12597        }
12598    }
12599
12600    public final void enterSafeMode() {
12601        synchronized(this) {
12602            // It only makes sense to do this before the system is ready
12603            // and started launching other packages.
12604            if (!mSystemReady) {
12605                try {
12606                    AppGlobals.getPackageManager().enterSafeMode();
12607                } catch (RemoteException e) {
12608                }
12609            }
12610
12611            mSafeMode = true;
12612        }
12613    }
12614
12615    public final void showSafeModeOverlay() {
12616        View v = LayoutInflater.from(mContext).inflate(
12617                com.android.internal.R.layout.safe_mode, null);
12618        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12619        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12620        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12621        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12622        lp.gravity = Gravity.BOTTOM | Gravity.START;
12623        lp.format = v.getBackground().getOpacity();
12624        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12625                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12626        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12627        ((WindowManager)mContext.getSystemService(
12628                Context.WINDOW_SERVICE)).addView(v, lp);
12629    }
12630
12631    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12632        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12633            return;
12634        }
12635        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12636        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12637        synchronized (stats) {
12638            if (mBatteryStatsService.isOnBattery()) {
12639                mBatteryStatsService.enforceCallingPermission();
12640                int MY_UID = Binder.getCallingUid();
12641                final int uid;
12642                if (sender == null) {
12643                    uid = sourceUid;
12644                } else {
12645                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12646                }
12647                BatteryStatsImpl.Uid.Pkg pkg =
12648                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12649                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12650                pkg.noteWakeupAlarmLocked(tag);
12651            }
12652        }
12653    }
12654
12655    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12656        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12657            return;
12658        }
12659        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12660        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12661        synchronized (stats) {
12662            mBatteryStatsService.enforceCallingPermission();
12663            int MY_UID = Binder.getCallingUid();
12664            final int uid;
12665            if (sender == null) {
12666                uid = sourceUid;
12667            } else {
12668                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12669            }
12670            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12671        }
12672    }
12673
12674    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12675        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12676            return;
12677        }
12678        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12679        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12680        synchronized (stats) {
12681            mBatteryStatsService.enforceCallingPermission();
12682            int MY_UID = Binder.getCallingUid();
12683            final int uid;
12684            if (sender == null) {
12685                uid = sourceUid;
12686            } else {
12687                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12688            }
12689            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12690        }
12691    }
12692
12693    public boolean killPids(int[] pids, String pReason, boolean secure) {
12694        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12695            throw new SecurityException("killPids only available to the system");
12696        }
12697        String reason = (pReason == null) ? "Unknown" : pReason;
12698        // XXX Note: don't acquire main activity lock here, because the window
12699        // manager calls in with its locks held.
12700
12701        boolean killed = false;
12702        synchronized (mPidsSelfLocked) {
12703            int worstType = 0;
12704            for (int i=0; i<pids.length; i++) {
12705                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12706                if (proc != null) {
12707                    int type = proc.setAdj;
12708                    if (type > worstType) {
12709                        worstType = type;
12710                    }
12711                }
12712            }
12713
12714            // If the worst oom_adj is somewhere in the cached proc LRU range,
12715            // then constrain it so we will kill all cached procs.
12716            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12717                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12718                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12719            }
12720
12721            // If this is not a secure call, don't let it kill processes that
12722            // are important.
12723            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12724                worstType = ProcessList.SERVICE_ADJ;
12725            }
12726
12727            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12728            for (int i=0; i<pids.length; i++) {
12729                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12730                if (proc == null) {
12731                    continue;
12732                }
12733                int adj = proc.setAdj;
12734                if (adj >= worstType && !proc.killedByAm) {
12735                    proc.kill(reason, true);
12736                    killed = true;
12737                }
12738            }
12739        }
12740        return killed;
12741    }
12742
12743    @Override
12744    public void killUid(int appId, int userId, String reason) {
12745        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12746        synchronized (this) {
12747            final long identity = Binder.clearCallingIdentity();
12748            try {
12749                killPackageProcessesLocked(null, appId, userId,
12750                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12751                        reason != null ? reason : "kill uid");
12752            } finally {
12753                Binder.restoreCallingIdentity(identity);
12754            }
12755        }
12756    }
12757
12758    @Override
12759    public boolean killProcessesBelowForeground(String reason) {
12760        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12761            throw new SecurityException("killProcessesBelowForeground() only available to system");
12762        }
12763
12764        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12765    }
12766
12767    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12768        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12769            throw new SecurityException("killProcessesBelowAdj() only available to system");
12770        }
12771
12772        boolean killed = false;
12773        synchronized (mPidsSelfLocked) {
12774            final int size = mPidsSelfLocked.size();
12775            for (int i = 0; i < size; i++) {
12776                final int pid = mPidsSelfLocked.keyAt(i);
12777                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12778                if (proc == null) continue;
12779
12780                final int adj = proc.setAdj;
12781                if (adj > belowAdj && !proc.killedByAm) {
12782                    proc.kill(reason, true);
12783                    killed = true;
12784                }
12785            }
12786        }
12787        return killed;
12788    }
12789
12790    @Override
12791    public void hang(final IBinder who, boolean allowRestart) {
12792        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12793                != PackageManager.PERMISSION_GRANTED) {
12794            throw new SecurityException("Requires permission "
12795                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12796        }
12797
12798        final IBinder.DeathRecipient death = new DeathRecipient() {
12799            @Override
12800            public void binderDied() {
12801                synchronized (this) {
12802                    notifyAll();
12803                }
12804            }
12805        };
12806
12807        try {
12808            who.linkToDeath(death, 0);
12809        } catch (RemoteException e) {
12810            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12811            return;
12812        }
12813
12814        synchronized (this) {
12815            Watchdog.getInstance().setAllowRestart(allowRestart);
12816            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12817            synchronized (death) {
12818                while (who.isBinderAlive()) {
12819                    try {
12820                        death.wait();
12821                    } catch (InterruptedException e) {
12822                    }
12823                }
12824            }
12825            Watchdog.getInstance().setAllowRestart(true);
12826        }
12827    }
12828
12829    @Override
12830    public void restart() {
12831        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12832                != PackageManager.PERMISSION_GRANTED) {
12833            throw new SecurityException("Requires permission "
12834                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12835        }
12836
12837        Log.i(TAG, "Sending shutdown broadcast...");
12838
12839        BroadcastReceiver br = new BroadcastReceiver() {
12840            @Override public void onReceive(Context context, Intent intent) {
12841                // Now the broadcast is done, finish up the low-level shutdown.
12842                Log.i(TAG, "Shutting down activity manager...");
12843                shutdown(10000);
12844                Log.i(TAG, "Shutdown complete, restarting!");
12845                Process.killProcess(Process.myPid());
12846                System.exit(10);
12847            }
12848        };
12849
12850        // First send the high-level shut down broadcast.
12851        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12852        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12853        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12854        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12855        mContext.sendOrderedBroadcastAsUser(intent,
12856                UserHandle.ALL, null, br, mHandler, 0, null, null);
12857        */
12858        br.onReceive(mContext, intent);
12859    }
12860
12861    private long getLowRamTimeSinceIdle(long now) {
12862        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12863    }
12864
12865    @Override
12866    public void performIdleMaintenance() {
12867        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12868                != PackageManager.PERMISSION_GRANTED) {
12869            throw new SecurityException("Requires permission "
12870                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12871        }
12872
12873        synchronized (this) {
12874            final long now = SystemClock.uptimeMillis();
12875            final long timeSinceLastIdle = now - mLastIdleTime;
12876            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12877            mLastIdleTime = now;
12878            mLowRamTimeSinceLastIdle = 0;
12879            if (mLowRamStartTime != 0) {
12880                mLowRamStartTime = now;
12881            }
12882
12883            StringBuilder sb = new StringBuilder(128);
12884            sb.append("Idle maintenance over ");
12885            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12886            sb.append(" low RAM for ");
12887            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12888            Slog.i(TAG, sb.toString());
12889
12890            // If at least 1/3 of our time since the last idle period has been spent
12891            // with RAM low, then we want to kill processes.
12892            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12893
12894            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12895                ProcessRecord proc = mLruProcesses.get(i);
12896                if (proc.notCachedSinceIdle) {
12897                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12898                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12899                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12900                        if (doKilling && proc.initialIdlePss != 0
12901                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12902                            sb = new StringBuilder(128);
12903                            sb.append("Kill");
12904                            sb.append(proc.processName);
12905                            sb.append(" in idle maint: pss=");
12906                            sb.append(proc.lastPss);
12907                            sb.append(", swapPss=");
12908                            sb.append(proc.lastSwapPss);
12909                            sb.append(", initialPss=");
12910                            sb.append(proc.initialIdlePss);
12911                            sb.append(", period=");
12912                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12913                            sb.append(", lowRamPeriod=");
12914                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12915                            Slog.wtfQuiet(TAG, sb.toString());
12916                            proc.kill("idle maint (pss " + proc.lastPss
12917                                    + " from " + proc.initialIdlePss + ")", true);
12918                        }
12919                    }
12920                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12921                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12922                    proc.notCachedSinceIdle = true;
12923                    proc.initialIdlePss = 0;
12924                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12925                            mTestPssMode, isSleepingLocked(), now);
12926                }
12927            }
12928
12929            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12930            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12931        }
12932    }
12933
12934    @Override
12935    public void sendIdleJobTrigger() {
12936        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12937                != PackageManager.PERMISSION_GRANTED) {
12938            throw new SecurityException("Requires permission "
12939                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12940        }
12941
12942        final long ident = Binder.clearCallingIdentity();
12943        try {
12944            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12945                    .setPackage("android")
12946                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12947            broadcastIntent(null, intent, null, null, 0, null, null, null,
12948                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12949        } finally {
12950            Binder.restoreCallingIdentity(ident);
12951        }
12952    }
12953
12954    private void retrieveSettings() {
12955        final ContentResolver resolver = mContext.getContentResolver();
12956        final boolean freeformWindowManagement =
12957                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12958                        || Settings.Global.getInt(
12959                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12960        final boolean supportsPictureInPicture =
12961                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12962
12963        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12964        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12965        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12966        final boolean alwaysFinishActivities =
12967                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12968        final boolean lenientBackgroundCheck =
12969                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12970        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12971        final boolean forceResizable = Settings.Global.getInt(
12972                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12973        final boolean supportsLeanbackOnly =
12974                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12975
12976        // Transfer any global setting for forcing RTL layout, into a System Property
12977        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12978
12979        final Configuration configuration = new Configuration();
12980        Settings.System.getConfiguration(resolver, configuration);
12981        if (forceRtl) {
12982            // This will take care of setting the correct layout direction flags
12983            configuration.setLayoutDirection(configuration.locale);
12984        }
12985
12986        synchronized (this) {
12987            mDebugApp = mOrigDebugApp = debugApp;
12988            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12989            mAlwaysFinishActivities = alwaysFinishActivities;
12990            mLenientBackgroundCheck = lenientBackgroundCheck;
12991            mSupportsLeanbackOnly = supportsLeanbackOnly;
12992            mForceResizableActivities = forceResizable;
12993            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12994            if (supportsMultiWindow || forceResizable) {
12995                mSupportsMultiWindow = true;
12996                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12997                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12998            } else {
12999                mSupportsMultiWindow = false;
13000                mSupportsFreeformWindowManagement = false;
13001                mSupportsPictureInPicture = false;
13002            }
13003            // This happens before any activities are started, so we can
13004            // change mConfiguration in-place.
13005            updateConfigurationLocked(configuration, null, true);
13006            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13007                    "Initial config: " + mConfiguration);
13008
13009            // Load resources only after the current configuration has been set.
13010            final Resources res = mContext.getResources();
13011            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13012            mThumbnailWidth = res.getDimensionPixelSize(
13013                    com.android.internal.R.dimen.thumbnail_width);
13014            mThumbnailHeight = res.getDimensionPixelSize(
13015                    com.android.internal.R.dimen.thumbnail_height);
13016            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13017                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13018            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13019                    com.android.internal.R.string.config_appsNotReportingCrashes));
13020            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13021                mFullscreenThumbnailScale = (float) res
13022                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13023                    (float) mConfiguration.screenWidthDp;
13024            } else {
13025                mFullscreenThumbnailScale = res.getFraction(
13026                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13027            }
13028        }
13029    }
13030
13031    public boolean testIsSystemReady() {
13032        // no need to synchronize(this) just to read & return the value
13033        return mSystemReady;
13034    }
13035
13036    public void systemReady(final Runnable goingCallback) {
13037        synchronized(this) {
13038            if (mSystemReady) {
13039                // If we're done calling all the receivers, run the next "boot phase" passed in
13040                // by the SystemServer
13041                if (goingCallback != null) {
13042                    goingCallback.run();
13043                }
13044                return;
13045            }
13046
13047            mLocalDeviceIdleController
13048                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13049
13050            // Make sure we have the current profile info, since it is needed for security checks.
13051            mUserController.onSystemReady();
13052            mRecentTasks.onSystemReadyLocked();
13053            mAppOpsService.systemReady();
13054            mSystemReady = true;
13055        }
13056
13057        ArrayList<ProcessRecord> procsToKill = null;
13058        synchronized(mPidsSelfLocked) {
13059            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13060                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13061                if (!isAllowedWhileBooting(proc.info)){
13062                    if (procsToKill == null) {
13063                        procsToKill = new ArrayList<ProcessRecord>();
13064                    }
13065                    procsToKill.add(proc);
13066                }
13067            }
13068        }
13069
13070        synchronized(this) {
13071            if (procsToKill != null) {
13072                for (int i=procsToKill.size()-1; i>=0; i--) {
13073                    ProcessRecord proc = procsToKill.get(i);
13074                    Slog.i(TAG, "Removing system update proc: " + proc);
13075                    removeProcessLocked(proc, true, false, "system update done");
13076                }
13077            }
13078
13079            // Now that we have cleaned up any update processes, we
13080            // are ready to start launching real processes and know that
13081            // we won't trample on them any more.
13082            mProcessesReady = true;
13083        }
13084
13085        Slog.i(TAG, "System now ready");
13086        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13087            SystemClock.uptimeMillis());
13088
13089        synchronized(this) {
13090            // Make sure we have no pre-ready processes sitting around.
13091
13092            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13093                ResolveInfo ri = mContext.getPackageManager()
13094                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13095                                STOCK_PM_FLAGS);
13096                CharSequence errorMsg = null;
13097                if (ri != null) {
13098                    ActivityInfo ai = ri.activityInfo;
13099                    ApplicationInfo app = ai.applicationInfo;
13100                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13101                        mTopAction = Intent.ACTION_FACTORY_TEST;
13102                        mTopData = null;
13103                        mTopComponent = new ComponentName(app.packageName,
13104                                ai.name);
13105                    } else {
13106                        errorMsg = mContext.getResources().getText(
13107                                com.android.internal.R.string.factorytest_not_system);
13108                    }
13109                } else {
13110                    errorMsg = mContext.getResources().getText(
13111                            com.android.internal.R.string.factorytest_no_action);
13112                }
13113                if (errorMsg != null) {
13114                    mTopAction = null;
13115                    mTopData = null;
13116                    mTopComponent = null;
13117                    Message msg = Message.obtain();
13118                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13119                    msg.getData().putCharSequence("msg", errorMsg);
13120                    mUiHandler.sendMessage(msg);
13121                }
13122            }
13123        }
13124
13125        retrieveSettings();
13126        final int currentUserId;
13127        synchronized (this) {
13128            currentUserId = mUserController.getCurrentUserIdLocked();
13129            readGrantedUriPermissionsLocked();
13130        }
13131
13132        if (goingCallback != null) goingCallback.run();
13133
13134        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13135                Integer.toString(currentUserId), currentUserId);
13136        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13137                Integer.toString(currentUserId), currentUserId);
13138        mSystemServiceManager.startUser(currentUserId);
13139
13140        synchronized (this) {
13141            // Only start up encryption-aware persistent apps; once user is
13142            // unlocked we'll come back around and start unaware apps
13143            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13144
13145            // Start up initial activity.
13146            mBooting = true;
13147            // Enable home activity for system user, so that the system can always boot
13148            if (UserManager.isSplitSystemUser()) {
13149                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13150                try {
13151                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13152                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13153                            UserHandle.USER_SYSTEM);
13154                } catch (RemoteException e) {
13155                    throw e.rethrowAsRuntimeException();
13156                }
13157            }
13158            startHomeActivityLocked(currentUserId, "systemReady");
13159
13160            try {
13161                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13162                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13163                            + " data partition or your device will be unstable.");
13164                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13165                }
13166            } catch (RemoteException e) {
13167            }
13168
13169            if (!Build.isBuildConsistent()) {
13170                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13171                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13172            }
13173
13174            long ident = Binder.clearCallingIdentity();
13175            try {
13176                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13177                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13178                        | Intent.FLAG_RECEIVER_FOREGROUND);
13179                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13180                broadcastIntentLocked(null, null, intent,
13181                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13182                        null, false, false, MY_PID, Process.SYSTEM_UID,
13183                        currentUserId);
13184                intent = new Intent(Intent.ACTION_USER_STARTING);
13185                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13186                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13187                broadcastIntentLocked(null, null, intent,
13188                        null, new IIntentReceiver.Stub() {
13189                            @Override
13190                            public void performReceive(Intent intent, int resultCode, String data,
13191                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13192                                    throws RemoteException {
13193                            }
13194                        }, 0, null, null,
13195                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13196                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13197            } catch (Throwable t) {
13198                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13199            } finally {
13200                Binder.restoreCallingIdentity(ident);
13201            }
13202            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13203            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13204        }
13205    }
13206
13207    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13208        synchronized (this) {
13209            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13210        }
13211    }
13212
13213    void skipCurrentReceiverLocked(ProcessRecord app) {
13214        for (BroadcastQueue queue : mBroadcastQueues) {
13215            queue.skipCurrentReceiverLocked(app);
13216        }
13217    }
13218
13219    /**
13220     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13221     * The application process will exit immediately after this call returns.
13222     * @param app object of the crashing app, null for the system server
13223     * @param crashInfo describing the exception
13224     */
13225    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13226        ProcessRecord r = findAppProcess(app, "Crash");
13227        final String processName = app == null ? "system_server"
13228                : (r == null ? "unknown" : r.processName);
13229
13230        handleApplicationCrashInner("crash", r, processName, crashInfo);
13231    }
13232
13233    /* Native crash reporting uses this inner version because it needs to be somewhat
13234     * decoupled from the AM-managed cleanup lifecycle
13235     */
13236    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13237            ApplicationErrorReport.CrashInfo crashInfo) {
13238        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13239                UserHandle.getUserId(Binder.getCallingUid()), processName,
13240                r == null ? -1 : r.info.flags,
13241                crashInfo.exceptionClassName,
13242                crashInfo.exceptionMessage,
13243                crashInfo.throwFileName,
13244                crashInfo.throwLineNumber);
13245
13246        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13247
13248        mAppErrors.crashApplication(r, crashInfo);
13249    }
13250
13251    public void handleApplicationStrictModeViolation(
13252            IBinder app,
13253            int violationMask,
13254            StrictMode.ViolationInfo info) {
13255        ProcessRecord r = findAppProcess(app, "StrictMode");
13256        if (r == null) {
13257            return;
13258        }
13259
13260        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13261            Integer stackFingerprint = info.hashCode();
13262            boolean logIt = true;
13263            synchronized (mAlreadyLoggedViolatedStacks) {
13264                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13265                    logIt = false;
13266                    // TODO: sub-sample into EventLog for these, with
13267                    // the info.durationMillis?  Then we'd get
13268                    // the relative pain numbers, without logging all
13269                    // the stack traces repeatedly.  We'd want to do
13270                    // likewise in the client code, which also does
13271                    // dup suppression, before the Binder call.
13272                } else {
13273                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13274                        mAlreadyLoggedViolatedStacks.clear();
13275                    }
13276                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13277                }
13278            }
13279            if (logIt) {
13280                logStrictModeViolationToDropBox(r, info);
13281            }
13282        }
13283
13284        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13285            AppErrorResult result = new AppErrorResult();
13286            synchronized (this) {
13287                final long origId = Binder.clearCallingIdentity();
13288
13289                Message msg = Message.obtain();
13290                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13291                HashMap<String, Object> data = new HashMap<String, Object>();
13292                data.put("result", result);
13293                data.put("app", r);
13294                data.put("violationMask", violationMask);
13295                data.put("info", info);
13296                msg.obj = data;
13297                mUiHandler.sendMessage(msg);
13298
13299                Binder.restoreCallingIdentity(origId);
13300            }
13301            int res = result.get();
13302            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13303        }
13304    }
13305
13306    // Depending on the policy in effect, there could be a bunch of
13307    // these in quick succession so we try to batch these together to
13308    // minimize disk writes, number of dropbox entries, and maximize
13309    // compression, by having more fewer, larger records.
13310    private void logStrictModeViolationToDropBox(
13311            ProcessRecord process,
13312            StrictMode.ViolationInfo info) {
13313        if (info == null) {
13314            return;
13315        }
13316        final boolean isSystemApp = process == null ||
13317                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13318                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13319        final String processName = process == null ? "unknown" : process.processName;
13320        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13321        final DropBoxManager dbox = (DropBoxManager)
13322                mContext.getSystemService(Context.DROPBOX_SERVICE);
13323
13324        // Exit early if the dropbox isn't configured to accept this report type.
13325        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13326
13327        boolean bufferWasEmpty;
13328        boolean needsFlush;
13329        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13330        synchronized (sb) {
13331            bufferWasEmpty = sb.length() == 0;
13332            appendDropBoxProcessHeaders(process, processName, sb);
13333            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13334            sb.append("System-App: ").append(isSystemApp).append("\n");
13335            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13336            if (info.violationNumThisLoop != 0) {
13337                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13338            }
13339            if (info.numAnimationsRunning != 0) {
13340                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13341            }
13342            if (info.broadcastIntentAction != null) {
13343                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13344            }
13345            if (info.durationMillis != -1) {
13346                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13347            }
13348            if (info.numInstances != -1) {
13349                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13350            }
13351            if (info.tags != null) {
13352                for (String tag : info.tags) {
13353                    sb.append("Span-Tag: ").append(tag).append("\n");
13354                }
13355            }
13356            sb.append("\n");
13357            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13358                sb.append(info.crashInfo.stackTrace);
13359                sb.append("\n");
13360            }
13361            if (info.message != null) {
13362                sb.append(info.message);
13363                sb.append("\n");
13364            }
13365
13366            // Only buffer up to ~64k.  Various logging bits truncate
13367            // things at 128k.
13368            needsFlush = (sb.length() > 64 * 1024);
13369        }
13370
13371        // Flush immediately if the buffer's grown too large, or this
13372        // is a non-system app.  Non-system apps are isolated with a
13373        // different tag & policy and not batched.
13374        //
13375        // Batching is useful during internal testing with
13376        // StrictMode settings turned up high.  Without batching,
13377        // thousands of separate files could be created on boot.
13378        if (!isSystemApp || needsFlush) {
13379            new Thread("Error dump: " + dropboxTag) {
13380                @Override
13381                public void run() {
13382                    String report;
13383                    synchronized (sb) {
13384                        report = sb.toString();
13385                        sb.delete(0, sb.length());
13386                        sb.trimToSize();
13387                    }
13388                    if (report.length() != 0) {
13389                        dbox.addText(dropboxTag, report);
13390                    }
13391                }
13392            }.start();
13393            return;
13394        }
13395
13396        // System app batching:
13397        if (!bufferWasEmpty) {
13398            // An existing dropbox-writing thread is outstanding, so
13399            // we don't need to start it up.  The existing thread will
13400            // catch the buffer appends we just did.
13401            return;
13402        }
13403
13404        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13405        // (After this point, we shouldn't access AMS internal data structures.)
13406        new Thread("Error dump: " + dropboxTag) {
13407            @Override
13408            public void run() {
13409                // 5 second sleep to let stacks arrive and be batched together
13410                try {
13411                    Thread.sleep(5000);  // 5 seconds
13412                } catch (InterruptedException e) {}
13413
13414                String errorReport;
13415                synchronized (mStrictModeBuffer) {
13416                    errorReport = mStrictModeBuffer.toString();
13417                    if (errorReport.length() == 0) {
13418                        return;
13419                    }
13420                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13421                    mStrictModeBuffer.trimToSize();
13422                }
13423                dbox.addText(dropboxTag, errorReport);
13424            }
13425        }.start();
13426    }
13427
13428    /**
13429     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13430     * @param app object of the crashing app, null for the system server
13431     * @param tag reported by the caller
13432     * @param system whether this wtf is coming from the system
13433     * @param crashInfo describing the context of the error
13434     * @return true if the process should exit immediately (WTF is fatal)
13435     */
13436    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13437            final ApplicationErrorReport.CrashInfo crashInfo) {
13438        final int callingUid = Binder.getCallingUid();
13439        final int callingPid = Binder.getCallingPid();
13440
13441        if (system) {
13442            // If this is coming from the system, we could very well have low-level
13443            // system locks held, so we want to do this all asynchronously.  And we
13444            // never want this to become fatal, so there is that too.
13445            mHandler.post(new Runnable() {
13446                @Override public void run() {
13447                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13448                }
13449            });
13450            return false;
13451        }
13452
13453        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13454                crashInfo);
13455
13456        if (r != null && r.pid != Process.myPid() &&
13457                Settings.Global.getInt(mContext.getContentResolver(),
13458                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13459            mAppErrors.crashApplication(r, crashInfo);
13460            return true;
13461        } else {
13462            return false;
13463        }
13464    }
13465
13466    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13467            final ApplicationErrorReport.CrashInfo crashInfo) {
13468        final ProcessRecord r = findAppProcess(app, "WTF");
13469        final String processName = app == null ? "system_server"
13470                : (r == null ? "unknown" : r.processName);
13471
13472        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13473                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13474
13475        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13476
13477        return r;
13478    }
13479
13480    /**
13481     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13482     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13483     */
13484    private ProcessRecord findAppProcess(IBinder app, String reason) {
13485        if (app == null) {
13486            return null;
13487        }
13488
13489        synchronized (this) {
13490            final int NP = mProcessNames.getMap().size();
13491            for (int ip=0; ip<NP; ip++) {
13492                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13493                final int NA = apps.size();
13494                for (int ia=0; ia<NA; ia++) {
13495                    ProcessRecord p = apps.valueAt(ia);
13496                    if (p.thread != null && p.thread.asBinder() == app) {
13497                        return p;
13498                    }
13499                }
13500            }
13501
13502            Slog.w(TAG, "Can't find mystery application for " + reason
13503                    + " from pid=" + Binder.getCallingPid()
13504                    + " uid=" + Binder.getCallingUid() + ": " + app);
13505            return null;
13506        }
13507    }
13508
13509    /**
13510     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13511     * to append various headers to the dropbox log text.
13512     */
13513    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13514            StringBuilder sb) {
13515        // Watchdog thread ends up invoking this function (with
13516        // a null ProcessRecord) to add the stack file to dropbox.
13517        // Do not acquire a lock on this (am) in such cases, as it
13518        // could cause a potential deadlock, if and when watchdog
13519        // is invoked due to unavailability of lock on am and it
13520        // would prevent watchdog from killing system_server.
13521        if (process == null) {
13522            sb.append("Process: ").append(processName).append("\n");
13523            return;
13524        }
13525        // Note: ProcessRecord 'process' is guarded by the service
13526        // instance.  (notably process.pkgList, which could otherwise change
13527        // concurrently during execution of this method)
13528        synchronized (this) {
13529            sb.append("Process: ").append(processName).append("\n");
13530            int flags = process.info.flags;
13531            IPackageManager pm = AppGlobals.getPackageManager();
13532            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13533            for (int ip=0; ip<process.pkgList.size(); ip++) {
13534                String pkg = process.pkgList.keyAt(ip);
13535                sb.append("Package: ").append(pkg);
13536                try {
13537                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13538                    if (pi != null) {
13539                        sb.append(" v").append(pi.versionCode);
13540                        if (pi.versionName != null) {
13541                            sb.append(" (").append(pi.versionName).append(")");
13542                        }
13543                    }
13544                } catch (RemoteException e) {
13545                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13546                }
13547                sb.append("\n");
13548            }
13549        }
13550    }
13551
13552    private static String processClass(ProcessRecord process) {
13553        if (process == null || process.pid == MY_PID) {
13554            return "system_server";
13555        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13556            return "system_app";
13557        } else {
13558            return "data_app";
13559        }
13560    }
13561
13562    private volatile long mWtfClusterStart;
13563    private volatile int mWtfClusterCount;
13564
13565    /**
13566     * Write a description of an error (crash, WTF, ANR) to the drop box.
13567     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13568     * @param process which caused the error, null means the system server
13569     * @param activity which triggered the error, null if unknown
13570     * @param parent activity related to the error, null if unknown
13571     * @param subject line related to the error, null if absent
13572     * @param report in long form describing the error, null if absent
13573     * @param dataFile text file to include in the report, null if none
13574     * @param crashInfo giving an application stack trace, null if absent
13575     */
13576    public void addErrorToDropBox(String eventType,
13577            ProcessRecord process, String processName, ActivityRecord activity,
13578            ActivityRecord parent, String subject,
13579            final String report, final File dataFile,
13580            final ApplicationErrorReport.CrashInfo crashInfo) {
13581        // NOTE -- this must never acquire the ActivityManagerService lock,
13582        // otherwise the watchdog may be prevented from resetting the system.
13583
13584        final String dropboxTag = processClass(process) + "_" + eventType;
13585        final DropBoxManager dbox = (DropBoxManager)
13586                mContext.getSystemService(Context.DROPBOX_SERVICE);
13587
13588        // Exit early if the dropbox isn't configured to accept this report type.
13589        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13590
13591        // Rate-limit how often we're willing to do the heavy lifting below to
13592        // collect and record logs; currently 5 logs per 10 second period.
13593        final long now = SystemClock.elapsedRealtime();
13594        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13595            mWtfClusterStart = now;
13596            mWtfClusterCount = 1;
13597        } else {
13598            if (mWtfClusterCount++ >= 5) return;
13599        }
13600
13601        final StringBuilder sb = new StringBuilder(1024);
13602        appendDropBoxProcessHeaders(process, processName, sb);
13603        if (process != null) {
13604            sb.append("Foreground: ")
13605                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13606                    .append("\n");
13607        }
13608        if (activity != null) {
13609            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13610        }
13611        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13612            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13613        }
13614        if (parent != null && parent != activity) {
13615            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13616        }
13617        if (subject != null) {
13618            sb.append("Subject: ").append(subject).append("\n");
13619        }
13620        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13621        if (Debug.isDebuggerConnected()) {
13622            sb.append("Debugger: Connected\n");
13623        }
13624        sb.append("\n");
13625
13626        // Do the rest in a worker thread to avoid blocking the caller on I/O
13627        // (After this point, we shouldn't access AMS internal data structures.)
13628        Thread worker = new Thread("Error dump: " + dropboxTag) {
13629            @Override
13630            public void run() {
13631                if (report != null) {
13632                    sb.append(report);
13633                }
13634
13635                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13636                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13637                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13638                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13639
13640                if (dataFile != null && maxDataFileSize > 0) {
13641                    try {
13642                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13643                                    "\n\n[[TRUNCATED]]"));
13644                    } catch (IOException e) {
13645                        Slog.e(TAG, "Error reading " + dataFile, e);
13646                    }
13647                }
13648                if (crashInfo != null && crashInfo.stackTrace != null) {
13649                    sb.append(crashInfo.stackTrace);
13650                }
13651
13652                if (lines > 0) {
13653                    sb.append("\n");
13654
13655                    // Merge several logcat streams, and take the last N lines
13656                    InputStreamReader input = null;
13657                    try {
13658                        java.lang.Process logcat = new ProcessBuilder(
13659                                "/system/bin/timeout", "-k", "15s", "10s",
13660                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13661                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13662                                        .redirectErrorStream(true).start();
13663
13664                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13665                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13666                        input = new InputStreamReader(logcat.getInputStream());
13667
13668                        int num;
13669                        char[] buf = new char[8192];
13670                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13671                    } catch (IOException e) {
13672                        Slog.e(TAG, "Error running logcat", e);
13673                    } finally {
13674                        if (input != null) try { input.close(); } catch (IOException e) {}
13675                    }
13676                }
13677
13678                dbox.addText(dropboxTag, sb.toString());
13679            }
13680        };
13681
13682        if (process == null) {
13683            // If process is null, we are being called from some internal code
13684            // and may be about to die -- run this synchronously.
13685            worker.run();
13686        } else {
13687            worker.start();
13688        }
13689    }
13690
13691    @Override
13692    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13693        enforceNotIsolatedCaller("getProcessesInErrorState");
13694        // assume our apps are happy - lazy create the list
13695        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13696
13697        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13698                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13699        int userId = UserHandle.getUserId(Binder.getCallingUid());
13700
13701        synchronized (this) {
13702
13703            // iterate across all processes
13704            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13705                ProcessRecord app = mLruProcesses.get(i);
13706                if (!allUsers && app.userId != userId) {
13707                    continue;
13708                }
13709                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13710                    // This one's in trouble, so we'll generate a report for it
13711                    // crashes are higher priority (in case there's a crash *and* an anr)
13712                    ActivityManager.ProcessErrorStateInfo report = null;
13713                    if (app.crashing) {
13714                        report = app.crashingReport;
13715                    } else if (app.notResponding) {
13716                        report = app.notRespondingReport;
13717                    }
13718
13719                    if (report != null) {
13720                        if (errList == null) {
13721                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13722                        }
13723                        errList.add(report);
13724                    } else {
13725                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13726                                " crashing = " + app.crashing +
13727                                " notResponding = " + app.notResponding);
13728                    }
13729                }
13730            }
13731        }
13732
13733        return errList;
13734    }
13735
13736    static int procStateToImportance(int procState, int memAdj,
13737            ActivityManager.RunningAppProcessInfo currApp) {
13738        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13739        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13740            currApp.lru = memAdj;
13741        } else {
13742            currApp.lru = 0;
13743        }
13744        return imp;
13745    }
13746
13747    private void fillInProcMemInfo(ProcessRecord app,
13748            ActivityManager.RunningAppProcessInfo outInfo) {
13749        outInfo.pid = app.pid;
13750        outInfo.uid = app.info.uid;
13751        if (mHeavyWeightProcess == app) {
13752            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13753        }
13754        if (app.persistent) {
13755            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13756        }
13757        if (app.activities.size() > 0) {
13758            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13759        }
13760        outInfo.lastTrimLevel = app.trimMemoryLevel;
13761        int adj = app.curAdj;
13762        int procState = app.curProcState;
13763        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13764        outInfo.importanceReasonCode = app.adjTypeCode;
13765        outInfo.processState = app.curProcState;
13766    }
13767
13768    @Override
13769    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13770        enforceNotIsolatedCaller("getRunningAppProcesses");
13771
13772        final int callingUid = Binder.getCallingUid();
13773
13774        // Lazy instantiation of list
13775        List<ActivityManager.RunningAppProcessInfo> runList = null;
13776        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13777                callingUid) == PackageManager.PERMISSION_GRANTED;
13778        final int userId = UserHandle.getUserId(callingUid);
13779        final boolean allUids = isGetTasksAllowed(
13780                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13781
13782        synchronized (this) {
13783            // Iterate across all processes
13784            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13785                ProcessRecord app = mLruProcesses.get(i);
13786                if ((!allUsers && app.userId != userId)
13787                        || (!allUids && app.uid != callingUid)) {
13788                    continue;
13789                }
13790                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13791                    // Generate process state info for running application
13792                    ActivityManager.RunningAppProcessInfo currApp =
13793                        new ActivityManager.RunningAppProcessInfo(app.processName,
13794                                app.pid, app.getPackageList());
13795                    fillInProcMemInfo(app, currApp);
13796                    if (app.adjSource instanceof ProcessRecord) {
13797                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13798                        currApp.importanceReasonImportance =
13799                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13800                                        app.adjSourceProcState);
13801                    } else if (app.adjSource instanceof ActivityRecord) {
13802                        ActivityRecord r = (ActivityRecord)app.adjSource;
13803                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13804                    }
13805                    if (app.adjTarget instanceof ComponentName) {
13806                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13807                    }
13808                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13809                    //        + " lru=" + currApp.lru);
13810                    if (runList == null) {
13811                        runList = new ArrayList<>();
13812                    }
13813                    runList.add(currApp);
13814                }
13815            }
13816        }
13817        return runList;
13818    }
13819
13820    @Override
13821    public List<ApplicationInfo> getRunningExternalApplications() {
13822        enforceNotIsolatedCaller("getRunningExternalApplications");
13823        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13824        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13825        if (runningApps != null && runningApps.size() > 0) {
13826            Set<String> extList = new HashSet<String>();
13827            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13828                if (app.pkgList != null) {
13829                    for (String pkg : app.pkgList) {
13830                        extList.add(pkg);
13831                    }
13832                }
13833            }
13834            IPackageManager pm = AppGlobals.getPackageManager();
13835            for (String pkg : extList) {
13836                try {
13837                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13838                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13839                        retList.add(info);
13840                    }
13841                } catch (RemoteException e) {
13842                }
13843            }
13844        }
13845        return retList;
13846    }
13847
13848    @Override
13849    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13850        enforceNotIsolatedCaller("getMyMemoryState");
13851        synchronized (this) {
13852            ProcessRecord proc;
13853            synchronized (mPidsSelfLocked) {
13854                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13855            }
13856            fillInProcMemInfo(proc, outInfo);
13857        }
13858    }
13859
13860    @Override
13861    public int getMemoryTrimLevel() {
13862        enforceNotIsolatedCaller("getMyMemoryState");
13863        synchronized (this) {
13864            return mLastMemoryLevel;
13865        }
13866    }
13867
13868    @Override
13869    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13870            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13871        (new ActivityManagerShellCommand(this, false)).exec(
13872                this, in, out, err, args, resultReceiver);
13873    }
13874
13875    @Override
13876    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13877        if (checkCallingPermission(android.Manifest.permission.DUMP)
13878                != PackageManager.PERMISSION_GRANTED) {
13879            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13880                    + Binder.getCallingPid()
13881                    + ", uid=" + Binder.getCallingUid()
13882                    + " without permission "
13883                    + android.Manifest.permission.DUMP);
13884            return;
13885        }
13886
13887        boolean dumpAll = false;
13888        boolean dumpClient = false;
13889        boolean dumpCheckin = false;
13890        boolean dumpCheckinFormat = false;
13891        String dumpPackage = null;
13892
13893        int opti = 0;
13894        while (opti < args.length) {
13895            String opt = args[opti];
13896            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13897                break;
13898            }
13899            opti++;
13900            if ("-a".equals(opt)) {
13901                dumpAll = true;
13902            } else if ("-c".equals(opt)) {
13903                dumpClient = true;
13904            } else if ("-p".equals(opt)) {
13905                if (opti < args.length) {
13906                    dumpPackage = args[opti];
13907                    opti++;
13908                } else {
13909                    pw.println("Error: -p option requires package argument");
13910                    return;
13911                }
13912                dumpClient = true;
13913            } else if ("--checkin".equals(opt)) {
13914                dumpCheckin = dumpCheckinFormat = true;
13915            } else if ("-C".equals(opt)) {
13916                dumpCheckinFormat = true;
13917            } else if ("-h".equals(opt)) {
13918                ActivityManagerShellCommand.dumpHelp(pw, true);
13919                return;
13920            } else {
13921                pw.println("Unknown argument: " + opt + "; use -h for help");
13922            }
13923        }
13924
13925        long origId = Binder.clearCallingIdentity();
13926        boolean more = false;
13927        // Is the caller requesting to dump a particular piece of data?
13928        if (opti < args.length) {
13929            String cmd = args[opti];
13930            opti++;
13931            if ("activities".equals(cmd) || "a".equals(cmd)) {
13932                synchronized (this) {
13933                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13934                }
13935            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13936                synchronized (this) {
13937                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13938                }
13939            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13940                String[] newArgs;
13941                String name;
13942                if (opti >= args.length) {
13943                    name = null;
13944                    newArgs = EMPTY_STRING_ARRAY;
13945                } else {
13946                    dumpPackage = args[opti];
13947                    opti++;
13948                    newArgs = new String[args.length - opti];
13949                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13950                            args.length - opti);
13951                }
13952                synchronized (this) {
13953                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13954                }
13955            } else if ("broadcast-stats".equals(cmd)) {
13956                String[] newArgs;
13957                String name;
13958                if (opti >= args.length) {
13959                    name = null;
13960                    newArgs = EMPTY_STRING_ARRAY;
13961                } else {
13962                    dumpPackage = args[opti];
13963                    opti++;
13964                    newArgs = new String[args.length - opti];
13965                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13966                            args.length - opti);
13967                }
13968                synchronized (this) {
13969                    if (dumpCheckinFormat) {
13970                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13971                                dumpPackage);
13972                    } else {
13973                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13974                    }
13975                }
13976            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13977                String[] newArgs;
13978                String name;
13979                if (opti >= args.length) {
13980                    name = null;
13981                    newArgs = EMPTY_STRING_ARRAY;
13982                } else {
13983                    dumpPackage = args[opti];
13984                    opti++;
13985                    newArgs = new String[args.length - opti];
13986                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13987                            args.length - opti);
13988                }
13989                synchronized (this) {
13990                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13991                }
13992            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13993                String[] newArgs;
13994                String name;
13995                if (opti >= args.length) {
13996                    name = null;
13997                    newArgs = EMPTY_STRING_ARRAY;
13998                } else {
13999                    dumpPackage = args[opti];
14000                    opti++;
14001                    newArgs = new String[args.length - opti];
14002                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14003                            args.length - opti);
14004                }
14005                synchronized (this) {
14006                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14007                }
14008            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14009                synchronized (this) {
14010                    dumpOomLocked(fd, pw, args, opti, true);
14011                }
14012            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14013                synchronized (this) {
14014                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14015                }
14016            } else if ("provider".equals(cmd)) {
14017                String[] newArgs;
14018                String name;
14019                if (opti >= args.length) {
14020                    name = null;
14021                    newArgs = EMPTY_STRING_ARRAY;
14022                } else {
14023                    name = args[opti];
14024                    opti++;
14025                    newArgs = new String[args.length - opti];
14026                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14027                }
14028                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14029                    pw.println("No providers match: " + name);
14030                    pw.println("Use -h for help.");
14031                }
14032            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14033                synchronized (this) {
14034                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14035                }
14036            } else if ("service".equals(cmd)) {
14037                String[] newArgs;
14038                String name;
14039                if (opti >= args.length) {
14040                    name = null;
14041                    newArgs = EMPTY_STRING_ARRAY;
14042                } else {
14043                    name = args[opti];
14044                    opti++;
14045                    newArgs = new String[args.length - opti];
14046                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14047                            args.length - opti);
14048                }
14049                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14050                    pw.println("No services match: " + name);
14051                    pw.println("Use -h for help.");
14052                }
14053            } else if ("package".equals(cmd)) {
14054                String[] newArgs;
14055                if (opti >= args.length) {
14056                    pw.println("package: no package name specified");
14057                    pw.println("Use -h for help.");
14058                } else {
14059                    dumpPackage = args[opti];
14060                    opti++;
14061                    newArgs = new String[args.length - opti];
14062                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14063                            args.length - opti);
14064                    args = newArgs;
14065                    opti = 0;
14066                    more = true;
14067                }
14068            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14069                synchronized (this) {
14070                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14071                }
14072            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14073                if (dumpClient) {
14074                    ActiveServices.ServiceDumper dumper;
14075                    synchronized (this) {
14076                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14077                                dumpPackage);
14078                    }
14079                    dumper.dumpWithClient();
14080                } else {
14081                    synchronized (this) {
14082                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14083                                dumpPackage).dumpLocked();
14084                    }
14085                }
14086            } else if ("locks".equals(cmd)) {
14087                LockGuard.dump(fd, pw, args);
14088            } else {
14089                // Dumping a single activity?
14090                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14091                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14092                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14093                    if (res < 0) {
14094                        pw.println("Bad activity command, or no activities match: " + cmd);
14095                        pw.println("Use -h for help.");
14096                    }
14097                }
14098            }
14099            if (!more) {
14100                Binder.restoreCallingIdentity(origId);
14101                return;
14102            }
14103        }
14104
14105        // No piece of data specified, dump everything.
14106        if (dumpCheckinFormat) {
14107            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14108        } else if (dumpClient) {
14109            ActiveServices.ServiceDumper sdumper;
14110            synchronized (this) {
14111                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14112                pw.println();
14113                if (dumpAll) {
14114                    pw.println("-------------------------------------------------------------------------------");
14115                }
14116                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14117                pw.println();
14118                if (dumpAll) {
14119                    pw.println("-------------------------------------------------------------------------------");
14120                }
14121                if (dumpAll || dumpPackage != null) {
14122                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14123                    pw.println();
14124                    if (dumpAll) {
14125                        pw.println("-------------------------------------------------------------------------------");
14126                    }
14127                }
14128                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14129                pw.println();
14130                if (dumpAll) {
14131                    pw.println("-------------------------------------------------------------------------------");
14132                }
14133                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14134                pw.println();
14135                if (dumpAll) {
14136                    pw.println("-------------------------------------------------------------------------------");
14137                }
14138                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14139                        dumpPackage);
14140            }
14141            sdumper.dumpWithClient();
14142            pw.println();
14143            synchronized (this) {
14144                if (dumpAll) {
14145                    pw.println("-------------------------------------------------------------------------------");
14146                }
14147                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14148                pw.println();
14149                if (dumpAll) {
14150                    pw.println("-------------------------------------------------------------------------------");
14151                }
14152                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14153                if (mAssociations.size() > 0) {
14154                    pw.println();
14155                    if (dumpAll) {
14156                        pw.println("-------------------------------------------------------------------------------");
14157                    }
14158                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14159                }
14160                pw.println();
14161                if (dumpAll) {
14162                    pw.println("-------------------------------------------------------------------------------");
14163                }
14164                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14165            }
14166
14167        } else {
14168            synchronized (this) {
14169                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14170                pw.println();
14171                if (dumpAll) {
14172                    pw.println("-------------------------------------------------------------------------------");
14173                }
14174                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14175                pw.println();
14176                if (dumpAll) {
14177                    pw.println("-------------------------------------------------------------------------------");
14178                }
14179                if (dumpAll || dumpPackage != null) {
14180                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14181                    pw.println();
14182                    if (dumpAll) {
14183                        pw.println("-------------------------------------------------------------------------------");
14184                    }
14185                }
14186                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14187                pw.println();
14188                if (dumpAll) {
14189                    pw.println("-------------------------------------------------------------------------------");
14190                }
14191                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14192                pw.println();
14193                if (dumpAll) {
14194                    pw.println("-------------------------------------------------------------------------------");
14195                }
14196                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14197                        .dumpLocked();
14198                pw.println();
14199                if (dumpAll) {
14200                    pw.println("-------------------------------------------------------------------------------");
14201                }
14202                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14203                pw.println();
14204                if (dumpAll) {
14205                    pw.println("-------------------------------------------------------------------------------");
14206                }
14207                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14208                if (mAssociations.size() > 0) {
14209                    pw.println();
14210                    if (dumpAll) {
14211                        pw.println("-------------------------------------------------------------------------------");
14212                    }
14213                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14214                }
14215                pw.println();
14216                if (dumpAll) {
14217                    pw.println("-------------------------------------------------------------------------------");
14218                }
14219                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14220            }
14221        }
14222        Binder.restoreCallingIdentity(origId);
14223    }
14224
14225    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14226            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14227        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14228
14229        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14230                dumpPackage);
14231        boolean needSep = printedAnything;
14232
14233        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14234                dumpPackage, needSep, "  mFocusedActivity: ");
14235        if (printed) {
14236            printedAnything = true;
14237            needSep = false;
14238        }
14239
14240        if (dumpPackage == null) {
14241            if (needSep) {
14242                pw.println();
14243            }
14244            needSep = true;
14245            printedAnything = true;
14246            mStackSupervisor.dump(pw, "  ");
14247        }
14248
14249        if (!printedAnything) {
14250            pw.println("  (nothing)");
14251        }
14252    }
14253
14254    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14255            int opti, boolean dumpAll, String dumpPackage) {
14256        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14257
14258        boolean printedAnything = false;
14259
14260        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14261            boolean printedHeader = false;
14262
14263            final int N = mRecentTasks.size();
14264            for (int i=0; i<N; i++) {
14265                TaskRecord tr = mRecentTasks.get(i);
14266                if (dumpPackage != null) {
14267                    if (tr.realActivity == null ||
14268                            !dumpPackage.equals(tr.realActivity)) {
14269                        continue;
14270                    }
14271                }
14272                if (!printedHeader) {
14273                    pw.println("  Recent tasks:");
14274                    printedHeader = true;
14275                    printedAnything = true;
14276                }
14277                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14278                        pw.println(tr);
14279                if (dumpAll) {
14280                    mRecentTasks.get(i).dump(pw, "    ");
14281                }
14282            }
14283        }
14284
14285        if (!printedAnything) {
14286            pw.println("  (nothing)");
14287        }
14288    }
14289
14290    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14291            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14292        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14293
14294        int dumpUid = 0;
14295        if (dumpPackage != null) {
14296            IPackageManager pm = AppGlobals.getPackageManager();
14297            try {
14298                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14299            } catch (RemoteException e) {
14300            }
14301        }
14302
14303        boolean printedAnything = false;
14304
14305        final long now = SystemClock.uptimeMillis();
14306
14307        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14308            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14309                    = mAssociations.valueAt(i1);
14310            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14311                SparseArray<ArrayMap<String, Association>> sourceUids
14312                        = targetComponents.valueAt(i2);
14313                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14314                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14315                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14316                        Association ass = sourceProcesses.valueAt(i4);
14317                        if (dumpPackage != null) {
14318                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14319                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14320                                continue;
14321                            }
14322                        }
14323                        printedAnything = true;
14324                        pw.print("  ");
14325                        pw.print(ass.mTargetProcess);
14326                        pw.print("/");
14327                        UserHandle.formatUid(pw, ass.mTargetUid);
14328                        pw.print(" <- ");
14329                        pw.print(ass.mSourceProcess);
14330                        pw.print("/");
14331                        UserHandle.formatUid(pw, ass.mSourceUid);
14332                        pw.println();
14333                        pw.print("    via ");
14334                        pw.print(ass.mTargetComponent.flattenToShortString());
14335                        pw.println();
14336                        pw.print("    ");
14337                        long dur = ass.mTime;
14338                        if (ass.mNesting > 0) {
14339                            dur += now - ass.mStartTime;
14340                        }
14341                        TimeUtils.formatDuration(dur, pw);
14342                        pw.print(" (");
14343                        pw.print(ass.mCount);
14344                        pw.print(" times)");
14345                        pw.print("  ");
14346                        for (int i=0; i<ass.mStateTimes.length; i++) {
14347                            long amt = ass.mStateTimes[i];
14348                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14349                                amt += now - ass.mLastStateUptime;
14350                            }
14351                            if (amt != 0) {
14352                                pw.print(" ");
14353                                pw.print(ProcessList.makeProcStateString(
14354                                            i + ActivityManager.MIN_PROCESS_STATE));
14355                                pw.print("=");
14356                                TimeUtils.formatDuration(amt, pw);
14357                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14358                                    pw.print("*");
14359                                }
14360                            }
14361                        }
14362                        pw.println();
14363                        if (ass.mNesting > 0) {
14364                            pw.print("    Currently active: ");
14365                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14366                            pw.println();
14367                        }
14368                    }
14369                }
14370            }
14371
14372        }
14373
14374        if (!printedAnything) {
14375            pw.println("  (nothing)");
14376        }
14377    }
14378
14379    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14380            String header, boolean needSep) {
14381        boolean printed = false;
14382        int whichAppId = -1;
14383        if (dumpPackage != null) {
14384            try {
14385                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14386                        dumpPackage, 0);
14387                whichAppId = UserHandle.getAppId(info.uid);
14388            } catch (NameNotFoundException e) {
14389                e.printStackTrace();
14390            }
14391        }
14392        for (int i=0; i<uids.size(); i++) {
14393            UidRecord uidRec = uids.valueAt(i);
14394            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14395                continue;
14396            }
14397            if (!printed) {
14398                printed = true;
14399                if (needSep) {
14400                    pw.println();
14401                }
14402                pw.print("  ");
14403                pw.println(header);
14404                needSep = true;
14405            }
14406            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14407            pw.print(": "); pw.println(uidRec);
14408        }
14409        return printed;
14410    }
14411
14412    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14413            int opti, boolean dumpAll, String dumpPackage) {
14414        boolean needSep = false;
14415        boolean printedAnything = false;
14416        int numPers = 0;
14417
14418        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14419
14420        if (dumpAll) {
14421            final int NP = mProcessNames.getMap().size();
14422            for (int ip=0; ip<NP; ip++) {
14423                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14424                final int NA = procs.size();
14425                for (int ia=0; ia<NA; ia++) {
14426                    ProcessRecord r = procs.valueAt(ia);
14427                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14428                        continue;
14429                    }
14430                    if (!needSep) {
14431                        pw.println("  All known processes:");
14432                        needSep = true;
14433                        printedAnything = true;
14434                    }
14435                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14436                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14437                        pw.print(" "); pw.println(r);
14438                    r.dump(pw, "    ");
14439                    if (r.persistent) {
14440                        numPers++;
14441                    }
14442                }
14443            }
14444        }
14445
14446        if (mIsolatedProcesses.size() > 0) {
14447            boolean printed = false;
14448            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14449                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14450                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14451                    continue;
14452                }
14453                if (!printed) {
14454                    if (needSep) {
14455                        pw.println();
14456                    }
14457                    pw.println("  Isolated process list (sorted by uid):");
14458                    printedAnything = true;
14459                    printed = true;
14460                    needSep = true;
14461                }
14462                pw.println(String.format("%sIsolated #%2d: %s",
14463                        "    ", i, r.toString()));
14464            }
14465        }
14466
14467        if (mActiveUids.size() > 0) {
14468            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14469                printedAnything = needSep = true;
14470            }
14471        }
14472        if (mValidateUids.size() > 0) {
14473            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14474                printedAnything = needSep = true;
14475            }
14476        }
14477
14478        if (mLruProcesses.size() > 0) {
14479            if (needSep) {
14480                pw.println();
14481            }
14482            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14483                    pw.print(" total, non-act at ");
14484                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14485                    pw.print(", non-svc at ");
14486                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14487                    pw.println("):");
14488            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14489            needSep = true;
14490            printedAnything = true;
14491        }
14492
14493        if (dumpAll || dumpPackage != null) {
14494            synchronized (mPidsSelfLocked) {
14495                boolean printed = false;
14496                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14497                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14498                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14499                        continue;
14500                    }
14501                    if (!printed) {
14502                        if (needSep) pw.println();
14503                        needSep = true;
14504                        pw.println("  PID mappings:");
14505                        printed = true;
14506                        printedAnything = true;
14507                    }
14508                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14509                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14510                }
14511            }
14512        }
14513
14514        if (mForegroundProcesses.size() > 0) {
14515            synchronized (mPidsSelfLocked) {
14516                boolean printed = false;
14517                for (int i=0; i<mForegroundProcesses.size(); i++) {
14518                    ProcessRecord r = mPidsSelfLocked.get(
14519                            mForegroundProcesses.valueAt(i).pid);
14520                    if (dumpPackage != null && (r == null
14521                            || !r.pkgList.containsKey(dumpPackage))) {
14522                        continue;
14523                    }
14524                    if (!printed) {
14525                        if (needSep) pw.println();
14526                        needSep = true;
14527                        pw.println("  Foreground Processes:");
14528                        printed = true;
14529                        printedAnything = true;
14530                    }
14531                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14532                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14533                }
14534            }
14535        }
14536
14537        if (mPersistentStartingProcesses.size() > 0) {
14538            if (needSep) pw.println();
14539            needSep = true;
14540            printedAnything = true;
14541            pw.println("  Persisent processes that are starting:");
14542            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14543                    "Starting Norm", "Restarting PERS", dumpPackage);
14544        }
14545
14546        if (mRemovedProcesses.size() > 0) {
14547            if (needSep) pw.println();
14548            needSep = true;
14549            printedAnything = true;
14550            pw.println("  Processes that are being removed:");
14551            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14552                    "Removed Norm", "Removed PERS", dumpPackage);
14553        }
14554
14555        if (mProcessesOnHold.size() > 0) {
14556            if (needSep) pw.println();
14557            needSep = true;
14558            printedAnything = true;
14559            pw.println("  Processes that are on old until the system is ready:");
14560            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14561                    "OnHold Norm", "OnHold PERS", dumpPackage);
14562        }
14563
14564        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14565
14566        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14567        if (needSep) {
14568            printedAnything = true;
14569        }
14570
14571        if (dumpPackage == null) {
14572            pw.println();
14573            needSep = false;
14574            mUserController.dump(pw, dumpAll);
14575        }
14576        if (mHomeProcess != null && (dumpPackage == null
14577                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14578            if (needSep) {
14579                pw.println();
14580                needSep = false;
14581            }
14582            pw.println("  mHomeProcess: " + mHomeProcess);
14583        }
14584        if (mPreviousProcess != null && (dumpPackage == null
14585                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14586            if (needSep) {
14587                pw.println();
14588                needSep = false;
14589            }
14590            pw.println("  mPreviousProcess: " + mPreviousProcess);
14591        }
14592        if (dumpAll) {
14593            StringBuilder sb = new StringBuilder(128);
14594            sb.append("  mPreviousProcessVisibleTime: ");
14595            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14596            pw.println(sb);
14597        }
14598        if (mHeavyWeightProcess != null && (dumpPackage == null
14599                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14600            if (needSep) {
14601                pw.println();
14602                needSep = false;
14603            }
14604            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14605        }
14606        if (dumpPackage == null) {
14607            pw.println("  mConfiguration: " + mConfiguration);
14608        }
14609        if (dumpAll) {
14610            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14611            if (mCompatModePackages.getPackages().size() > 0) {
14612                boolean printed = false;
14613                for (Map.Entry<String, Integer> entry
14614                        : mCompatModePackages.getPackages().entrySet()) {
14615                    String pkg = entry.getKey();
14616                    int mode = entry.getValue();
14617                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14618                        continue;
14619                    }
14620                    if (!printed) {
14621                        pw.println("  mScreenCompatPackages:");
14622                        printed = true;
14623                    }
14624                    pw.print("    "); pw.print(pkg); pw.print(": ");
14625                            pw.print(mode); pw.println();
14626                }
14627            }
14628        }
14629        if (dumpPackage == null) {
14630            pw.println("  mWakefulness="
14631                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14632            pw.println("  mSleepTokens=" + mSleepTokens);
14633            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14634                    + lockScreenShownToString());
14635            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14636            if (mRunningVoice != null) {
14637                pw.println("  mRunningVoice=" + mRunningVoice);
14638                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14639            }
14640        }
14641        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14642                || mOrigWaitForDebugger) {
14643            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14644                    || dumpPackage.equals(mOrigDebugApp)) {
14645                if (needSep) {
14646                    pw.println();
14647                    needSep = false;
14648                }
14649                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14650                        + " mDebugTransient=" + mDebugTransient
14651                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14652            }
14653        }
14654        if (mCurAppTimeTracker != null) {
14655            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14656        }
14657        if (mMemWatchProcesses.getMap().size() > 0) {
14658            pw.println("  Mem watch processes:");
14659            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14660                    = mMemWatchProcesses.getMap();
14661            for (int i=0; i<procs.size(); i++) {
14662                final String proc = procs.keyAt(i);
14663                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14664                for (int j=0; j<uids.size(); j++) {
14665                    if (needSep) {
14666                        pw.println();
14667                        needSep = false;
14668                    }
14669                    StringBuilder sb = new StringBuilder();
14670                    sb.append("    ").append(proc).append('/');
14671                    UserHandle.formatUid(sb, uids.keyAt(j));
14672                    Pair<Long, String> val = uids.valueAt(j);
14673                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14674                    if (val.second != null) {
14675                        sb.append(", report to ").append(val.second);
14676                    }
14677                    pw.println(sb.toString());
14678                }
14679            }
14680            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14681            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14682            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14683                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14684        }
14685        if (mTrackAllocationApp != null) {
14686            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14687                if (needSep) {
14688                    pw.println();
14689                    needSep = false;
14690                }
14691                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14692            }
14693        }
14694        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14695                || mProfileFd != null) {
14696            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14697                if (needSep) {
14698                    pw.println();
14699                    needSep = false;
14700                }
14701                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14702                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14703                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14704                        + mAutoStopProfiler);
14705                pw.println("  mProfileType=" + mProfileType);
14706            }
14707        }
14708        if (mNativeDebuggingApp != null) {
14709            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14710                if (needSep) {
14711                    pw.println();
14712                    needSep = false;
14713                }
14714                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14715            }
14716        }
14717        if (dumpPackage == null) {
14718            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14719                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14720                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14721            }
14722            if (mController != null) {
14723                pw.println("  mController=" + mController
14724                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14725            }
14726            if (dumpAll) {
14727                pw.println("  Total persistent processes: " + numPers);
14728                pw.println("  mProcessesReady=" + mProcessesReady
14729                        + " mSystemReady=" + mSystemReady
14730                        + " mBooted=" + mBooted
14731                        + " mFactoryTest=" + mFactoryTest);
14732                pw.println("  mBooting=" + mBooting
14733                        + " mCallFinishBooting=" + mCallFinishBooting
14734                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14735                pw.print("  mLastPowerCheckRealtime=");
14736                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14737                        pw.println("");
14738                pw.print("  mLastPowerCheckUptime=");
14739                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14740                        pw.println("");
14741                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14742                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14743                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14744                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14745                        + " (" + mLruProcesses.size() + " total)"
14746                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14747                        + " mNumServiceProcs=" + mNumServiceProcs
14748                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14749                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14750                        + " mLastMemoryLevel=" + mLastMemoryLevel
14751                        + " mLastNumProcesses=" + mLastNumProcesses);
14752                long now = SystemClock.uptimeMillis();
14753                pw.print("  mLastIdleTime=");
14754                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14755                        pw.print(" mLowRamSinceLastIdle=");
14756                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14757                        pw.println();
14758            }
14759        }
14760
14761        if (!printedAnything) {
14762            pw.println("  (nothing)");
14763        }
14764    }
14765
14766    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14767            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14768        if (mProcessesToGc.size() > 0) {
14769            boolean printed = false;
14770            long now = SystemClock.uptimeMillis();
14771            for (int i=0; i<mProcessesToGc.size(); i++) {
14772                ProcessRecord proc = mProcessesToGc.get(i);
14773                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14774                    continue;
14775                }
14776                if (!printed) {
14777                    if (needSep) pw.println();
14778                    needSep = true;
14779                    pw.println("  Processes that are waiting to GC:");
14780                    printed = true;
14781                }
14782                pw.print("    Process "); pw.println(proc);
14783                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14784                        pw.print(", last gced=");
14785                        pw.print(now-proc.lastRequestedGc);
14786                        pw.print(" ms ago, last lowMem=");
14787                        pw.print(now-proc.lastLowMemory);
14788                        pw.println(" ms ago");
14789
14790            }
14791        }
14792        return needSep;
14793    }
14794
14795    void printOomLevel(PrintWriter pw, String name, int adj) {
14796        pw.print("    ");
14797        if (adj >= 0) {
14798            pw.print(' ');
14799            if (adj < 10) pw.print(' ');
14800        } else {
14801            if (adj > -10) pw.print(' ');
14802        }
14803        pw.print(adj);
14804        pw.print(": ");
14805        pw.print(name);
14806        pw.print(" (");
14807        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14808        pw.println(")");
14809    }
14810
14811    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14812            int opti, boolean dumpAll) {
14813        boolean needSep = false;
14814
14815        if (mLruProcesses.size() > 0) {
14816            if (needSep) pw.println();
14817            needSep = true;
14818            pw.println("  OOM levels:");
14819            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14820            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14821            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14822            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14823            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14824            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14825            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14826            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14827            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14828            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14829            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14830            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14831            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14832            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14833
14834            if (needSep) pw.println();
14835            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14836                    pw.print(" total, non-act at ");
14837                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14838                    pw.print(", non-svc at ");
14839                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14840                    pw.println("):");
14841            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14842            needSep = true;
14843        }
14844
14845        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14846
14847        pw.println();
14848        pw.println("  mHomeProcess: " + mHomeProcess);
14849        pw.println("  mPreviousProcess: " + mPreviousProcess);
14850        if (mHeavyWeightProcess != null) {
14851            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14852        }
14853
14854        return true;
14855    }
14856
14857    /**
14858     * There are three ways to call this:
14859     *  - no provider specified: dump all the providers
14860     *  - a flattened component name that matched an existing provider was specified as the
14861     *    first arg: dump that one provider
14862     *  - the first arg isn't the flattened component name of an existing provider:
14863     *    dump all providers whose component contains the first arg as a substring
14864     */
14865    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14866            int opti, boolean dumpAll) {
14867        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14868    }
14869
14870    static class ItemMatcher {
14871        ArrayList<ComponentName> components;
14872        ArrayList<String> strings;
14873        ArrayList<Integer> objects;
14874        boolean all;
14875
14876        ItemMatcher() {
14877            all = true;
14878        }
14879
14880        void build(String name) {
14881            ComponentName componentName = ComponentName.unflattenFromString(name);
14882            if (componentName != null) {
14883                if (components == null) {
14884                    components = new ArrayList<ComponentName>();
14885                }
14886                components.add(componentName);
14887                all = false;
14888            } else {
14889                int objectId = 0;
14890                // Not a '/' separated full component name; maybe an object ID?
14891                try {
14892                    objectId = Integer.parseInt(name, 16);
14893                    if (objects == null) {
14894                        objects = new ArrayList<Integer>();
14895                    }
14896                    objects.add(objectId);
14897                    all = false;
14898                } catch (RuntimeException e) {
14899                    // Not an integer; just do string match.
14900                    if (strings == null) {
14901                        strings = new ArrayList<String>();
14902                    }
14903                    strings.add(name);
14904                    all = false;
14905                }
14906            }
14907        }
14908
14909        int build(String[] args, int opti) {
14910            for (; opti<args.length; opti++) {
14911                String name = args[opti];
14912                if ("--".equals(name)) {
14913                    return opti+1;
14914                }
14915                build(name);
14916            }
14917            return opti;
14918        }
14919
14920        boolean match(Object object, ComponentName comp) {
14921            if (all) {
14922                return true;
14923            }
14924            if (components != null) {
14925                for (int i=0; i<components.size(); i++) {
14926                    if (components.get(i).equals(comp)) {
14927                        return true;
14928                    }
14929                }
14930            }
14931            if (objects != null) {
14932                for (int i=0; i<objects.size(); i++) {
14933                    if (System.identityHashCode(object) == objects.get(i)) {
14934                        return true;
14935                    }
14936                }
14937            }
14938            if (strings != null) {
14939                String flat = comp.flattenToString();
14940                for (int i=0; i<strings.size(); i++) {
14941                    if (flat.contains(strings.get(i))) {
14942                        return true;
14943                    }
14944                }
14945            }
14946            return false;
14947        }
14948    }
14949
14950    /**
14951     * There are three things that cmd can be:
14952     *  - a flattened component name that matches an existing activity
14953     *  - the cmd arg isn't the flattened component name of an existing activity:
14954     *    dump all activity whose component contains the cmd as a substring
14955     *  - A hex number of the ActivityRecord object instance.
14956     */
14957    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14958            int opti, boolean dumpAll) {
14959        ArrayList<ActivityRecord> activities;
14960
14961        synchronized (this) {
14962            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14963        }
14964
14965        if (activities.size() <= 0) {
14966            return false;
14967        }
14968
14969        String[] newArgs = new String[args.length - opti];
14970        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14971
14972        TaskRecord lastTask = null;
14973        boolean needSep = false;
14974        for (int i=activities.size()-1; i>=0; i--) {
14975            ActivityRecord r = activities.get(i);
14976            if (needSep) {
14977                pw.println();
14978            }
14979            needSep = true;
14980            synchronized (this) {
14981                if (lastTask != r.task) {
14982                    lastTask = r.task;
14983                    pw.print("TASK "); pw.print(lastTask.affinity);
14984                            pw.print(" id="); pw.println(lastTask.taskId);
14985                    if (dumpAll) {
14986                        lastTask.dump(pw, "  ");
14987                    }
14988                }
14989            }
14990            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14991        }
14992        return true;
14993    }
14994
14995    /**
14996     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14997     * there is a thread associated with the activity.
14998     */
14999    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15000            final ActivityRecord r, String[] args, boolean dumpAll) {
15001        String innerPrefix = prefix + "  ";
15002        synchronized (this) {
15003            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15004                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15005                    pw.print(" pid=");
15006                    if (r.app != null) pw.println(r.app.pid);
15007                    else pw.println("(not running)");
15008            if (dumpAll) {
15009                r.dump(pw, innerPrefix);
15010            }
15011        }
15012        if (r.app != null && r.app.thread != null) {
15013            // flush anything that is already in the PrintWriter since the thread is going
15014            // to write to the file descriptor directly
15015            pw.flush();
15016            try {
15017                TransferPipe tp = new TransferPipe();
15018                try {
15019                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15020                            r.appToken, innerPrefix, args);
15021                    tp.go(fd);
15022                } finally {
15023                    tp.kill();
15024                }
15025            } catch (IOException e) {
15026                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15027            } catch (RemoteException e) {
15028                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15029            }
15030        }
15031    }
15032
15033    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15034            int opti, boolean dumpAll, String dumpPackage) {
15035        boolean needSep = false;
15036        boolean onlyHistory = false;
15037        boolean printedAnything = false;
15038
15039        if ("history".equals(dumpPackage)) {
15040            if (opti < args.length && "-s".equals(args[opti])) {
15041                dumpAll = false;
15042            }
15043            onlyHistory = true;
15044            dumpPackage = null;
15045        }
15046
15047        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15048        if (!onlyHistory && dumpAll) {
15049            if (mRegisteredReceivers.size() > 0) {
15050                boolean printed = false;
15051                Iterator it = mRegisteredReceivers.values().iterator();
15052                while (it.hasNext()) {
15053                    ReceiverList r = (ReceiverList)it.next();
15054                    if (dumpPackage != null && (r.app == null ||
15055                            !dumpPackage.equals(r.app.info.packageName))) {
15056                        continue;
15057                    }
15058                    if (!printed) {
15059                        pw.println("  Registered Receivers:");
15060                        needSep = true;
15061                        printed = true;
15062                        printedAnything = true;
15063                    }
15064                    pw.print("  * "); pw.println(r);
15065                    r.dump(pw, "    ");
15066                }
15067            }
15068
15069            if (mReceiverResolver.dump(pw, needSep ?
15070                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15071                    "    ", dumpPackage, false, false)) {
15072                needSep = true;
15073                printedAnything = true;
15074            }
15075        }
15076
15077        for (BroadcastQueue q : mBroadcastQueues) {
15078            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15079            printedAnything |= needSep;
15080        }
15081
15082        needSep = true;
15083
15084        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15085            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15086                if (needSep) {
15087                    pw.println();
15088                }
15089                needSep = true;
15090                printedAnything = true;
15091                pw.print("  Sticky broadcasts for user ");
15092                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15093                StringBuilder sb = new StringBuilder(128);
15094                for (Map.Entry<String, ArrayList<Intent>> ent
15095                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15096                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15097                    if (dumpAll) {
15098                        pw.println(":");
15099                        ArrayList<Intent> intents = ent.getValue();
15100                        final int N = intents.size();
15101                        for (int i=0; i<N; i++) {
15102                            sb.setLength(0);
15103                            sb.append("    Intent: ");
15104                            intents.get(i).toShortString(sb, false, true, false, false);
15105                            pw.println(sb.toString());
15106                            Bundle bundle = intents.get(i).getExtras();
15107                            if (bundle != null) {
15108                                pw.print("      ");
15109                                pw.println(bundle.toString());
15110                            }
15111                        }
15112                    } else {
15113                        pw.println("");
15114                    }
15115                }
15116            }
15117        }
15118
15119        if (!onlyHistory && dumpAll) {
15120            pw.println();
15121            for (BroadcastQueue queue : mBroadcastQueues) {
15122                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15123                        + queue.mBroadcastsScheduled);
15124            }
15125            pw.println("  mHandler:");
15126            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15127            needSep = true;
15128            printedAnything = true;
15129        }
15130
15131        if (!printedAnything) {
15132            pw.println("  (nothing)");
15133        }
15134    }
15135
15136    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15137            int opti, boolean dumpAll, String dumpPackage) {
15138        if (mCurBroadcastStats == null) {
15139            return;
15140        }
15141
15142        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15143        final long now = SystemClock.elapsedRealtime();
15144        if (mLastBroadcastStats != null) {
15145            pw.print("  Last stats (from ");
15146            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15147            pw.print(" to ");
15148            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15149            pw.print(", ");
15150            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15151                    - mLastBroadcastStats.mStartUptime, pw);
15152            pw.println(" uptime):");
15153            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15154                pw.println("    (nothing)");
15155            }
15156            pw.println();
15157        }
15158        pw.print("  Current stats (from ");
15159        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15160        pw.print(" to now, ");
15161        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15162                - mCurBroadcastStats.mStartUptime, pw);
15163        pw.println(" uptime):");
15164        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15165            pw.println("    (nothing)");
15166        }
15167    }
15168
15169    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15170            int opti, boolean fullCheckin, String dumpPackage) {
15171        if (mCurBroadcastStats == null) {
15172            return;
15173        }
15174
15175        if (mLastBroadcastStats != null) {
15176            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15177            if (fullCheckin) {
15178                mLastBroadcastStats = null;
15179                return;
15180            }
15181        }
15182        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15183        if (fullCheckin) {
15184            mCurBroadcastStats = null;
15185        }
15186    }
15187
15188    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15189            int opti, boolean dumpAll, String dumpPackage) {
15190        boolean needSep;
15191        boolean printedAnything = false;
15192
15193        ItemMatcher matcher = new ItemMatcher();
15194        matcher.build(args, opti);
15195
15196        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15197
15198        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15199        printedAnything |= needSep;
15200
15201        if (mLaunchingProviders.size() > 0) {
15202            boolean printed = false;
15203            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15204                ContentProviderRecord r = mLaunchingProviders.get(i);
15205                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15206                    continue;
15207                }
15208                if (!printed) {
15209                    if (needSep) pw.println();
15210                    needSep = true;
15211                    pw.println("  Launching content providers:");
15212                    printed = true;
15213                    printedAnything = true;
15214                }
15215                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15216                        pw.println(r);
15217            }
15218        }
15219
15220        if (!printedAnything) {
15221            pw.println("  (nothing)");
15222        }
15223    }
15224
15225    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15226            int opti, boolean dumpAll, String dumpPackage) {
15227        boolean needSep = false;
15228        boolean printedAnything = false;
15229
15230        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15231
15232        if (mGrantedUriPermissions.size() > 0) {
15233            boolean printed = false;
15234            int dumpUid = -2;
15235            if (dumpPackage != null) {
15236                try {
15237                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15238                            MATCH_UNINSTALLED_PACKAGES, 0);
15239                } catch (NameNotFoundException e) {
15240                    dumpUid = -1;
15241                }
15242            }
15243            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15244                int uid = mGrantedUriPermissions.keyAt(i);
15245                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15246                    continue;
15247                }
15248                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15249                if (!printed) {
15250                    if (needSep) pw.println();
15251                    needSep = true;
15252                    pw.println("  Granted Uri Permissions:");
15253                    printed = true;
15254                    printedAnything = true;
15255                }
15256                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15257                for (UriPermission perm : perms.values()) {
15258                    pw.print("    "); pw.println(perm);
15259                    if (dumpAll) {
15260                        perm.dump(pw, "      ");
15261                    }
15262                }
15263            }
15264        }
15265
15266        if (!printedAnything) {
15267            pw.println("  (nothing)");
15268        }
15269    }
15270
15271    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15272            int opti, boolean dumpAll, String dumpPackage) {
15273        boolean printed = false;
15274
15275        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15276
15277        if (mIntentSenderRecords.size() > 0) {
15278            Iterator<WeakReference<PendingIntentRecord>> it
15279                    = mIntentSenderRecords.values().iterator();
15280            while (it.hasNext()) {
15281                WeakReference<PendingIntentRecord> ref = it.next();
15282                PendingIntentRecord rec = ref != null ? ref.get(): null;
15283                if (dumpPackage != null && (rec == null
15284                        || !dumpPackage.equals(rec.key.packageName))) {
15285                    continue;
15286                }
15287                printed = true;
15288                if (rec != null) {
15289                    pw.print("  * "); pw.println(rec);
15290                    if (dumpAll) {
15291                        rec.dump(pw, "    ");
15292                    }
15293                } else {
15294                    pw.print("  * "); pw.println(ref);
15295                }
15296            }
15297        }
15298
15299        if (!printed) {
15300            pw.println("  (nothing)");
15301        }
15302    }
15303
15304    private static final int dumpProcessList(PrintWriter pw,
15305            ActivityManagerService service, List list,
15306            String prefix, String normalLabel, String persistentLabel,
15307            String dumpPackage) {
15308        int numPers = 0;
15309        final int N = list.size()-1;
15310        for (int i=N; i>=0; i--) {
15311            ProcessRecord r = (ProcessRecord)list.get(i);
15312            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15313                continue;
15314            }
15315            pw.println(String.format("%s%s #%2d: %s",
15316                    prefix, (r.persistent ? persistentLabel : normalLabel),
15317                    i, r.toString()));
15318            if (r.persistent) {
15319                numPers++;
15320            }
15321        }
15322        return numPers;
15323    }
15324
15325    private static final boolean dumpProcessOomList(PrintWriter pw,
15326            ActivityManagerService service, List<ProcessRecord> origList,
15327            String prefix, String normalLabel, String persistentLabel,
15328            boolean inclDetails, String dumpPackage) {
15329
15330        ArrayList<Pair<ProcessRecord, Integer>> list
15331                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15332        for (int i=0; i<origList.size(); i++) {
15333            ProcessRecord r = origList.get(i);
15334            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15335                continue;
15336            }
15337            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15338        }
15339
15340        if (list.size() <= 0) {
15341            return false;
15342        }
15343
15344        Comparator<Pair<ProcessRecord, Integer>> comparator
15345                = new Comparator<Pair<ProcessRecord, Integer>>() {
15346            @Override
15347            public int compare(Pair<ProcessRecord, Integer> object1,
15348                    Pair<ProcessRecord, Integer> object2) {
15349                if (object1.first.setAdj != object2.first.setAdj) {
15350                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15351                }
15352                if (object1.first.setProcState != object2.first.setProcState) {
15353                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15354                }
15355                if (object1.second.intValue() != object2.second.intValue()) {
15356                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15357                }
15358                return 0;
15359            }
15360        };
15361
15362        Collections.sort(list, comparator);
15363
15364        final long curRealtime = SystemClock.elapsedRealtime();
15365        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15366        final long curUptime = SystemClock.uptimeMillis();
15367        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15368
15369        for (int i=list.size()-1; i>=0; i--) {
15370            ProcessRecord r = list.get(i).first;
15371            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15372            char schedGroup;
15373            switch (r.setSchedGroup) {
15374                case ProcessList.SCHED_GROUP_BACKGROUND:
15375                    schedGroup = 'B';
15376                    break;
15377                case ProcessList.SCHED_GROUP_DEFAULT:
15378                    schedGroup = 'F';
15379                    break;
15380                case ProcessList.SCHED_GROUP_TOP_APP:
15381                    schedGroup = 'T';
15382                    break;
15383                default:
15384                    schedGroup = '?';
15385                    break;
15386            }
15387            char foreground;
15388            if (r.foregroundActivities) {
15389                foreground = 'A';
15390            } else if (r.foregroundServices) {
15391                foreground = 'S';
15392            } else {
15393                foreground = ' ';
15394            }
15395            String procState = ProcessList.makeProcStateString(r.curProcState);
15396            pw.print(prefix);
15397            pw.print(r.persistent ? persistentLabel : normalLabel);
15398            pw.print(" #");
15399            int num = (origList.size()-1)-list.get(i).second;
15400            if (num < 10) pw.print(' ');
15401            pw.print(num);
15402            pw.print(": ");
15403            pw.print(oomAdj);
15404            pw.print(' ');
15405            pw.print(schedGroup);
15406            pw.print('/');
15407            pw.print(foreground);
15408            pw.print('/');
15409            pw.print(procState);
15410            pw.print(" trm:");
15411            if (r.trimMemoryLevel < 10) pw.print(' ');
15412            pw.print(r.trimMemoryLevel);
15413            pw.print(' ');
15414            pw.print(r.toShortString());
15415            pw.print(" (");
15416            pw.print(r.adjType);
15417            pw.println(')');
15418            if (r.adjSource != null || r.adjTarget != null) {
15419                pw.print(prefix);
15420                pw.print("    ");
15421                if (r.adjTarget instanceof ComponentName) {
15422                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15423                } else if (r.adjTarget != null) {
15424                    pw.print(r.adjTarget.toString());
15425                } else {
15426                    pw.print("{null}");
15427                }
15428                pw.print("<=");
15429                if (r.adjSource instanceof ProcessRecord) {
15430                    pw.print("Proc{");
15431                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15432                    pw.println("}");
15433                } else if (r.adjSource != null) {
15434                    pw.println(r.adjSource.toString());
15435                } else {
15436                    pw.println("{null}");
15437                }
15438            }
15439            if (inclDetails) {
15440                pw.print(prefix);
15441                pw.print("    ");
15442                pw.print("oom: max="); pw.print(r.maxAdj);
15443                pw.print(" curRaw="); pw.print(r.curRawAdj);
15444                pw.print(" setRaw="); pw.print(r.setRawAdj);
15445                pw.print(" cur="); pw.print(r.curAdj);
15446                pw.print(" set="); pw.println(r.setAdj);
15447                pw.print(prefix);
15448                pw.print("    ");
15449                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15450                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15451                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15452                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15453                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15454                pw.println();
15455                pw.print(prefix);
15456                pw.print("    ");
15457                pw.print("cached="); pw.print(r.cached);
15458                pw.print(" empty="); pw.print(r.empty);
15459                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15460
15461                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15462                    if (r.lastWakeTime != 0) {
15463                        long wtime;
15464                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15465                        synchronized (stats) {
15466                            wtime = stats.getProcessWakeTime(r.info.uid,
15467                                    r.pid, curRealtime);
15468                        }
15469                        long timeUsed = wtime - r.lastWakeTime;
15470                        pw.print(prefix);
15471                        pw.print("    ");
15472                        pw.print("keep awake over ");
15473                        TimeUtils.formatDuration(realtimeSince, pw);
15474                        pw.print(" used ");
15475                        TimeUtils.formatDuration(timeUsed, pw);
15476                        pw.print(" (");
15477                        pw.print((timeUsed*100)/realtimeSince);
15478                        pw.println("%)");
15479                    }
15480                    if (r.lastCpuTime != 0) {
15481                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15482                        pw.print(prefix);
15483                        pw.print("    ");
15484                        pw.print("run cpu over ");
15485                        TimeUtils.formatDuration(uptimeSince, pw);
15486                        pw.print(" used ");
15487                        TimeUtils.formatDuration(timeUsed, pw);
15488                        pw.print(" (");
15489                        pw.print((timeUsed*100)/uptimeSince);
15490                        pw.println("%)");
15491                    }
15492                }
15493            }
15494        }
15495        return true;
15496    }
15497
15498    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15499            String[] args) {
15500        ArrayList<ProcessRecord> procs;
15501        synchronized (this) {
15502            if (args != null && args.length > start
15503                    && args[start].charAt(0) != '-') {
15504                procs = new ArrayList<ProcessRecord>();
15505                int pid = -1;
15506                try {
15507                    pid = Integer.parseInt(args[start]);
15508                } catch (NumberFormatException e) {
15509                }
15510                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15511                    ProcessRecord proc = mLruProcesses.get(i);
15512                    if (proc.pid == pid) {
15513                        procs.add(proc);
15514                    } else if (allPkgs && proc.pkgList != null
15515                            && proc.pkgList.containsKey(args[start])) {
15516                        procs.add(proc);
15517                    } else if (proc.processName.equals(args[start])) {
15518                        procs.add(proc);
15519                    }
15520                }
15521                if (procs.size() <= 0) {
15522                    return null;
15523                }
15524            } else {
15525                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15526            }
15527        }
15528        return procs;
15529    }
15530
15531    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15532            PrintWriter pw, String[] args) {
15533        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15534        if (procs == null) {
15535            pw.println("No process found for: " + args[0]);
15536            return;
15537        }
15538
15539        long uptime = SystemClock.uptimeMillis();
15540        long realtime = SystemClock.elapsedRealtime();
15541        pw.println("Applications Graphics Acceleration Info:");
15542        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15543
15544        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15545            ProcessRecord r = procs.get(i);
15546            if (r.thread != null) {
15547                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15548                pw.flush();
15549                try {
15550                    TransferPipe tp = new TransferPipe();
15551                    try {
15552                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15553                        tp.go(fd);
15554                    } finally {
15555                        tp.kill();
15556                    }
15557                } catch (IOException e) {
15558                    pw.println("Failure while dumping the app: " + r);
15559                    pw.flush();
15560                } catch (RemoteException e) {
15561                    pw.println("Got a RemoteException while dumping the app " + r);
15562                    pw.flush();
15563                }
15564            }
15565        }
15566    }
15567
15568    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15569        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15570        if (procs == null) {
15571            pw.println("No process found for: " + args[0]);
15572            return;
15573        }
15574
15575        pw.println("Applications Database Info:");
15576
15577        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15578            ProcessRecord r = procs.get(i);
15579            if (r.thread != null) {
15580                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15581                pw.flush();
15582                try {
15583                    TransferPipe tp = new TransferPipe();
15584                    try {
15585                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15586                        tp.go(fd);
15587                    } finally {
15588                        tp.kill();
15589                    }
15590                } catch (IOException e) {
15591                    pw.println("Failure while dumping the app: " + r);
15592                    pw.flush();
15593                } catch (RemoteException e) {
15594                    pw.println("Got a RemoteException while dumping the app " + r);
15595                    pw.flush();
15596                }
15597            }
15598        }
15599    }
15600
15601    final static class MemItem {
15602        final boolean isProc;
15603        final String label;
15604        final String shortLabel;
15605        final long pss;
15606        final long swapPss;
15607        final int id;
15608        final boolean hasActivities;
15609        ArrayList<MemItem> subitems;
15610
15611        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15612                boolean _hasActivities) {
15613            isProc = true;
15614            label = _label;
15615            shortLabel = _shortLabel;
15616            pss = _pss;
15617            swapPss = _swapPss;
15618            id = _id;
15619            hasActivities = _hasActivities;
15620        }
15621
15622        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15623            isProc = false;
15624            label = _label;
15625            shortLabel = _shortLabel;
15626            pss = _pss;
15627            swapPss = _swapPss;
15628            id = _id;
15629            hasActivities = false;
15630        }
15631    }
15632
15633    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15634            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15635        if (sort && !isCompact) {
15636            Collections.sort(items, new Comparator<MemItem>() {
15637                @Override
15638                public int compare(MemItem lhs, MemItem rhs) {
15639                    if (lhs.pss < rhs.pss) {
15640                        return 1;
15641                    } else if (lhs.pss > rhs.pss) {
15642                        return -1;
15643                    }
15644                    return 0;
15645                }
15646            });
15647        }
15648
15649        for (int i=0; i<items.size(); i++) {
15650            MemItem mi = items.get(i);
15651            if (!isCompact) {
15652                if (dumpSwapPss) {
15653                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15654                            mi.label, stringifyKBSize(mi.swapPss));
15655                } else {
15656                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15657                }
15658            } else if (mi.isProc) {
15659                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15660                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15661                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15662                pw.println(mi.hasActivities ? ",a" : ",e");
15663            } else {
15664                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15665                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15666            }
15667            if (mi.subitems != null) {
15668                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15669                        true, isCompact, dumpSwapPss);
15670            }
15671        }
15672    }
15673
15674    // These are in KB.
15675    static final long[] DUMP_MEM_BUCKETS = new long[] {
15676        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15677        120*1024, 160*1024, 200*1024,
15678        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15679        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15680    };
15681
15682    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15683            boolean stackLike) {
15684        int start = label.lastIndexOf('.');
15685        if (start >= 0) start++;
15686        else start = 0;
15687        int end = label.length();
15688        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15689            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15690                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15691                out.append(bucket);
15692                out.append(stackLike ? "MB." : "MB ");
15693                out.append(label, start, end);
15694                return;
15695            }
15696        }
15697        out.append(memKB/1024);
15698        out.append(stackLike ? "MB." : "MB ");
15699        out.append(label, start, end);
15700    }
15701
15702    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15703            ProcessList.NATIVE_ADJ,
15704            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15705            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15706            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15707            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15708            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15709            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15710    };
15711    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15712            "Native",
15713            "System", "Persistent", "Persistent Service", "Foreground",
15714            "Visible", "Perceptible",
15715            "Heavy Weight", "Backup",
15716            "A Services", "Home",
15717            "Previous", "B Services", "Cached"
15718    };
15719    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15720            "native",
15721            "sys", "pers", "persvc", "fore",
15722            "vis", "percept",
15723            "heavy", "backup",
15724            "servicea", "home",
15725            "prev", "serviceb", "cached"
15726    };
15727
15728    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15729            long realtime, boolean isCheckinRequest, boolean isCompact) {
15730        if (isCompact) {
15731            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15732        }
15733        if (isCheckinRequest || isCompact) {
15734            // short checkin version
15735            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15736        } else {
15737            pw.println("Applications Memory Usage (in Kilobytes):");
15738            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15739        }
15740    }
15741
15742    private static final int KSM_SHARED = 0;
15743    private static final int KSM_SHARING = 1;
15744    private static final int KSM_UNSHARED = 2;
15745    private static final int KSM_VOLATILE = 3;
15746
15747    private final long[] getKsmInfo() {
15748        long[] longOut = new long[4];
15749        final int[] SINGLE_LONG_FORMAT = new int[] {
15750            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15751        };
15752        long[] longTmp = new long[1];
15753        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15754                SINGLE_LONG_FORMAT, null, longTmp, null);
15755        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15756        longTmp[0] = 0;
15757        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15758                SINGLE_LONG_FORMAT, null, longTmp, null);
15759        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15760        longTmp[0] = 0;
15761        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15762                SINGLE_LONG_FORMAT, null, longTmp, null);
15763        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15764        longTmp[0] = 0;
15765        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15766                SINGLE_LONG_FORMAT, null, longTmp, null);
15767        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15768        return longOut;
15769    }
15770
15771    private static String stringifySize(long size, int order) {
15772        Locale locale = Locale.US;
15773        switch (order) {
15774            case 1:
15775                return String.format(locale, "%,13d", size);
15776            case 1024:
15777                return String.format(locale, "%,9dK", size / 1024);
15778            case 1024 * 1024:
15779                return String.format(locale, "%,5dM", size / 1024 / 1024);
15780            case 1024 * 1024 * 1024:
15781                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15782            default:
15783                throw new IllegalArgumentException("Invalid size order");
15784        }
15785    }
15786
15787    private static String stringifyKBSize(long size) {
15788        return stringifySize(size * 1024, 1024);
15789    }
15790
15791    // Update this version number in case you change the 'compact' format
15792    private static final int MEMINFO_COMPACT_VERSION = 1;
15793
15794    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15795            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15796        boolean dumpDetails = false;
15797        boolean dumpFullDetails = false;
15798        boolean dumpDalvik = false;
15799        boolean dumpSummaryOnly = false;
15800        boolean dumpUnreachable = false;
15801        boolean oomOnly = false;
15802        boolean isCompact = false;
15803        boolean localOnly = false;
15804        boolean packages = false;
15805        boolean isCheckinRequest = false;
15806        boolean dumpSwapPss = false;
15807
15808        int opti = 0;
15809        while (opti < args.length) {
15810            String opt = args[opti];
15811            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15812                break;
15813            }
15814            opti++;
15815            if ("-a".equals(opt)) {
15816                dumpDetails = true;
15817                dumpFullDetails = true;
15818                dumpDalvik = true;
15819                dumpSwapPss = true;
15820            } else if ("-d".equals(opt)) {
15821                dumpDalvik = true;
15822            } else if ("-c".equals(opt)) {
15823                isCompact = true;
15824            } else if ("-s".equals(opt)) {
15825                dumpDetails = true;
15826                dumpSummaryOnly = true;
15827            } else if ("-S".equals(opt)) {
15828                dumpSwapPss = true;
15829            } else if ("--unreachable".equals(opt)) {
15830                dumpUnreachable = true;
15831            } else if ("--oom".equals(opt)) {
15832                oomOnly = true;
15833            } else if ("--local".equals(opt)) {
15834                localOnly = true;
15835            } else if ("--package".equals(opt)) {
15836                packages = true;
15837            } else if ("--checkin".equals(opt)) {
15838                isCheckinRequest = true;
15839
15840            } else if ("-h".equals(opt)) {
15841                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15842                pw.println("  -a: include all available information for each process.");
15843                pw.println("  -d: include dalvik details.");
15844                pw.println("  -c: dump in a compact machine-parseable representation.");
15845                pw.println("  -s: dump only summary of application memory usage.");
15846                pw.println("  -S: dump also SwapPss.");
15847                pw.println("  --oom: only show processes organized by oom adj.");
15848                pw.println("  --local: only collect details locally, don't call process.");
15849                pw.println("  --package: interpret process arg as package, dumping all");
15850                pw.println("             processes that have loaded that package.");
15851                pw.println("  --checkin: dump data for a checkin");
15852                pw.println("If [process] is specified it can be the name or ");
15853                pw.println("pid of a specific process to dump.");
15854                return;
15855            } else {
15856                pw.println("Unknown argument: " + opt + "; use -h for help");
15857            }
15858        }
15859
15860        long uptime = SystemClock.uptimeMillis();
15861        long realtime = SystemClock.elapsedRealtime();
15862        final long[] tmpLong = new long[1];
15863
15864        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15865        if (procs == null) {
15866            // No Java processes.  Maybe they want to print a native process.
15867            if (args != null && args.length > opti
15868                    && args[opti].charAt(0) != '-') {
15869                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15870                        = new ArrayList<ProcessCpuTracker.Stats>();
15871                updateCpuStatsNow();
15872                int findPid = -1;
15873                try {
15874                    findPid = Integer.parseInt(args[opti]);
15875                } catch (NumberFormatException e) {
15876                }
15877                synchronized (mProcessCpuTracker) {
15878                    final int N = mProcessCpuTracker.countStats();
15879                    for (int i=0; i<N; i++) {
15880                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15881                        if (st.pid == findPid || (st.baseName != null
15882                                && st.baseName.equals(args[opti]))) {
15883                            nativeProcs.add(st);
15884                        }
15885                    }
15886                }
15887                if (nativeProcs.size() > 0) {
15888                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15889                            isCompact);
15890                    Debug.MemoryInfo mi = null;
15891                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15892                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15893                        final int pid = r.pid;
15894                        if (!isCheckinRequest && dumpDetails) {
15895                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15896                        }
15897                        if (mi == null) {
15898                            mi = new Debug.MemoryInfo();
15899                        }
15900                        if (dumpDetails || (!brief && !oomOnly)) {
15901                            Debug.getMemoryInfo(pid, mi);
15902                        } else {
15903                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15904                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15905                        }
15906                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15907                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15908                        if (isCheckinRequest) {
15909                            pw.println();
15910                        }
15911                    }
15912                    return;
15913                }
15914            }
15915            pw.println("No process found for: " + args[opti]);
15916            return;
15917        }
15918
15919        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15920            dumpDetails = true;
15921        }
15922
15923        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15924
15925        String[] innerArgs = new String[args.length-opti];
15926        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15927
15928        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15929        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15930        long nativePss = 0;
15931        long nativeSwapPss = 0;
15932        long dalvikPss = 0;
15933        long dalvikSwapPss = 0;
15934        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15935                EmptyArray.LONG;
15936        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15937                EmptyArray.LONG;
15938        long otherPss = 0;
15939        long otherSwapPss = 0;
15940        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15941        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15942
15943        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15944        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15945        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15946                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15947
15948        long totalPss = 0;
15949        long totalSwapPss = 0;
15950        long cachedPss = 0;
15951        long cachedSwapPss = 0;
15952        boolean hasSwapPss = false;
15953
15954        Debug.MemoryInfo mi = null;
15955        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15956            final ProcessRecord r = procs.get(i);
15957            final IApplicationThread thread;
15958            final int pid;
15959            final int oomAdj;
15960            final boolean hasActivities;
15961            synchronized (this) {
15962                thread = r.thread;
15963                pid = r.pid;
15964                oomAdj = r.getSetAdjWithServices();
15965                hasActivities = r.activities.size() > 0;
15966            }
15967            if (thread != null) {
15968                if (!isCheckinRequest && dumpDetails) {
15969                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15970                }
15971                if (mi == null) {
15972                    mi = new Debug.MemoryInfo();
15973                }
15974                if (dumpDetails || (!brief && !oomOnly)) {
15975                    Debug.getMemoryInfo(pid, mi);
15976                    hasSwapPss = mi.hasSwappedOutPss;
15977                } else {
15978                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15979                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15980                }
15981                if (dumpDetails) {
15982                    if (localOnly) {
15983                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15984                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15985                        if (isCheckinRequest) {
15986                            pw.println();
15987                        }
15988                    } else {
15989                        try {
15990                            pw.flush();
15991                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15992                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15993                        } catch (RemoteException e) {
15994                            if (!isCheckinRequest) {
15995                                pw.println("Got RemoteException!");
15996                                pw.flush();
15997                            }
15998                        }
15999                    }
16000                }
16001
16002                final long myTotalPss = mi.getTotalPss();
16003                final long myTotalUss = mi.getTotalUss();
16004                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16005
16006                synchronized (this) {
16007                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16008                        // Record this for posterity if the process has been stable.
16009                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16010                    }
16011                }
16012
16013                if (!isCheckinRequest && mi != null) {
16014                    totalPss += myTotalPss;
16015                    totalSwapPss += myTotalSwapPss;
16016                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16017                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16018                            myTotalSwapPss, pid, hasActivities);
16019                    procMems.add(pssItem);
16020                    procMemsMap.put(pid, pssItem);
16021
16022                    nativePss += mi.nativePss;
16023                    nativeSwapPss += mi.nativeSwappedOutPss;
16024                    dalvikPss += mi.dalvikPss;
16025                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16026                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16027                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16028                        dalvikSubitemSwapPss[j] +=
16029                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16030                    }
16031                    otherPss += mi.otherPss;
16032                    otherSwapPss += mi.otherSwappedOutPss;
16033                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16034                        long mem = mi.getOtherPss(j);
16035                        miscPss[j] += mem;
16036                        otherPss -= mem;
16037                        mem = mi.getOtherSwappedOutPss(j);
16038                        miscSwapPss[j] += mem;
16039                        otherSwapPss -= mem;
16040                    }
16041
16042                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16043                        cachedPss += myTotalPss;
16044                        cachedSwapPss += myTotalSwapPss;
16045                    }
16046
16047                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16048                        if (oomIndex == (oomPss.length - 1)
16049                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16050                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16051                            oomPss[oomIndex] += myTotalPss;
16052                            oomSwapPss[oomIndex] += myTotalSwapPss;
16053                            if (oomProcs[oomIndex] == null) {
16054                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16055                            }
16056                            oomProcs[oomIndex].add(pssItem);
16057                            break;
16058                        }
16059                    }
16060                }
16061            }
16062        }
16063
16064        long nativeProcTotalPss = 0;
16065
16066        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16067            // If we are showing aggregations, also look for native processes to
16068            // include so that our aggregations are more accurate.
16069            updateCpuStatsNow();
16070            mi = null;
16071            synchronized (mProcessCpuTracker) {
16072                final int N = mProcessCpuTracker.countStats();
16073                for (int i=0; i<N; i++) {
16074                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16075                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16076                        if (mi == null) {
16077                            mi = new Debug.MemoryInfo();
16078                        }
16079                        if (!brief && !oomOnly) {
16080                            Debug.getMemoryInfo(st.pid, mi);
16081                        } else {
16082                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16083                            mi.nativePrivateDirty = (int)tmpLong[0];
16084                        }
16085
16086                        final long myTotalPss = mi.getTotalPss();
16087                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16088                        totalPss += myTotalPss;
16089                        nativeProcTotalPss += myTotalPss;
16090
16091                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16092                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16093                        procMems.add(pssItem);
16094
16095                        nativePss += mi.nativePss;
16096                        nativeSwapPss += mi.nativeSwappedOutPss;
16097                        dalvikPss += mi.dalvikPss;
16098                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16099                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16100                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16101                            dalvikSubitemSwapPss[j] +=
16102                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16103                        }
16104                        otherPss += mi.otherPss;
16105                        otherSwapPss += mi.otherSwappedOutPss;
16106                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16107                            long mem = mi.getOtherPss(j);
16108                            miscPss[j] += mem;
16109                            otherPss -= mem;
16110                            mem = mi.getOtherSwappedOutPss(j);
16111                            miscSwapPss[j] += mem;
16112                            otherSwapPss -= mem;
16113                        }
16114                        oomPss[0] += myTotalPss;
16115                        oomSwapPss[0] += myTotalSwapPss;
16116                        if (oomProcs[0] == null) {
16117                            oomProcs[0] = new ArrayList<MemItem>();
16118                        }
16119                        oomProcs[0].add(pssItem);
16120                    }
16121                }
16122            }
16123
16124            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16125
16126            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16127            final MemItem dalvikItem =
16128                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16129            if (dalvikSubitemPss.length > 0) {
16130                dalvikItem.subitems = new ArrayList<MemItem>();
16131                for (int j=0; j<dalvikSubitemPss.length; j++) {
16132                    final String name = Debug.MemoryInfo.getOtherLabel(
16133                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16134                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16135                                    dalvikSubitemSwapPss[j], j));
16136                }
16137            }
16138            catMems.add(dalvikItem);
16139            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16140            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16141                String label = Debug.MemoryInfo.getOtherLabel(j);
16142                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16143            }
16144
16145            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16146            for (int j=0; j<oomPss.length; j++) {
16147                if (oomPss[j] != 0) {
16148                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16149                            : DUMP_MEM_OOM_LABEL[j];
16150                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16151                            DUMP_MEM_OOM_ADJ[j]);
16152                    item.subitems = oomProcs[j];
16153                    oomMems.add(item);
16154                }
16155            }
16156
16157            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16158            if (!brief && !oomOnly && !isCompact) {
16159                pw.println();
16160                pw.println("Total PSS by process:");
16161                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16162                pw.println();
16163            }
16164            if (!isCompact) {
16165                pw.println("Total PSS by OOM adjustment:");
16166            }
16167            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16168            if (!brief && !oomOnly) {
16169                PrintWriter out = categoryPw != null ? categoryPw : pw;
16170                if (!isCompact) {
16171                    out.println();
16172                    out.println("Total PSS by category:");
16173                }
16174                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16175            }
16176            if (!isCompact) {
16177                pw.println();
16178            }
16179            MemInfoReader memInfo = new MemInfoReader();
16180            memInfo.readMemInfo();
16181            if (nativeProcTotalPss > 0) {
16182                synchronized (this) {
16183                    final long cachedKb = memInfo.getCachedSizeKb();
16184                    final long freeKb = memInfo.getFreeSizeKb();
16185                    final long zramKb = memInfo.getZramTotalSizeKb();
16186                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16187                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16188                            kernelKb*1024, nativeProcTotalPss*1024);
16189                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16190                            nativeProcTotalPss);
16191                }
16192            }
16193            if (!brief) {
16194                if (!isCompact) {
16195                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16196                    pw.print(" (status ");
16197                    switch (mLastMemoryLevel) {
16198                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16199                            pw.println("normal)");
16200                            break;
16201                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16202                            pw.println("moderate)");
16203                            break;
16204                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16205                            pw.println("low)");
16206                            break;
16207                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16208                            pw.println("critical)");
16209                            break;
16210                        default:
16211                            pw.print(mLastMemoryLevel);
16212                            pw.println(")");
16213                            break;
16214                    }
16215                    pw.print(" Free RAM: ");
16216                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16217                            + memInfo.getFreeSizeKb()));
16218                    pw.print(" (");
16219                    pw.print(stringifyKBSize(cachedPss));
16220                    pw.print(" cached pss + ");
16221                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16222                    pw.print(" cached kernel + ");
16223                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16224                    pw.println(" free)");
16225                } else {
16226                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16227                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16228                            + memInfo.getFreeSizeKb()); pw.print(",");
16229                    pw.println(totalPss - cachedPss);
16230                }
16231            }
16232            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16233                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16234                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16235            if (!isCompact) {
16236                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16237                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16238                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16239                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16240                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16241            } else {
16242                pw.print("lostram,"); pw.println(lostRAM);
16243            }
16244            if (!brief) {
16245                if (memInfo.getZramTotalSizeKb() != 0) {
16246                    if (!isCompact) {
16247                        pw.print("     ZRAM: ");
16248                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16249                                pw.print(" physical used for ");
16250                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16251                                        - memInfo.getSwapFreeSizeKb()));
16252                                pw.print(" in swap (");
16253                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16254                                pw.println(" total swap)");
16255                    } else {
16256                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16257                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16258                                pw.println(memInfo.getSwapFreeSizeKb());
16259                    }
16260                }
16261                final long[] ksm = getKsmInfo();
16262                if (!isCompact) {
16263                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16264                            || ksm[KSM_VOLATILE] != 0) {
16265                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16266                                pw.print(" saved from shared ");
16267                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16268                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16269                                pw.print(" unshared; ");
16270                                pw.print(stringifyKBSize(
16271                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16272                    }
16273                    pw.print("   Tuning: ");
16274                    pw.print(ActivityManager.staticGetMemoryClass());
16275                    pw.print(" (large ");
16276                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16277                    pw.print("), oom ");
16278                    pw.print(stringifySize(
16279                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16280                    pw.print(", restore limit ");
16281                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16282                    if (ActivityManager.isLowRamDeviceStatic()) {
16283                        pw.print(" (low-ram)");
16284                    }
16285                    if (ActivityManager.isHighEndGfx()) {
16286                        pw.print(" (high-end-gfx)");
16287                    }
16288                    pw.println();
16289                } else {
16290                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16291                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16292                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16293                    pw.print("tuning,");
16294                    pw.print(ActivityManager.staticGetMemoryClass());
16295                    pw.print(',');
16296                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16297                    pw.print(',');
16298                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16299                    if (ActivityManager.isLowRamDeviceStatic()) {
16300                        pw.print(",low-ram");
16301                    }
16302                    if (ActivityManager.isHighEndGfx()) {
16303                        pw.print(",high-end-gfx");
16304                    }
16305                    pw.println();
16306                }
16307            }
16308        }
16309    }
16310
16311    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16312            long memtrack, String name) {
16313        sb.append("  ");
16314        sb.append(ProcessList.makeOomAdjString(oomAdj));
16315        sb.append(' ');
16316        sb.append(ProcessList.makeProcStateString(procState));
16317        sb.append(' ');
16318        ProcessList.appendRamKb(sb, pss);
16319        sb.append(": ");
16320        sb.append(name);
16321        if (memtrack > 0) {
16322            sb.append(" (");
16323            sb.append(stringifyKBSize(memtrack));
16324            sb.append(" memtrack)");
16325        }
16326    }
16327
16328    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16329        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16330        sb.append(" (pid ");
16331        sb.append(mi.pid);
16332        sb.append(") ");
16333        sb.append(mi.adjType);
16334        sb.append('\n');
16335        if (mi.adjReason != null) {
16336            sb.append("                      ");
16337            sb.append(mi.adjReason);
16338            sb.append('\n');
16339        }
16340    }
16341
16342    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16343        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16344        for (int i=0, N=memInfos.size(); i<N; i++) {
16345            ProcessMemInfo mi = memInfos.get(i);
16346            infoMap.put(mi.pid, mi);
16347        }
16348        updateCpuStatsNow();
16349        long[] memtrackTmp = new long[1];
16350        synchronized (mProcessCpuTracker) {
16351            final int N = mProcessCpuTracker.countStats();
16352            for (int i=0; i<N; i++) {
16353                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16354                if (st.vsize > 0) {
16355                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16356                    if (pss > 0) {
16357                        if (infoMap.indexOfKey(st.pid) < 0) {
16358                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16359                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16360                            mi.pss = pss;
16361                            mi.memtrack = memtrackTmp[0];
16362                            memInfos.add(mi);
16363                        }
16364                    }
16365                }
16366            }
16367        }
16368
16369        long totalPss = 0;
16370        long totalMemtrack = 0;
16371        for (int i=0, N=memInfos.size(); i<N; i++) {
16372            ProcessMemInfo mi = memInfos.get(i);
16373            if (mi.pss == 0) {
16374                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16375                mi.memtrack = memtrackTmp[0];
16376            }
16377            totalPss += mi.pss;
16378            totalMemtrack += mi.memtrack;
16379        }
16380        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16381            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16382                if (lhs.oomAdj != rhs.oomAdj) {
16383                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16384                }
16385                if (lhs.pss != rhs.pss) {
16386                    return lhs.pss < rhs.pss ? 1 : -1;
16387                }
16388                return 0;
16389            }
16390        });
16391
16392        StringBuilder tag = new StringBuilder(128);
16393        StringBuilder stack = new StringBuilder(128);
16394        tag.append("Low on memory -- ");
16395        appendMemBucket(tag, totalPss, "total", false);
16396        appendMemBucket(stack, totalPss, "total", true);
16397
16398        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16399        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16400        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16401
16402        boolean firstLine = true;
16403        int lastOomAdj = Integer.MIN_VALUE;
16404        long extraNativeRam = 0;
16405        long extraNativeMemtrack = 0;
16406        long cachedPss = 0;
16407        for (int i=0, N=memInfos.size(); i<N; i++) {
16408            ProcessMemInfo mi = memInfos.get(i);
16409
16410            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16411                cachedPss += mi.pss;
16412            }
16413
16414            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16415                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16416                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16417                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16418                if (lastOomAdj != mi.oomAdj) {
16419                    lastOomAdj = mi.oomAdj;
16420                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16421                        tag.append(" / ");
16422                    }
16423                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16424                        if (firstLine) {
16425                            stack.append(":");
16426                            firstLine = false;
16427                        }
16428                        stack.append("\n\t at ");
16429                    } else {
16430                        stack.append("$");
16431                    }
16432                } else {
16433                    tag.append(" ");
16434                    stack.append("$");
16435                }
16436                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16437                    appendMemBucket(tag, mi.pss, mi.name, false);
16438                }
16439                appendMemBucket(stack, mi.pss, mi.name, true);
16440                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16441                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16442                    stack.append("(");
16443                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16444                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16445                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16446                            stack.append(":");
16447                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16448                        }
16449                    }
16450                    stack.append(")");
16451                }
16452            }
16453
16454            appendMemInfo(fullNativeBuilder, mi);
16455            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16456                // The short form only has native processes that are >= 512K.
16457                if (mi.pss >= 512) {
16458                    appendMemInfo(shortNativeBuilder, mi);
16459                } else {
16460                    extraNativeRam += mi.pss;
16461                    extraNativeMemtrack += mi.memtrack;
16462                }
16463            } else {
16464                // Short form has all other details, but if we have collected RAM
16465                // from smaller native processes let's dump a summary of that.
16466                if (extraNativeRam > 0) {
16467                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16468                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16469                    shortNativeBuilder.append('\n');
16470                    extraNativeRam = 0;
16471                }
16472                appendMemInfo(fullJavaBuilder, mi);
16473            }
16474        }
16475
16476        fullJavaBuilder.append("           ");
16477        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16478        fullJavaBuilder.append(": TOTAL");
16479        if (totalMemtrack > 0) {
16480            fullJavaBuilder.append(" (");
16481            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16482            fullJavaBuilder.append(" memtrack)");
16483        } else {
16484        }
16485        fullJavaBuilder.append("\n");
16486
16487        MemInfoReader memInfo = new MemInfoReader();
16488        memInfo.readMemInfo();
16489        final long[] infos = memInfo.getRawInfo();
16490
16491        StringBuilder memInfoBuilder = new StringBuilder(1024);
16492        Debug.getMemInfo(infos);
16493        memInfoBuilder.append("  MemInfo: ");
16494        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16495        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16496        memInfoBuilder.append(stringifyKBSize(
16497                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16498        memInfoBuilder.append(stringifyKBSize(
16499                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16500        memInfoBuilder.append(stringifyKBSize(
16501                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16502        memInfoBuilder.append("           ");
16503        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16504        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16505        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16506        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16507        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16508            memInfoBuilder.append("  ZRAM: ");
16509            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16510            memInfoBuilder.append(" RAM, ");
16511            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16512            memInfoBuilder.append(" swap total, ");
16513            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16514            memInfoBuilder.append(" swap free\n");
16515        }
16516        final long[] ksm = getKsmInfo();
16517        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16518                || ksm[KSM_VOLATILE] != 0) {
16519            memInfoBuilder.append("  KSM: ");
16520            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16521            memInfoBuilder.append(" saved from shared ");
16522            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16523            memInfoBuilder.append("\n       ");
16524            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16525            memInfoBuilder.append(" unshared; ");
16526            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16527            memInfoBuilder.append(" volatile\n");
16528        }
16529        memInfoBuilder.append("  Free RAM: ");
16530        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16531                + memInfo.getFreeSizeKb()));
16532        memInfoBuilder.append("\n");
16533        memInfoBuilder.append("  Used RAM: ");
16534        memInfoBuilder.append(stringifyKBSize(
16535                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16536        memInfoBuilder.append("\n");
16537        memInfoBuilder.append("  Lost RAM: ");
16538        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16539                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16540                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16541        memInfoBuilder.append("\n");
16542        Slog.i(TAG, "Low on memory:");
16543        Slog.i(TAG, shortNativeBuilder.toString());
16544        Slog.i(TAG, fullJavaBuilder.toString());
16545        Slog.i(TAG, memInfoBuilder.toString());
16546
16547        StringBuilder dropBuilder = new StringBuilder(1024);
16548        /*
16549        StringWriter oomSw = new StringWriter();
16550        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16551        StringWriter catSw = new StringWriter();
16552        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16553        String[] emptyArgs = new String[] { };
16554        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16555        oomPw.flush();
16556        String oomString = oomSw.toString();
16557        */
16558        dropBuilder.append("Low on memory:");
16559        dropBuilder.append(stack);
16560        dropBuilder.append('\n');
16561        dropBuilder.append(fullNativeBuilder);
16562        dropBuilder.append(fullJavaBuilder);
16563        dropBuilder.append('\n');
16564        dropBuilder.append(memInfoBuilder);
16565        dropBuilder.append('\n');
16566        /*
16567        dropBuilder.append(oomString);
16568        dropBuilder.append('\n');
16569        */
16570        StringWriter catSw = new StringWriter();
16571        synchronized (ActivityManagerService.this) {
16572            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16573            String[] emptyArgs = new String[] { };
16574            catPw.println();
16575            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16576            catPw.println();
16577            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16578                    false, null).dumpLocked();
16579            catPw.println();
16580            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16581            catPw.flush();
16582        }
16583        dropBuilder.append(catSw.toString());
16584        addErrorToDropBox("lowmem", null, "system_server", null,
16585                null, tag.toString(), dropBuilder.toString(), null, null);
16586        //Slog.i(TAG, "Sent to dropbox:");
16587        //Slog.i(TAG, dropBuilder.toString());
16588        synchronized (ActivityManagerService.this) {
16589            long now = SystemClock.uptimeMillis();
16590            if (mLastMemUsageReportTime < now) {
16591                mLastMemUsageReportTime = now;
16592            }
16593        }
16594    }
16595
16596    /**
16597     * Searches array of arguments for the specified string
16598     * @param args array of argument strings
16599     * @param value value to search for
16600     * @return true if the value is contained in the array
16601     */
16602    private static boolean scanArgs(String[] args, String value) {
16603        if (args != null) {
16604            for (String arg : args) {
16605                if (value.equals(arg)) {
16606                    return true;
16607                }
16608            }
16609        }
16610        return false;
16611    }
16612
16613    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16614            ContentProviderRecord cpr, boolean always) {
16615        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16616
16617        if (!inLaunching || always) {
16618            synchronized (cpr) {
16619                cpr.launchingApp = null;
16620                cpr.notifyAll();
16621            }
16622            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16623            String names[] = cpr.info.authority.split(";");
16624            for (int j = 0; j < names.length; j++) {
16625                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16626            }
16627        }
16628
16629        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16630            ContentProviderConnection conn = cpr.connections.get(i);
16631            if (conn.waiting) {
16632                // If this connection is waiting for the provider, then we don't
16633                // need to mess with its process unless we are always removing
16634                // or for some reason the provider is not currently launching.
16635                if (inLaunching && !always) {
16636                    continue;
16637                }
16638            }
16639            ProcessRecord capp = conn.client;
16640            conn.dead = true;
16641            if (conn.stableCount > 0) {
16642                if (!capp.persistent && capp.thread != null
16643                        && capp.pid != 0
16644                        && capp.pid != MY_PID) {
16645                    capp.kill("depends on provider "
16646                            + cpr.name.flattenToShortString()
16647                            + " in dying proc " + (proc != null ? proc.processName : "??")
16648                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16649                }
16650            } else if (capp.thread != null && conn.provider.provider != null) {
16651                try {
16652                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16653                } catch (RemoteException e) {
16654                }
16655                // In the protocol here, we don't expect the client to correctly
16656                // clean up this connection, we'll just remove it.
16657                cpr.connections.remove(i);
16658                if (conn.client.conProviders.remove(conn)) {
16659                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16660                }
16661            }
16662        }
16663
16664        if (inLaunching && always) {
16665            mLaunchingProviders.remove(cpr);
16666        }
16667        return inLaunching;
16668    }
16669
16670    /**
16671     * Main code for cleaning up a process when it has gone away.  This is
16672     * called both as a result of the process dying, or directly when stopping
16673     * a process when running in single process mode.
16674     *
16675     * @return Returns true if the given process has been restarted, so the
16676     * app that was passed in must remain on the process lists.
16677     */
16678    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16679            boolean restarting, boolean allowRestart, int index) {
16680        if (index >= 0) {
16681            removeLruProcessLocked(app);
16682            ProcessList.remove(app.pid);
16683        }
16684
16685        mProcessesToGc.remove(app);
16686        mPendingPssProcesses.remove(app);
16687
16688        // Dismiss any open dialogs.
16689        if (app.crashDialog != null && !app.forceCrashReport) {
16690            app.crashDialog.dismiss();
16691            app.crashDialog = null;
16692        }
16693        if (app.anrDialog != null) {
16694            app.anrDialog.dismiss();
16695            app.anrDialog = null;
16696        }
16697        if (app.waitDialog != null) {
16698            app.waitDialog.dismiss();
16699            app.waitDialog = null;
16700        }
16701
16702        app.crashing = false;
16703        app.notResponding = false;
16704
16705        app.resetPackageList(mProcessStats);
16706        app.unlinkDeathRecipient();
16707        app.makeInactive(mProcessStats);
16708        app.waitingToKill = null;
16709        app.forcingToForeground = null;
16710        updateProcessForegroundLocked(app, false, false);
16711        app.foregroundActivities = false;
16712        app.hasShownUi = false;
16713        app.treatLikeActivity = false;
16714        app.hasAboveClient = false;
16715        app.hasClientActivities = false;
16716
16717        mServices.killServicesLocked(app, allowRestart);
16718
16719        boolean restart = false;
16720
16721        // Remove published content providers.
16722        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16723            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16724            final boolean always = app.bad || !allowRestart;
16725            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16726            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16727                // We left the provider in the launching list, need to
16728                // restart it.
16729                restart = true;
16730            }
16731
16732            cpr.provider = null;
16733            cpr.proc = null;
16734        }
16735        app.pubProviders.clear();
16736
16737        // Take care of any launching providers waiting for this process.
16738        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16739            restart = true;
16740        }
16741
16742        // Unregister from connected content providers.
16743        if (!app.conProviders.isEmpty()) {
16744            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16745                ContentProviderConnection conn = app.conProviders.get(i);
16746                conn.provider.connections.remove(conn);
16747                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16748                        conn.provider.name);
16749            }
16750            app.conProviders.clear();
16751        }
16752
16753        // At this point there may be remaining entries in mLaunchingProviders
16754        // where we were the only one waiting, so they are no longer of use.
16755        // Look for these and clean up if found.
16756        // XXX Commented out for now.  Trying to figure out a way to reproduce
16757        // the actual situation to identify what is actually going on.
16758        if (false) {
16759            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16760                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16761                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16762                    synchronized (cpr) {
16763                        cpr.launchingApp = null;
16764                        cpr.notifyAll();
16765                    }
16766                }
16767            }
16768        }
16769
16770        skipCurrentReceiverLocked(app);
16771
16772        // Unregister any receivers.
16773        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16774            removeReceiverLocked(app.receivers.valueAt(i));
16775        }
16776        app.receivers.clear();
16777
16778        // If the app is undergoing backup, tell the backup manager about it
16779        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16780            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16781                    + mBackupTarget.appInfo + " died during backup");
16782            mHandler.post(new Runnable() {
16783                @Override
16784                public void run(){
16785                    try {
16786                        IBackupManager bm = IBackupManager.Stub.asInterface(
16787                                ServiceManager.getService(Context.BACKUP_SERVICE));
16788                        bm.agentDisconnected(app.info.packageName);
16789                    } catch (RemoteException e) {
16790                        // can't happen; backup manager is local
16791                    }
16792                }
16793            });
16794        }
16795
16796        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16797            ProcessChangeItem item = mPendingProcessChanges.get(i);
16798            if (item.pid == app.pid) {
16799                mPendingProcessChanges.remove(i);
16800                mAvailProcessChanges.add(item);
16801            }
16802        }
16803        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16804                null).sendToTarget();
16805
16806        // If the caller is restarting this app, then leave it in its
16807        // current lists and let the caller take care of it.
16808        if (restarting) {
16809            return false;
16810        }
16811
16812        if (!app.persistent || app.isolated) {
16813            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16814                    "Removing non-persistent process during cleanup: " + app);
16815            removeProcessNameLocked(app.processName, app.uid);
16816            if (mHeavyWeightProcess == app) {
16817                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16818                        mHeavyWeightProcess.userId, 0));
16819                mHeavyWeightProcess = null;
16820            }
16821        } else if (!app.removed) {
16822            // This app is persistent, so we need to keep its record around.
16823            // If it is not already on the pending app list, add it there
16824            // and start a new process for it.
16825            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16826                mPersistentStartingProcesses.add(app);
16827                restart = true;
16828            }
16829        }
16830        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16831                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16832        mProcessesOnHold.remove(app);
16833
16834        if (app == mHomeProcess) {
16835            mHomeProcess = null;
16836        }
16837        if (app == mPreviousProcess) {
16838            mPreviousProcess = null;
16839        }
16840
16841        if (restart && !app.isolated) {
16842            // We have components that still need to be running in the
16843            // process, so re-launch it.
16844            if (index < 0) {
16845                ProcessList.remove(app.pid);
16846            }
16847            addProcessNameLocked(app);
16848            startProcessLocked(app, "restart", app.processName);
16849            return true;
16850        } else if (app.pid > 0 && app.pid != MY_PID) {
16851            // Goodbye!
16852            boolean removed;
16853            synchronized (mPidsSelfLocked) {
16854                mPidsSelfLocked.remove(app.pid);
16855                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16856            }
16857            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16858            if (app.isolated) {
16859                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16860            }
16861            app.setPid(0);
16862        }
16863        return false;
16864    }
16865
16866    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16867        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16868            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16869            if (cpr.launchingApp == app) {
16870                return true;
16871            }
16872        }
16873        return false;
16874    }
16875
16876    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16877        // Look through the content providers we are waiting to have launched,
16878        // and if any run in this process then either schedule a restart of
16879        // the process or kill the client waiting for it if this process has
16880        // gone bad.
16881        boolean restart = false;
16882        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16883            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16884            if (cpr.launchingApp == app) {
16885                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16886                    restart = true;
16887                } else {
16888                    removeDyingProviderLocked(app, cpr, true);
16889                }
16890            }
16891        }
16892        return restart;
16893    }
16894
16895    // =========================================================
16896    // SERVICES
16897    // =========================================================
16898
16899    @Override
16900    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16901            int flags) {
16902        enforceNotIsolatedCaller("getServices");
16903        synchronized (this) {
16904            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16905        }
16906    }
16907
16908    @Override
16909    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16910        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16911        synchronized (this) {
16912            return mServices.getRunningServiceControlPanelLocked(name);
16913        }
16914    }
16915
16916    @Override
16917    public ComponentName startService(IApplicationThread caller, Intent service,
16918            String resolvedType, String callingPackage, int userId)
16919            throws TransactionTooLargeException {
16920        enforceNotIsolatedCaller("startService");
16921        // Refuse possible leaked file descriptors
16922        if (service != null && service.hasFileDescriptors() == true) {
16923            throw new IllegalArgumentException("File descriptors passed in Intent");
16924        }
16925
16926        if (callingPackage == null) {
16927            throw new IllegalArgumentException("callingPackage cannot be null");
16928        }
16929
16930        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16931                "startService: " + service + " type=" + resolvedType);
16932        synchronized(this) {
16933            final int callingPid = Binder.getCallingPid();
16934            final int callingUid = Binder.getCallingUid();
16935            final long origId = Binder.clearCallingIdentity();
16936            ComponentName res = mServices.startServiceLocked(caller, service,
16937                    resolvedType, callingPid, callingUid, callingPackage, userId);
16938            Binder.restoreCallingIdentity(origId);
16939            return res;
16940        }
16941    }
16942
16943    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16944            String callingPackage, int userId)
16945            throws TransactionTooLargeException {
16946        synchronized(this) {
16947            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16948                    "startServiceInPackage: " + service + " type=" + resolvedType);
16949            final long origId = Binder.clearCallingIdentity();
16950            ComponentName res = mServices.startServiceLocked(null, service,
16951                    resolvedType, -1, uid, callingPackage, userId);
16952            Binder.restoreCallingIdentity(origId);
16953            return res;
16954        }
16955    }
16956
16957    @Override
16958    public int stopService(IApplicationThread caller, Intent service,
16959            String resolvedType, int userId) {
16960        enforceNotIsolatedCaller("stopService");
16961        // Refuse possible leaked file descriptors
16962        if (service != null && service.hasFileDescriptors() == true) {
16963            throw new IllegalArgumentException("File descriptors passed in Intent");
16964        }
16965
16966        synchronized(this) {
16967            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16968        }
16969    }
16970
16971    @Override
16972    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16973        enforceNotIsolatedCaller("peekService");
16974        // Refuse possible leaked file descriptors
16975        if (service != null && service.hasFileDescriptors() == true) {
16976            throw new IllegalArgumentException("File descriptors passed in Intent");
16977        }
16978
16979        if (callingPackage == null) {
16980            throw new IllegalArgumentException("callingPackage cannot be null");
16981        }
16982
16983        synchronized(this) {
16984            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16985        }
16986    }
16987
16988    @Override
16989    public boolean stopServiceToken(ComponentName className, IBinder token,
16990            int startId) {
16991        synchronized(this) {
16992            return mServices.stopServiceTokenLocked(className, token, startId);
16993        }
16994    }
16995
16996    @Override
16997    public void setServiceForeground(ComponentName className, IBinder token,
16998            int id, Notification notification, int flags) {
16999        synchronized(this) {
17000            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17001        }
17002    }
17003
17004    @Override
17005    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17006            boolean requireFull, String name, String callerPackage) {
17007        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17008                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17009    }
17010
17011    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17012            String className, int flags) {
17013        boolean result = false;
17014        // For apps that don't have pre-defined UIDs, check for permission
17015        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17016            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17017                if (ActivityManager.checkUidPermission(
17018                        INTERACT_ACROSS_USERS,
17019                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17020                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17021                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17022                            + " requests FLAG_SINGLE_USER, but app does not hold "
17023                            + INTERACT_ACROSS_USERS;
17024                    Slog.w(TAG, msg);
17025                    throw new SecurityException(msg);
17026                }
17027                // Permission passed
17028                result = true;
17029            }
17030        } else if ("system".equals(componentProcessName)) {
17031            result = true;
17032        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17033            // Phone app and persistent apps are allowed to export singleuser providers.
17034            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17035                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17036        }
17037        if (DEBUG_MU) Slog.v(TAG_MU,
17038                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17039                + Integer.toHexString(flags) + ") = " + result);
17040        return result;
17041    }
17042
17043    /**
17044     * Checks to see if the caller is in the same app as the singleton
17045     * component, or the component is in a special app. It allows special apps
17046     * to export singleton components but prevents exporting singleton
17047     * components for regular apps.
17048     */
17049    boolean isValidSingletonCall(int callingUid, int componentUid) {
17050        int componentAppId = UserHandle.getAppId(componentUid);
17051        return UserHandle.isSameApp(callingUid, componentUid)
17052                || componentAppId == Process.SYSTEM_UID
17053                || componentAppId == Process.PHONE_UID
17054                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17055                        == PackageManager.PERMISSION_GRANTED;
17056    }
17057
17058    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17059            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17060            int userId) throws TransactionTooLargeException {
17061        enforceNotIsolatedCaller("bindService");
17062
17063        // Refuse possible leaked file descriptors
17064        if (service != null && service.hasFileDescriptors() == true) {
17065            throw new IllegalArgumentException("File descriptors passed in Intent");
17066        }
17067
17068        if (callingPackage == null) {
17069            throw new IllegalArgumentException("callingPackage cannot be null");
17070        }
17071
17072        synchronized(this) {
17073            return mServices.bindServiceLocked(caller, token, service,
17074                    resolvedType, connection, flags, callingPackage, userId);
17075        }
17076    }
17077
17078    public boolean unbindService(IServiceConnection connection) {
17079        synchronized (this) {
17080            return mServices.unbindServiceLocked(connection);
17081        }
17082    }
17083
17084    public void publishService(IBinder token, Intent intent, IBinder service) {
17085        // Refuse possible leaked file descriptors
17086        if (intent != null && intent.hasFileDescriptors() == true) {
17087            throw new IllegalArgumentException("File descriptors passed in Intent");
17088        }
17089
17090        synchronized(this) {
17091            if (!(token instanceof ServiceRecord)) {
17092                throw new IllegalArgumentException("Invalid service token");
17093            }
17094            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17095        }
17096    }
17097
17098    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17099        // Refuse possible leaked file descriptors
17100        if (intent != null && intent.hasFileDescriptors() == true) {
17101            throw new IllegalArgumentException("File descriptors passed in Intent");
17102        }
17103
17104        synchronized(this) {
17105            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17106        }
17107    }
17108
17109    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17110        synchronized(this) {
17111            if (!(token instanceof ServiceRecord)) {
17112                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17113                throw new IllegalArgumentException("Invalid service token");
17114            }
17115            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17116        }
17117    }
17118
17119    // =========================================================
17120    // BACKUP AND RESTORE
17121    // =========================================================
17122
17123    // Cause the target app to be launched if necessary and its backup agent
17124    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17125    // activity manager to announce its creation.
17126    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17127        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17128        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17129
17130        IPackageManager pm = AppGlobals.getPackageManager();
17131        ApplicationInfo app = null;
17132        try {
17133            app = pm.getApplicationInfo(packageName, 0, userId);
17134        } catch (RemoteException e) {
17135            // can't happen; package manager is process-local
17136        }
17137        if (app == null) {
17138            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17139            return false;
17140        }
17141
17142        synchronized(this) {
17143            // !!! TODO: currently no check here that we're already bound
17144            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17145            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17146            synchronized (stats) {
17147                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17148            }
17149
17150            // Backup agent is now in use, its package can't be stopped.
17151            try {
17152                AppGlobals.getPackageManager().setPackageStoppedState(
17153                        app.packageName, false, UserHandle.getUserId(app.uid));
17154            } catch (RemoteException e) {
17155            } catch (IllegalArgumentException e) {
17156                Slog.w(TAG, "Failed trying to unstop package "
17157                        + app.packageName + ": " + e);
17158            }
17159
17160            BackupRecord r = new BackupRecord(ss, app, backupMode);
17161            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17162                    ? new ComponentName(app.packageName, app.backupAgentName)
17163                    : new ComponentName("android", "FullBackupAgent");
17164            // startProcessLocked() returns existing proc's record if it's already running
17165            ProcessRecord proc = startProcessLocked(app.processName, app,
17166                    false, 0, "backup", hostingName, false, false, false);
17167            if (proc == null) {
17168                Slog.e(TAG, "Unable to start backup agent process " + r);
17169                return false;
17170            }
17171
17172            // If the app is a regular app (uid >= 10000) and not the system server or phone
17173            // process, etc, then mark it as being in full backup so that certain calls to the
17174            // process can be blocked. This is not reset to false anywhere because we kill the
17175            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17176            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17177                proc.inFullBackup = true;
17178            }
17179            r.app = proc;
17180            mBackupTarget = r;
17181            mBackupAppName = app.packageName;
17182
17183            // Try not to kill the process during backup
17184            updateOomAdjLocked(proc);
17185
17186            // If the process is already attached, schedule the creation of the backup agent now.
17187            // If it is not yet live, this will be done when it attaches to the framework.
17188            if (proc.thread != null) {
17189                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17190                try {
17191                    proc.thread.scheduleCreateBackupAgent(app,
17192                            compatibilityInfoForPackageLocked(app), backupMode);
17193                } catch (RemoteException e) {
17194                    // Will time out on the backup manager side
17195                }
17196            } else {
17197                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17198            }
17199            // Invariants: at this point, the target app process exists and the application
17200            // is either already running or in the process of coming up.  mBackupTarget and
17201            // mBackupAppName describe the app, so that when it binds back to the AM we
17202            // know that it's scheduled for a backup-agent operation.
17203        }
17204
17205        return true;
17206    }
17207
17208    @Override
17209    public void clearPendingBackup() {
17210        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17211        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17212
17213        synchronized (this) {
17214            mBackupTarget = null;
17215            mBackupAppName = null;
17216        }
17217    }
17218
17219    // A backup agent has just come up
17220    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17221        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17222                + " = " + agent);
17223
17224        synchronized(this) {
17225            if (!agentPackageName.equals(mBackupAppName)) {
17226                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17227                return;
17228            }
17229        }
17230
17231        long oldIdent = Binder.clearCallingIdentity();
17232        try {
17233            IBackupManager bm = IBackupManager.Stub.asInterface(
17234                    ServiceManager.getService(Context.BACKUP_SERVICE));
17235            bm.agentConnected(agentPackageName, agent);
17236        } catch (RemoteException e) {
17237            // can't happen; the backup manager service is local
17238        } catch (Exception e) {
17239            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17240            e.printStackTrace();
17241        } finally {
17242            Binder.restoreCallingIdentity(oldIdent);
17243        }
17244    }
17245
17246    // done with this agent
17247    public void unbindBackupAgent(ApplicationInfo appInfo) {
17248        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17249        if (appInfo == null) {
17250            Slog.w(TAG, "unbind backup agent for null app");
17251            return;
17252        }
17253
17254        synchronized(this) {
17255            try {
17256                if (mBackupAppName == null) {
17257                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17258                    return;
17259                }
17260
17261                if (!mBackupAppName.equals(appInfo.packageName)) {
17262                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17263                    return;
17264                }
17265
17266                // Not backing this app up any more; reset its OOM adjustment
17267                final ProcessRecord proc = mBackupTarget.app;
17268                updateOomAdjLocked(proc);
17269
17270                // If the app crashed during backup, 'thread' will be null here
17271                if (proc.thread != null) {
17272                    try {
17273                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17274                                compatibilityInfoForPackageLocked(appInfo));
17275                    } catch (Exception e) {
17276                        Slog.e(TAG, "Exception when unbinding backup agent:");
17277                        e.printStackTrace();
17278                    }
17279                }
17280            } finally {
17281                mBackupTarget = null;
17282                mBackupAppName = null;
17283            }
17284        }
17285    }
17286    // =========================================================
17287    // BROADCASTS
17288    // =========================================================
17289
17290    boolean isPendingBroadcastProcessLocked(int pid) {
17291        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17292                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17293    }
17294
17295    void skipPendingBroadcastLocked(int pid) {
17296            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17297            for (BroadcastQueue queue : mBroadcastQueues) {
17298                queue.skipPendingBroadcastLocked(pid);
17299            }
17300    }
17301
17302    // The app just attached; send any pending broadcasts that it should receive
17303    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17304        boolean didSomething = false;
17305        for (BroadcastQueue queue : mBroadcastQueues) {
17306            didSomething |= queue.sendPendingBroadcastsLocked(app);
17307        }
17308        return didSomething;
17309    }
17310
17311    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17312            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17313        enforceNotIsolatedCaller("registerReceiver");
17314        ArrayList<Intent> stickyIntents = null;
17315        ProcessRecord callerApp = null;
17316        int callingUid;
17317        int callingPid;
17318        synchronized(this) {
17319            if (caller != null) {
17320                callerApp = getRecordForAppLocked(caller);
17321                if (callerApp == null) {
17322                    throw new SecurityException(
17323                            "Unable to find app for caller " + caller
17324                            + " (pid=" + Binder.getCallingPid()
17325                            + ") when registering receiver " + receiver);
17326                }
17327                if (callerApp.info.uid != Process.SYSTEM_UID &&
17328                        !callerApp.pkgList.containsKey(callerPackage) &&
17329                        !"android".equals(callerPackage)) {
17330                    throw new SecurityException("Given caller package " + callerPackage
17331                            + " is not running in process " + callerApp);
17332                }
17333                callingUid = callerApp.info.uid;
17334                callingPid = callerApp.pid;
17335            } else {
17336                callerPackage = null;
17337                callingUid = Binder.getCallingUid();
17338                callingPid = Binder.getCallingPid();
17339            }
17340
17341            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17342                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17343
17344            Iterator<String> actions = filter.actionsIterator();
17345            if (actions == null) {
17346                ArrayList<String> noAction = new ArrayList<String>(1);
17347                noAction.add(null);
17348                actions = noAction.iterator();
17349            }
17350
17351            // Collect stickies of users
17352            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17353            while (actions.hasNext()) {
17354                String action = actions.next();
17355                for (int id : userIds) {
17356                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17357                    if (stickies != null) {
17358                        ArrayList<Intent> intents = stickies.get(action);
17359                        if (intents != null) {
17360                            if (stickyIntents == null) {
17361                                stickyIntents = new ArrayList<Intent>();
17362                            }
17363                            stickyIntents.addAll(intents);
17364                        }
17365                    }
17366                }
17367            }
17368        }
17369
17370        ArrayList<Intent> allSticky = null;
17371        if (stickyIntents != null) {
17372            final ContentResolver resolver = mContext.getContentResolver();
17373            // Look for any matching sticky broadcasts...
17374            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17375                Intent intent = stickyIntents.get(i);
17376                // If intent has scheme "content", it will need to acccess
17377                // provider that needs to lock mProviderMap in ActivityThread
17378                // and also it may need to wait application response, so we
17379                // cannot lock ActivityManagerService here.
17380                if (filter.match(resolver, intent, true, TAG) >= 0) {
17381                    if (allSticky == null) {
17382                        allSticky = new ArrayList<Intent>();
17383                    }
17384                    allSticky.add(intent);
17385                }
17386            }
17387        }
17388
17389        // The first sticky in the list is returned directly back to the client.
17390        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17391        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17392        if (receiver == null) {
17393            return sticky;
17394        }
17395
17396        synchronized (this) {
17397            if (callerApp != null && (callerApp.thread == null
17398                    || callerApp.thread.asBinder() != caller.asBinder())) {
17399                // Original caller already died
17400                return null;
17401            }
17402            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17403            if (rl == null) {
17404                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17405                        userId, receiver);
17406                if (rl.app != null) {
17407                    rl.app.receivers.add(rl);
17408                } else {
17409                    try {
17410                        receiver.asBinder().linkToDeath(rl, 0);
17411                    } catch (RemoteException e) {
17412                        return sticky;
17413                    }
17414                    rl.linkedToDeath = true;
17415                }
17416                mRegisteredReceivers.put(receiver.asBinder(), rl);
17417            } else if (rl.uid != callingUid) {
17418                throw new IllegalArgumentException(
17419                        "Receiver requested to register for uid " + callingUid
17420                        + " was previously registered for uid " + rl.uid);
17421            } else if (rl.pid != callingPid) {
17422                throw new IllegalArgumentException(
17423                        "Receiver requested to register for pid " + callingPid
17424                        + " was previously registered for pid " + rl.pid);
17425            } else if (rl.userId != userId) {
17426                throw new IllegalArgumentException(
17427                        "Receiver requested to register for user " + userId
17428                        + " was previously registered for user " + rl.userId);
17429            }
17430            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17431                    permission, callingUid, userId);
17432            rl.add(bf);
17433            if (!bf.debugCheck()) {
17434                Slog.w(TAG, "==> For Dynamic broadcast");
17435            }
17436            mReceiverResolver.addFilter(bf);
17437
17438            // Enqueue broadcasts for all existing stickies that match
17439            // this filter.
17440            if (allSticky != null) {
17441                ArrayList receivers = new ArrayList();
17442                receivers.add(bf);
17443
17444                final int stickyCount = allSticky.size();
17445                for (int i = 0; i < stickyCount; i++) {
17446                    Intent intent = allSticky.get(i);
17447                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17448                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17449                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17450                            null, 0, null, null, false, true, true, -1);
17451                    queue.enqueueParallelBroadcastLocked(r);
17452                    queue.scheduleBroadcastsLocked();
17453                }
17454            }
17455
17456            return sticky;
17457        }
17458    }
17459
17460    public void unregisterReceiver(IIntentReceiver receiver) {
17461        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17462
17463        final long origId = Binder.clearCallingIdentity();
17464        try {
17465            boolean doTrim = false;
17466
17467            synchronized(this) {
17468                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17469                if (rl != null) {
17470                    final BroadcastRecord r = rl.curBroadcast;
17471                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17472                        final boolean doNext = r.queue.finishReceiverLocked(
17473                                r, r.resultCode, r.resultData, r.resultExtras,
17474                                r.resultAbort, false);
17475                        if (doNext) {
17476                            doTrim = true;
17477                            r.queue.processNextBroadcast(false);
17478                        }
17479                    }
17480
17481                    if (rl.app != null) {
17482                        rl.app.receivers.remove(rl);
17483                    }
17484                    removeReceiverLocked(rl);
17485                    if (rl.linkedToDeath) {
17486                        rl.linkedToDeath = false;
17487                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17488                    }
17489                }
17490            }
17491
17492            // If we actually concluded any broadcasts, we might now be able
17493            // to trim the recipients' apps from our working set
17494            if (doTrim) {
17495                trimApplications();
17496                return;
17497            }
17498
17499        } finally {
17500            Binder.restoreCallingIdentity(origId);
17501        }
17502    }
17503
17504    void removeReceiverLocked(ReceiverList rl) {
17505        mRegisteredReceivers.remove(rl.receiver.asBinder());
17506        for (int i = rl.size() - 1; i >= 0; i--) {
17507            mReceiverResolver.removeFilter(rl.get(i));
17508        }
17509    }
17510
17511    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17512        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17513            ProcessRecord r = mLruProcesses.get(i);
17514            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17515                try {
17516                    r.thread.dispatchPackageBroadcast(cmd, packages);
17517                } catch (RemoteException ex) {
17518                }
17519            }
17520        }
17521    }
17522
17523    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17524            int callingUid, int[] users) {
17525        // TODO: come back and remove this assumption to triage all broadcasts
17526        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17527
17528        List<ResolveInfo> receivers = null;
17529        try {
17530            HashSet<ComponentName> singleUserReceivers = null;
17531            boolean scannedFirstReceivers = false;
17532            for (int user : users) {
17533                // Skip users that have Shell restrictions, with exception of always permitted
17534                // Shell broadcasts
17535                if (callingUid == Process.SHELL_UID
17536                        && mUserController.hasUserRestriction(
17537                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17538                        && !isPermittedShellBroadcast(intent)) {
17539                    continue;
17540                }
17541                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17542                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17543                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17544                    // If this is not the system user, we need to check for
17545                    // any receivers that should be filtered out.
17546                    for (int i=0; i<newReceivers.size(); i++) {
17547                        ResolveInfo ri = newReceivers.get(i);
17548                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17549                            newReceivers.remove(i);
17550                            i--;
17551                        }
17552                    }
17553                }
17554                if (newReceivers != null && newReceivers.size() == 0) {
17555                    newReceivers = null;
17556                }
17557                if (receivers == null) {
17558                    receivers = newReceivers;
17559                } else if (newReceivers != null) {
17560                    // We need to concatenate the additional receivers
17561                    // found with what we have do far.  This would be easy,
17562                    // but we also need to de-dup any receivers that are
17563                    // singleUser.
17564                    if (!scannedFirstReceivers) {
17565                        // Collect any single user receivers we had already retrieved.
17566                        scannedFirstReceivers = true;
17567                        for (int i=0; i<receivers.size(); i++) {
17568                            ResolveInfo ri = receivers.get(i);
17569                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17570                                ComponentName cn = new ComponentName(
17571                                        ri.activityInfo.packageName, ri.activityInfo.name);
17572                                if (singleUserReceivers == null) {
17573                                    singleUserReceivers = new HashSet<ComponentName>();
17574                                }
17575                                singleUserReceivers.add(cn);
17576                            }
17577                        }
17578                    }
17579                    // Add the new results to the existing results, tracking
17580                    // and de-dupping single user receivers.
17581                    for (int i=0; i<newReceivers.size(); i++) {
17582                        ResolveInfo ri = newReceivers.get(i);
17583                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17584                            ComponentName cn = new ComponentName(
17585                                    ri.activityInfo.packageName, ri.activityInfo.name);
17586                            if (singleUserReceivers == null) {
17587                                singleUserReceivers = new HashSet<ComponentName>();
17588                            }
17589                            if (!singleUserReceivers.contains(cn)) {
17590                                singleUserReceivers.add(cn);
17591                                receivers.add(ri);
17592                            }
17593                        } else {
17594                            receivers.add(ri);
17595                        }
17596                    }
17597                }
17598            }
17599        } catch (RemoteException ex) {
17600            // pm is in same process, this will never happen.
17601        }
17602        return receivers;
17603    }
17604
17605    private boolean isPermittedShellBroadcast(Intent intent) {
17606        // remote bugreport should always be allowed to be taken
17607        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17608    }
17609
17610    final int broadcastIntentLocked(ProcessRecord callerApp,
17611            String callerPackage, Intent intent, String resolvedType,
17612            IIntentReceiver resultTo, int resultCode, String resultData,
17613            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17614            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17615        intent = new Intent(intent);
17616
17617        // By default broadcasts do not go to stopped apps.
17618        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17619
17620        // If we have not finished booting, don't allow this to launch new processes.
17621        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17622            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17623        }
17624
17625        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17626                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17627                + " ordered=" + ordered + " userid=" + userId);
17628        if ((resultTo != null) && !ordered) {
17629            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17630        }
17631
17632        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17633                ALLOW_NON_FULL, "broadcast", callerPackage);
17634
17635        // Make sure that the user who is receiving this broadcast is running.
17636        // If not, we will just skip it. Make an exception for shutdown broadcasts
17637        // and upgrade steps.
17638
17639        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17640            if ((callingUid != Process.SYSTEM_UID
17641                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17642                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17643                Slog.w(TAG, "Skipping broadcast of " + intent
17644                        + ": user " + userId + " is stopped");
17645                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17646            }
17647        }
17648
17649        BroadcastOptions brOptions = null;
17650        if (bOptions != null) {
17651            brOptions = new BroadcastOptions(bOptions);
17652            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17653                // See if the caller is allowed to do this.  Note we are checking against
17654                // the actual real caller (not whoever provided the operation as say a
17655                // PendingIntent), because that who is actually supplied the arguments.
17656                if (checkComponentPermission(
17657                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17658                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17659                        != PackageManager.PERMISSION_GRANTED) {
17660                    String msg = "Permission Denial: " + intent.getAction()
17661                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17662                            + ", uid=" + callingUid + ")"
17663                            + " requires "
17664                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17665                    Slog.w(TAG, msg);
17666                    throw new SecurityException(msg);
17667                }
17668            }
17669        }
17670
17671        // Verify that protected broadcasts are only being sent by system code,
17672        // and that system code is only sending protected broadcasts.
17673        final String action = intent.getAction();
17674        final boolean isProtectedBroadcast;
17675        try {
17676            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17677        } catch (RemoteException e) {
17678            Slog.w(TAG, "Remote exception", e);
17679            return ActivityManager.BROADCAST_SUCCESS;
17680        }
17681
17682        final boolean isCallerSystem;
17683        switch (UserHandle.getAppId(callingUid)) {
17684            case Process.ROOT_UID:
17685            case Process.SYSTEM_UID:
17686            case Process.PHONE_UID:
17687            case Process.BLUETOOTH_UID:
17688            case Process.NFC_UID:
17689                isCallerSystem = true;
17690                break;
17691            default:
17692                isCallerSystem = (callerApp != null) && callerApp.persistent;
17693                break;
17694        }
17695
17696        if (isCallerSystem) {
17697            if (isProtectedBroadcast
17698                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17699                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17700                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17701                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17702                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17703                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17704                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17705                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17706                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17707                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17708                // Broadcast is either protected, or it's a public action that
17709                // we've relaxed, so it's fine for system internals to send.
17710            } else {
17711                // The vast majority of broadcasts sent from system internals
17712                // should be protected to avoid security holes, so yell loudly
17713                // to ensure we examine these cases.
17714                if (callerApp != null) {
17715                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17716                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17717                            new Throwable());
17718                } else {
17719                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17720                            + " from system uid " + UserHandle.formatUid(callingUid)
17721                            + " pkg " + callerPackage,
17722                            new Throwable());
17723                }
17724            }
17725
17726        } else {
17727            if (isProtectedBroadcast) {
17728                String msg = "Permission Denial: not allowed to send broadcast "
17729                        + action + " from pid="
17730                        + callingPid + ", uid=" + callingUid;
17731                Slog.w(TAG, msg);
17732                throw new SecurityException(msg);
17733
17734            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17735                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17736                // Special case for compatibility: we don't want apps to send this,
17737                // but historically it has not been protected and apps may be using it
17738                // to poke their own app widget.  So, instead of making it protected,
17739                // just limit it to the caller.
17740                if (callerPackage == null) {
17741                    String msg = "Permission Denial: not allowed to send broadcast "
17742                            + action + " from unknown caller.";
17743                    Slog.w(TAG, msg);
17744                    throw new SecurityException(msg);
17745                } else if (intent.getComponent() != null) {
17746                    // They are good enough to send to an explicit component...  verify
17747                    // it is being sent to the calling app.
17748                    if (!intent.getComponent().getPackageName().equals(
17749                            callerPackage)) {
17750                        String msg = "Permission Denial: not allowed to send broadcast "
17751                                + action + " to "
17752                                + intent.getComponent().getPackageName() + " from "
17753                                + callerPackage;
17754                        Slog.w(TAG, msg);
17755                        throw new SecurityException(msg);
17756                    }
17757                } else {
17758                    // Limit broadcast to their own package.
17759                    intent.setPackage(callerPackage);
17760                }
17761            }
17762        }
17763
17764        if (action != null) {
17765            switch (action) {
17766                case Intent.ACTION_UID_REMOVED:
17767                case Intent.ACTION_PACKAGE_REMOVED:
17768                case Intent.ACTION_PACKAGE_CHANGED:
17769                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17770                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17771                case Intent.ACTION_PACKAGES_SUSPENDED:
17772                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17773                    // Handle special intents: if this broadcast is from the package
17774                    // manager about a package being removed, we need to remove all of
17775                    // its activities from the history stack.
17776                    if (checkComponentPermission(
17777                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17778                            callingPid, callingUid, -1, true)
17779                            != PackageManager.PERMISSION_GRANTED) {
17780                        String msg = "Permission Denial: " + intent.getAction()
17781                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17782                                + ", uid=" + callingUid + ")"
17783                                + " requires "
17784                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17785                        Slog.w(TAG, msg);
17786                        throw new SecurityException(msg);
17787                    }
17788                    switch (action) {
17789                        case Intent.ACTION_UID_REMOVED:
17790                            final Bundle intentExtras = intent.getExtras();
17791                            final int uid = intentExtras != null
17792                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17793                            if (uid >= 0) {
17794                                mBatteryStatsService.removeUid(uid);
17795                                mAppOpsService.uidRemoved(uid);
17796                            }
17797                            break;
17798                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17799                            // If resources are unavailable just force stop all those packages
17800                            // and flush the attribute cache as well.
17801                            String list[] =
17802                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17803                            if (list != null && list.length > 0) {
17804                                for (int i = 0; i < list.length; i++) {
17805                                    forceStopPackageLocked(list[i], -1, false, true, true,
17806                                            false, false, userId, "storage unmount");
17807                                }
17808                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17809                                sendPackageBroadcastLocked(
17810                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17811                                        userId);
17812                            }
17813                            break;
17814                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17815                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17816                            break;
17817                        case Intent.ACTION_PACKAGE_REMOVED:
17818                        case Intent.ACTION_PACKAGE_CHANGED:
17819                            Uri data = intent.getData();
17820                            String ssp;
17821                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17822                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17823                                final boolean replacing =
17824                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17825                                final boolean killProcess =
17826                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17827                                final boolean fullUninstall = removed && !replacing;
17828                                if (removed) {
17829                                    if (killProcess) {
17830                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17831                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17832                                                false, true, true, false, fullUninstall, userId,
17833                                                removed ? "pkg removed" : "pkg changed");
17834                                    }
17835                                    final int cmd = killProcess
17836                                            ? IApplicationThread.PACKAGE_REMOVED
17837                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17838                                    sendPackageBroadcastLocked(cmd,
17839                                            new String[] {ssp}, userId);
17840                                    if (fullUninstall) {
17841                                        mAppOpsService.packageRemoved(
17842                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17843
17844                                        // Remove all permissions granted from/to this package
17845                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17846
17847                                        removeTasksByPackageNameLocked(ssp, userId);
17848
17849                                        // Hide the "unsupported display" dialog if necessary.
17850                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17851                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17852                                            mUnsupportedDisplaySizeDialog.dismiss();
17853                                            mUnsupportedDisplaySizeDialog = null;
17854                                        }
17855                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17856                                        mBatteryStatsService.notePackageUninstalled(ssp);
17857                                    }
17858                                } else {
17859                                    if (killProcess) {
17860                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17861                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17862                                                userId, ProcessList.INVALID_ADJ,
17863                                                false, true, true, false, "change " + ssp);
17864                                    }
17865                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17866                                            intent.getStringArrayExtra(
17867                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17868                                }
17869                            }
17870                            break;
17871                        case Intent.ACTION_PACKAGES_SUSPENDED:
17872                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17873                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17874                                    intent.getAction());
17875                            final String[] packageNames = intent.getStringArrayExtra(
17876                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17877                            final int userHandle = intent.getIntExtra(
17878                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17879
17880                            synchronized(ActivityManagerService.this) {
17881                                mRecentTasks.onPackagesSuspendedChanged(
17882                                        packageNames, suspended, userHandle);
17883                            }
17884                            break;
17885                    }
17886                    break;
17887                case Intent.ACTION_PACKAGE_REPLACED:
17888                {
17889                    final Uri data = intent.getData();
17890                    final String ssp;
17891                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17892                        final ApplicationInfo aInfo =
17893                                getPackageManagerInternalLocked().getApplicationInfo(
17894                                        ssp,
17895                                        userId);
17896                        if (aInfo == null) {
17897                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17898                                    + " ssp=" + ssp + " data=" + data);
17899                            return ActivityManager.BROADCAST_SUCCESS;
17900                        }
17901                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17902                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17903                                new String[] {ssp}, userId);
17904                    }
17905                    break;
17906                }
17907                case Intent.ACTION_PACKAGE_ADDED:
17908                {
17909                    // Special case for adding a package: by default turn on compatibility mode.
17910                    Uri data = intent.getData();
17911                    String ssp;
17912                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17913                        final boolean replacing =
17914                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17915                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17916
17917                        try {
17918                            ApplicationInfo ai = AppGlobals.getPackageManager().
17919                                    getApplicationInfo(ssp, 0, 0);
17920                            mBatteryStatsService.notePackageInstalled(ssp,
17921                                    ai != null ? ai.versionCode : 0);
17922                        } catch (RemoteException e) {
17923                        }
17924                    }
17925                    break;
17926                }
17927                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17928                {
17929                    Uri data = intent.getData();
17930                    String ssp;
17931                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17932                        // Hide the "unsupported display" dialog if necessary.
17933                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17934                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17935                            mUnsupportedDisplaySizeDialog.dismiss();
17936                            mUnsupportedDisplaySizeDialog = null;
17937                        }
17938                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17939                    }
17940                    break;
17941                }
17942                case Intent.ACTION_TIMEZONE_CHANGED:
17943                    // If this is the time zone changed action, queue up a message that will reset
17944                    // the timezone of all currently running processes. This message will get
17945                    // queued up before the broadcast happens.
17946                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17947                    break;
17948                case Intent.ACTION_TIME_CHANGED:
17949                    // If the user set the time, let all running processes know.
17950                    final int is24Hour =
17951                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17952                                    : 0;
17953                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17954                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17955                    synchronized (stats) {
17956                        stats.noteCurrentTimeChangedLocked();
17957                    }
17958                    break;
17959                case Intent.ACTION_CLEAR_DNS_CACHE:
17960                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17961                    break;
17962                case Proxy.PROXY_CHANGE_ACTION:
17963                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17964                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17965                    break;
17966                case android.hardware.Camera.ACTION_NEW_PICTURE:
17967                case android.hardware.Camera.ACTION_NEW_VIDEO:
17968                    // These broadcasts are no longer allowed by the system, since they can
17969                    // cause significant thrashing at a crictical point (using the camera).
17970                    // Apps should use JobScehduler to monitor for media provider changes.
17971                    Slog.w(TAG, action + " no longer allowed; dropping from "
17972                            + UserHandle.formatUid(callingUid));
17973                    if (resultTo != null) {
17974                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17975                        try {
17976                            queue.performReceiveLocked(callerApp, resultTo, intent,
17977                                    Activity.RESULT_CANCELED, null, null,
17978                                    false, false, userId);
17979                        } catch (RemoteException e) {
17980                            Slog.w(TAG, "Failure ["
17981                                    + queue.mQueueName + "] sending broadcast result of "
17982                                    + intent, e);
17983
17984                        }
17985                    }
17986                    // Lie; we don't want to crash the app.
17987                    return ActivityManager.BROADCAST_SUCCESS;
17988            }
17989        }
17990
17991        // Add to the sticky list if requested.
17992        if (sticky) {
17993            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17994                    callingPid, callingUid)
17995                    != PackageManager.PERMISSION_GRANTED) {
17996                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17997                        + callingPid + ", uid=" + callingUid
17998                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17999                Slog.w(TAG, msg);
18000                throw new SecurityException(msg);
18001            }
18002            if (requiredPermissions != null && requiredPermissions.length > 0) {
18003                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18004                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18005                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18006            }
18007            if (intent.getComponent() != null) {
18008                throw new SecurityException(
18009                        "Sticky broadcasts can't target a specific component");
18010            }
18011            // We use userId directly here, since the "all" target is maintained
18012            // as a separate set of sticky broadcasts.
18013            if (userId != UserHandle.USER_ALL) {
18014                // But first, if this is not a broadcast to all users, then
18015                // make sure it doesn't conflict with an existing broadcast to
18016                // all users.
18017                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18018                        UserHandle.USER_ALL);
18019                if (stickies != null) {
18020                    ArrayList<Intent> list = stickies.get(intent.getAction());
18021                    if (list != null) {
18022                        int N = list.size();
18023                        int i;
18024                        for (i=0; i<N; i++) {
18025                            if (intent.filterEquals(list.get(i))) {
18026                                throw new IllegalArgumentException(
18027                                        "Sticky broadcast " + intent + " for user "
18028                                        + userId + " conflicts with existing global broadcast");
18029                            }
18030                        }
18031                    }
18032                }
18033            }
18034            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18035            if (stickies == null) {
18036                stickies = new ArrayMap<>();
18037                mStickyBroadcasts.put(userId, stickies);
18038            }
18039            ArrayList<Intent> list = stickies.get(intent.getAction());
18040            if (list == null) {
18041                list = new ArrayList<>();
18042                stickies.put(intent.getAction(), list);
18043            }
18044            final int stickiesCount = list.size();
18045            int i;
18046            for (i = 0; i < stickiesCount; i++) {
18047                if (intent.filterEquals(list.get(i))) {
18048                    // This sticky already exists, replace it.
18049                    list.set(i, new Intent(intent));
18050                    break;
18051                }
18052            }
18053            if (i >= stickiesCount) {
18054                list.add(new Intent(intent));
18055            }
18056        }
18057
18058        int[] users;
18059        if (userId == UserHandle.USER_ALL) {
18060            // Caller wants broadcast to go to all started users.
18061            users = mUserController.getStartedUserArrayLocked();
18062        } else {
18063            // Caller wants broadcast to go to one specific user.
18064            users = new int[] {userId};
18065        }
18066
18067        // Figure out who all will receive this broadcast.
18068        List receivers = null;
18069        List<BroadcastFilter> registeredReceivers = null;
18070        // Need to resolve the intent to interested receivers...
18071        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18072                 == 0) {
18073            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18074        }
18075        if (intent.getComponent() == null) {
18076            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18077                // Query one target user at a time, excluding shell-restricted users
18078                for (int i = 0; i < users.length; i++) {
18079                    if (mUserController.hasUserRestriction(
18080                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18081                        continue;
18082                    }
18083                    List<BroadcastFilter> registeredReceiversForUser =
18084                            mReceiverResolver.queryIntent(intent,
18085                                    resolvedType, false, users[i]);
18086                    if (registeredReceivers == null) {
18087                        registeredReceivers = registeredReceiversForUser;
18088                    } else if (registeredReceiversForUser != null) {
18089                        registeredReceivers.addAll(registeredReceiversForUser);
18090                    }
18091                }
18092            } else {
18093                registeredReceivers = mReceiverResolver.queryIntent(intent,
18094                        resolvedType, false, userId);
18095            }
18096        }
18097
18098        final boolean replacePending =
18099                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18100
18101        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18102                + " replacePending=" + replacePending);
18103
18104        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18105        if (!ordered && NR > 0) {
18106            // If we are not serializing this broadcast, then send the
18107            // registered receivers separately so they don't wait for the
18108            // components to be launched.
18109            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18110            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18111                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18112                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18113                    resultExtras, ordered, sticky, false, userId);
18114            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18115            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18116            if (!replaced) {
18117                queue.enqueueParallelBroadcastLocked(r);
18118                queue.scheduleBroadcastsLocked();
18119            }
18120            registeredReceivers = null;
18121            NR = 0;
18122        }
18123
18124        // Merge into one list.
18125        int ir = 0;
18126        if (receivers != null) {
18127            // A special case for PACKAGE_ADDED: do not allow the package
18128            // being added to see this broadcast.  This prevents them from
18129            // using this as a back door to get run as soon as they are
18130            // installed.  Maybe in the future we want to have a special install
18131            // broadcast or such for apps, but we'd like to deliberately make
18132            // this decision.
18133            String skipPackages[] = null;
18134            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18135                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18136                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18137                Uri data = intent.getData();
18138                if (data != null) {
18139                    String pkgName = data.getSchemeSpecificPart();
18140                    if (pkgName != null) {
18141                        skipPackages = new String[] { pkgName };
18142                    }
18143                }
18144            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18145                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18146            }
18147            if (skipPackages != null && (skipPackages.length > 0)) {
18148                for (String skipPackage : skipPackages) {
18149                    if (skipPackage != null) {
18150                        int NT = receivers.size();
18151                        for (int it=0; it<NT; it++) {
18152                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18153                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18154                                receivers.remove(it);
18155                                it--;
18156                                NT--;
18157                            }
18158                        }
18159                    }
18160                }
18161            }
18162
18163            int NT = receivers != null ? receivers.size() : 0;
18164            int it = 0;
18165            ResolveInfo curt = null;
18166            BroadcastFilter curr = null;
18167            while (it < NT && ir < NR) {
18168                if (curt == null) {
18169                    curt = (ResolveInfo)receivers.get(it);
18170                }
18171                if (curr == null) {
18172                    curr = registeredReceivers.get(ir);
18173                }
18174                if (curr.getPriority() >= curt.priority) {
18175                    // Insert this broadcast record into the final list.
18176                    receivers.add(it, curr);
18177                    ir++;
18178                    curr = null;
18179                    it++;
18180                    NT++;
18181                } else {
18182                    // Skip to the next ResolveInfo in the final list.
18183                    it++;
18184                    curt = null;
18185                }
18186            }
18187        }
18188        while (ir < NR) {
18189            if (receivers == null) {
18190                receivers = new ArrayList();
18191            }
18192            receivers.add(registeredReceivers.get(ir));
18193            ir++;
18194        }
18195
18196        if ((receivers != null && receivers.size() > 0)
18197                || resultTo != null) {
18198            BroadcastQueue queue = broadcastQueueForIntent(intent);
18199            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18200                    callerPackage, callingPid, callingUid, resolvedType,
18201                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18202                    resultData, resultExtras, ordered, sticky, false, userId);
18203
18204            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18205                    + ": prev had " + queue.mOrderedBroadcasts.size());
18206            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18207                    "Enqueueing broadcast " + r.intent.getAction());
18208
18209            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18210            if (!replaced) {
18211                queue.enqueueOrderedBroadcastLocked(r);
18212                queue.scheduleBroadcastsLocked();
18213            }
18214        } else {
18215            // There was nobody interested in the broadcast, but we still want to record
18216            // that it happened.
18217            if (intent.getComponent() == null && intent.getPackage() == null
18218                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18219                // This was an implicit broadcast... let's record it for posterity.
18220                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18221            }
18222        }
18223
18224        return ActivityManager.BROADCAST_SUCCESS;
18225    }
18226
18227    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18228            int skipCount, long dispatchTime) {
18229        final long now = SystemClock.elapsedRealtime();
18230        if (mCurBroadcastStats == null ||
18231                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18232            mLastBroadcastStats = mCurBroadcastStats;
18233            if (mLastBroadcastStats != null) {
18234                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18235                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18236            }
18237            mCurBroadcastStats = new BroadcastStats();
18238        }
18239        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18240    }
18241
18242    final Intent verifyBroadcastLocked(Intent intent) {
18243        // Refuse possible leaked file descriptors
18244        if (intent != null && intent.hasFileDescriptors() == true) {
18245            throw new IllegalArgumentException("File descriptors passed in Intent");
18246        }
18247
18248        int flags = intent.getFlags();
18249
18250        if (!mProcessesReady) {
18251            // if the caller really truly claims to know what they're doing, go
18252            // ahead and allow the broadcast without launching any receivers
18253            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18254                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18255            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18256                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18257                        + " before boot completion");
18258                throw new IllegalStateException("Cannot broadcast before boot completed");
18259            }
18260        }
18261
18262        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18263            throw new IllegalArgumentException(
18264                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18265        }
18266
18267        return intent;
18268    }
18269
18270    public final int broadcastIntent(IApplicationThread caller,
18271            Intent intent, String resolvedType, IIntentReceiver resultTo,
18272            int resultCode, String resultData, Bundle resultExtras,
18273            String[] requiredPermissions, int appOp, Bundle bOptions,
18274            boolean serialized, boolean sticky, int userId) {
18275        enforceNotIsolatedCaller("broadcastIntent");
18276        synchronized(this) {
18277            intent = verifyBroadcastLocked(intent);
18278
18279            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18280            final int callingPid = Binder.getCallingPid();
18281            final int callingUid = Binder.getCallingUid();
18282            final long origId = Binder.clearCallingIdentity();
18283            int res = broadcastIntentLocked(callerApp,
18284                    callerApp != null ? callerApp.info.packageName : null,
18285                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18286                    requiredPermissions, appOp, bOptions, serialized, sticky,
18287                    callingPid, callingUid, userId);
18288            Binder.restoreCallingIdentity(origId);
18289            return res;
18290        }
18291    }
18292
18293
18294    int broadcastIntentInPackage(String packageName, int uid,
18295            Intent intent, String resolvedType, IIntentReceiver resultTo,
18296            int resultCode, String resultData, Bundle resultExtras,
18297            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18298            int userId) {
18299        synchronized(this) {
18300            intent = verifyBroadcastLocked(intent);
18301
18302            final long origId = Binder.clearCallingIdentity();
18303            String[] requiredPermissions = requiredPermission == null ? null
18304                    : new String[] {requiredPermission};
18305            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18306                    resultTo, resultCode, resultData, resultExtras,
18307                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18308                    sticky, -1, uid, userId);
18309            Binder.restoreCallingIdentity(origId);
18310            return res;
18311        }
18312    }
18313
18314    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18315        // Refuse possible leaked file descriptors
18316        if (intent != null && intent.hasFileDescriptors() == true) {
18317            throw new IllegalArgumentException("File descriptors passed in Intent");
18318        }
18319
18320        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18321                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18322
18323        synchronized(this) {
18324            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18325                    != PackageManager.PERMISSION_GRANTED) {
18326                String msg = "Permission Denial: unbroadcastIntent() from pid="
18327                        + Binder.getCallingPid()
18328                        + ", uid=" + Binder.getCallingUid()
18329                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18330                Slog.w(TAG, msg);
18331                throw new SecurityException(msg);
18332            }
18333            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18334            if (stickies != null) {
18335                ArrayList<Intent> list = stickies.get(intent.getAction());
18336                if (list != null) {
18337                    int N = list.size();
18338                    int i;
18339                    for (i=0; i<N; i++) {
18340                        if (intent.filterEquals(list.get(i))) {
18341                            list.remove(i);
18342                            break;
18343                        }
18344                    }
18345                    if (list.size() <= 0) {
18346                        stickies.remove(intent.getAction());
18347                    }
18348                }
18349                if (stickies.size() <= 0) {
18350                    mStickyBroadcasts.remove(userId);
18351                }
18352            }
18353        }
18354    }
18355
18356    void backgroundServicesFinishedLocked(int userId) {
18357        for (BroadcastQueue queue : mBroadcastQueues) {
18358            queue.backgroundServicesFinishedLocked(userId);
18359        }
18360    }
18361
18362    public void finishReceiver(IBinder who, int resultCode, String resultData,
18363            Bundle resultExtras, boolean resultAbort, int flags) {
18364        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18365
18366        // Refuse possible leaked file descriptors
18367        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18368            throw new IllegalArgumentException("File descriptors passed in Bundle");
18369        }
18370
18371        final long origId = Binder.clearCallingIdentity();
18372        try {
18373            boolean doNext = false;
18374            BroadcastRecord r;
18375
18376            synchronized(this) {
18377                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18378                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18379                r = queue.getMatchingOrderedReceiver(who);
18380                if (r != null) {
18381                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18382                        resultData, resultExtras, resultAbort, true);
18383                }
18384            }
18385
18386            if (doNext) {
18387                r.queue.processNextBroadcast(false);
18388            }
18389            trimApplications();
18390        } finally {
18391            Binder.restoreCallingIdentity(origId);
18392        }
18393    }
18394
18395    // =========================================================
18396    // INSTRUMENTATION
18397    // =========================================================
18398
18399    public boolean startInstrumentation(ComponentName className,
18400            String profileFile, int flags, Bundle arguments,
18401            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18402            int userId, String abiOverride) {
18403        enforceNotIsolatedCaller("startInstrumentation");
18404        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18405                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18406        // Refuse possible leaked file descriptors
18407        if (arguments != null && arguments.hasFileDescriptors()) {
18408            throw new IllegalArgumentException("File descriptors passed in Bundle");
18409        }
18410
18411        synchronized(this) {
18412            InstrumentationInfo ii = null;
18413            ApplicationInfo ai = null;
18414            try {
18415                ii = mContext.getPackageManager().getInstrumentationInfo(
18416                    className, STOCK_PM_FLAGS);
18417                ai = AppGlobals.getPackageManager().getApplicationInfo(
18418                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18419            } catch (PackageManager.NameNotFoundException e) {
18420            } catch (RemoteException e) {
18421            }
18422            if (ii == null) {
18423                reportStartInstrumentationFailureLocked(watcher, className,
18424                        "Unable to find instrumentation info for: " + className);
18425                return false;
18426            }
18427            if (ai == null) {
18428                reportStartInstrumentationFailureLocked(watcher, className,
18429                        "Unable to find instrumentation target package: " + ii.targetPackage);
18430                return false;
18431            }
18432            if (!ai.hasCode()) {
18433                reportStartInstrumentationFailureLocked(watcher, className,
18434                        "Instrumentation target has no code: " + ii.targetPackage);
18435                return false;
18436            }
18437
18438            int match = mContext.getPackageManager().checkSignatures(
18439                    ii.targetPackage, ii.packageName);
18440            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18441                String msg = "Permission Denial: starting instrumentation "
18442                        + className + " from pid="
18443                        + Binder.getCallingPid()
18444                        + ", uid=" + Binder.getCallingPid()
18445                        + " not allowed because package " + ii.packageName
18446                        + " does not have a signature matching the target "
18447                        + ii.targetPackage;
18448                reportStartInstrumentationFailureLocked(watcher, className, msg);
18449                throw new SecurityException(msg);
18450            }
18451
18452            final long origId = Binder.clearCallingIdentity();
18453            // Instrumentation can kill and relaunch even persistent processes
18454            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18455                    "start instr");
18456            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18457            app.instrumentationClass = className;
18458            app.instrumentationInfo = ai;
18459            app.instrumentationProfileFile = profileFile;
18460            app.instrumentationArguments = arguments;
18461            app.instrumentationWatcher = watcher;
18462            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18463            app.instrumentationResultClass = className;
18464            Binder.restoreCallingIdentity(origId);
18465        }
18466
18467        return true;
18468    }
18469
18470    /**
18471     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18472     * error to the logs, but if somebody is watching, send the report there too.  This enables
18473     * the "am" command to report errors with more information.
18474     *
18475     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18476     * @param cn The component name of the instrumentation.
18477     * @param report The error report.
18478     */
18479    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18480            ComponentName cn, String report) {
18481        Slog.w(TAG, report);
18482        if (watcher != null) {
18483            Bundle results = new Bundle();
18484            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18485            results.putString("Error", report);
18486            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18487        }
18488    }
18489
18490    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18491        if (app.instrumentationWatcher != null) {
18492            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18493                    app.instrumentationClass, resultCode, results);
18494        }
18495
18496        // Can't call out of the system process with a lock held, so post a message.
18497        if (app.instrumentationUiAutomationConnection != null) {
18498            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18499                    app.instrumentationUiAutomationConnection).sendToTarget();
18500        }
18501
18502        app.instrumentationWatcher = null;
18503        app.instrumentationUiAutomationConnection = null;
18504        app.instrumentationClass = null;
18505        app.instrumentationInfo = null;
18506        app.instrumentationProfileFile = null;
18507        app.instrumentationArguments = null;
18508
18509        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18510                "finished inst");
18511    }
18512
18513    public void finishInstrumentation(IApplicationThread target,
18514            int resultCode, Bundle results) {
18515        int userId = UserHandle.getCallingUserId();
18516        // Refuse possible leaked file descriptors
18517        if (results != null && results.hasFileDescriptors()) {
18518            throw new IllegalArgumentException("File descriptors passed in Intent");
18519        }
18520
18521        synchronized(this) {
18522            ProcessRecord app = getRecordForAppLocked(target);
18523            if (app == null) {
18524                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18525                return;
18526            }
18527            final long origId = Binder.clearCallingIdentity();
18528            finishInstrumentationLocked(app, resultCode, results);
18529            Binder.restoreCallingIdentity(origId);
18530        }
18531    }
18532
18533    // =========================================================
18534    // CONFIGURATION
18535    // =========================================================
18536
18537    public ConfigurationInfo getDeviceConfigurationInfo() {
18538        ConfigurationInfo config = new ConfigurationInfo();
18539        synchronized (this) {
18540            config.reqTouchScreen = mConfiguration.touchscreen;
18541            config.reqKeyboardType = mConfiguration.keyboard;
18542            config.reqNavigation = mConfiguration.navigation;
18543            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18544                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18545                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18546            }
18547            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18548                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18549                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18550            }
18551            config.reqGlEsVersion = GL_ES_VERSION;
18552        }
18553        return config;
18554    }
18555
18556    ActivityStack getFocusedStack() {
18557        return mStackSupervisor.getFocusedStack();
18558    }
18559
18560    @Override
18561    public int getFocusedStackId() throws RemoteException {
18562        ActivityStack focusedStack = getFocusedStack();
18563        if (focusedStack != null) {
18564            return focusedStack.getStackId();
18565        }
18566        return -1;
18567    }
18568
18569    public Configuration getConfiguration() {
18570        Configuration ci;
18571        synchronized(this) {
18572            ci = new Configuration(mConfiguration);
18573            ci.userSetLocale = false;
18574        }
18575        return ci;
18576    }
18577
18578    @Override
18579    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18580        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18581        synchronized (this) {
18582            mSuppressResizeConfigChanges = suppress;
18583        }
18584    }
18585
18586    @Override
18587    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18588        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18589        if (fromStackId == HOME_STACK_ID) {
18590            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18591        }
18592        synchronized (this) {
18593            final long origId = Binder.clearCallingIdentity();
18594            try {
18595                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18596            } finally {
18597                Binder.restoreCallingIdentity(origId);
18598            }
18599        }
18600    }
18601
18602    @Override
18603    public void updatePersistentConfiguration(Configuration values) {
18604        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18605                "updateConfiguration()");
18606        enforceWriteSettingsPermission("updateConfiguration()");
18607        if (values == null) {
18608            throw new NullPointerException("Configuration must not be null");
18609        }
18610
18611        int userId = UserHandle.getCallingUserId();
18612
18613        synchronized(this) {
18614            final long origId = Binder.clearCallingIdentity();
18615            updateConfigurationLocked(values, null, false, true, userId);
18616            Binder.restoreCallingIdentity(origId);
18617        }
18618    }
18619
18620    private void updateFontScaleIfNeeded() {
18621        final int currentUserId;
18622        synchronized(this) {
18623            currentUserId = mUserController.getCurrentUserIdLocked();
18624        }
18625        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18626                FONT_SCALE, 1.0f, currentUserId);
18627        if (mConfiguration.fontScale != scaleFactor) {
18628            final Configuration configuration = mWindowManager.computeNewConfiguration();
18629            configuration.fontScale = scaleFactor;
18630            updatePersistentConfiguration(configuration);
18631        }
18632    }
18633
18634    private void enforceWriteSettingsPermission(String func) {
18635        int uid = Binder.getCallingUid();
18636        if (uid == Process.ROOT_UID) {
18637            return;
18638        }
18639
18640        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18641                Settings.getPackageNameForUid(mContext, uid), false)) {
18642            return;
18643        }
18644
18645        String msg = "Permission Denial: " + func + " from pid="
18646                + Binder.getCallingPid()
18647                + ", uid=" + uid
18648                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18649        Slog.w(TAG, msg);
18650        throw new SecurityException(msg);
18651    }
18652
18653    public void updateConfiguration(Configuration values) {
18654        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18655                "updateConfiguration()");
18656
18657        synchronized(this) {
18658            if (values == null && mWindowManager != null) {
18659                // sentinel: fetch the current configuration from the window manager
18660                values = mWindowManager.computeNewConfiguration();
18661            }
18662
18663            if (mWindowManager != null) {
18664                mProcessList.applyDisplaySize(mWindowManager);
18665            }
18666
18667            final long origId = Binder.clearCallingIdentity();
18668            if (values != null) {
18669                Settings.System.clearConfiguration(values);
18670            }
18671            updateConfigurationLocked(values, null, false);
18672            Binder.restoreCallingIdentity(origId);
18673        }
18674    }
18675
18676    void updateUserConfigurationLocked() {
18677        Configuration configuration = new Configuration(mConfiguration);
18678        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18679                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18680        updateConfigurationLocked(configuration, null, false);
18681    }
18682
18683    boolean updateConfigurationLocked(Configuration values,
18684            ActivityRecord starting, boolean initLocale) {
18685        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18686        return updateConfigurationLocked(values, starting, initLocale, false,
18687                UserHandle.USER_NULL);
18688    }
18689
18690    // To cache the list of supported system locales
18691    private String[] mSupportedSystemLocales = null;
18692
18693    /**
18694     * Do either or both things: (1) change the current configuration, and (2)
18695     * make sure the given activity is running with the (now) current
18696     * configuration.  Returns true if the activity has been left running, or
18697     * false if <var>starting</var> is being destroyed to match the new
18698     * configuration.
18699     *
18700     * @param userId is only used when persistent parameter is set to true to persist configuration
18701     *               for that particular user
18702     */
18703    private boolean updateConfigurationLocked(Configuration values,
18704            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18705        int changes = 0;
18706
18707        if (mWindowManager != null) {
18708            mWindowManager.deferSurfaceLayout();
18709        }
18710        if (values != null) {
18711            Configuration newConfig = new Configuration(mConfiguration);
18712            changes = newConfig.updateFrom(values);
18713            if (changes != 0) {
18714                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18715                        "Updating configuration to: " + values);
18716
18717                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18718
18719                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18720                    final LocaleList locales = values.getLocales();
18721                    int bestLocaleIndex = 0;
18722                    if (locales.size() > 1) {
18723                        if (mSupportedSystemLocales == null) {
18724                            mSupportedSystemLocales =
18725                                    Resources.getSystem().getAssets().getLocales();
18726                        }
18727                        bestLocaleIndex = Math.max(0,
18728                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18729                    }
18730                    SystemProperties.set("persist.sys.locale",
18731                            locales.get(bestLocaleIndex).toLanguageTag());
18732                    LocaleList.setDefault(locales, bestLocaleIndex);
18733                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18734                            locales.get(bestLocaleIndex)));
18735                }
18736
18737                mConfigurationSeq++;
18738                if (mConfigurationSeq <= 0) {
18739                    mConfigurationSeq = 1;
18740                }
18741                newConfig.seq = mConfigurationSeq;
18742                mConfiguration = newConfig;
18743                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18744                mUsageStatsService.reportConfigurationChange(newConfig,
18745                        mUserController.getCurrentUserIdLocked());
18746                //mUsageStatsService.noteStartConfig(newConfig);
18747
18748                final Configuration configCopy = new Configuration(mConfiguration);
18749
18750                // TODO: If our config changes, should we auto dismiss any currently
18751                // showing dialogs?
18752                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18753
18754                AttributeCache ac = AttributeCache.instance();
18755                if (ac != null) {
18756                    ac.updateConfiguration(configCopy);
18757                }
18758
18759                // Make sure all resources in our process are updated
18760                // right now, so that anyone who is going to retrieve
18761                // resource values after we return will be sure to get
18762                // the new ones.  This is especially important during
18763                // boot, where the first config change needs to guarantee
18764                // all resources have that config before following boot
18765                // code is executed.
18766                mSystemThread.applyConfigurationToResources(configCopy);
18767
18768                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18769                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18770                    msg.obj = new Configuration(configCopy);
18771                    msg.arg1 = userId;
18772                    mHandler.sendMessage(msg);
18773                }
18774
18775                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18776                if (isDensityChange) {
18777                    // Reset the unsupported display size dialog.
18778                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18779
18780                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18781                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18782                }
18783
18784                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18785                    ProcessRecord app = mLruProcesses.get(i);
18786                    try {
18787                        if (app.thread != null) {
18788                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18789                                    + app.processName + " new config " + mConfiguration);
18790                            app.thread.scheduleConfigurationChanged(configCopy);
18791                        }
18792                    } catch (Exception e) {
18793                    }
18794                }
18795                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18796                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18797                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18798                        | Intent.FLAG_RECEIVER_FOREGROUND);
18799                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18800                        null, AppOpsManager.OP_NONE, null, false, false,
18801                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18802                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18803                    // Tell the shortcut manager that the system locale changed.  It needs to know
18804                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18805                    // we "push" from here, rather than having the service listen to the broadcast.
18806                    final ShortcutServiceInternal shortcutService =
18807                            LocalServices.getService(ShortcutServiceInternal.class);
18808                    if (shortcutService != null) {
18809                        shortcutService.onSystemLocaleChangedNoLock();
18810                    }
18811
18812                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18813                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18814                    if (!mProcessesReady) {
18815                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18816                    }
18817                    broadcastIntentLocked(null, null, intent,
18818                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18819                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18820                }
18821            }
18822            // Update the configuration with WM first and check if any of the stacks need to be
18823            // resized due to the configuration change. If so, resize the stacks now and do any
18824            // relaunches if necessary. This way we don't need to relaunch again below in
18825            // ensureActivityConfigurationLocked().
18826            if (mWindowManager != null) {
18827                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18828                if (resizedStacks != null) {
18829                    for (int stackId : resizedStacks) {
18830                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18831                        mStackSupervisor.resizeStackLocked(
18832                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18833                    }
18834                }
18835            }
18836        }
18837
18838        boolean kept = true;
18839        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18840        // mainStack is null during startup.
18841        if (mainStack != null) {
18842            if (changes != 0 && starting == null) {
18843                // If the configuration changed, and the caller is not already
18844                // in the process of starting an activity, then find the top
18845                // activity to check if its configuration needs to change.
18846                starting = mainStack.topRunningActivityLocked();
18847            }
18848
18849            if (starting != null) {
18850                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18851                // And we need to make sure at this point that all other activities
18852                // are made visible with the correct configuration.
18853                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18854                        !PRESERVE_WINDOWS);
18855            }
18856        }
18857        if (mWindowManager != null) {
18858            mWindowManager.continueSurfaceLayout();
18859        }
18860        return kept;
18861    }
18862
18863    /**
18864     * Decide based on the configuration whether we should shouw the ANR,
18865     * crash, etc dialogs.  The idea is that if there is no affordnace to
18866     * press the on-screen buttons, we shouldn't show the dialog.
18867     *
18868     * A thought: SystemUI might also want to get told about this, the Power
18869     * dialog / global actions also might want different behaviors.
18870     */
18871    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18872        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18873                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18874                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18875        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18876                                    == Configuration.UI_MODE_TYPE_CAR);
18877        return inputMethodExists && uiIsNotCarType && !inVrMode;
18878    }
18879
18880    @Override
18881    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18882        synchronized (this) {
18883            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18884            if (srec != null) {
18885                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18886            }
18887        }
18888        return false;
18889    }
18890
18891    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18892            Intent resultData) {
18893
18894        synchronized (this) {
18895            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18896            if (r != null) {
18897                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18898            }
18899            return false;
18900        }
18901    }
18902
18903    public int getLaunchedFromUid(IBinder activityToken) {
18904        ActivityRecord srec;
18905        synchronized (this) {
18906            srec = ActivityRecord.forTokenLocked(activityToken);
18907        }
18908        if (srec == null) {
18909            return -1;
18910        }
18911        return srec.launchedFromUid;
18912    }
18913
18914    public String getLaunchedFromPackage(IBinder activityToken) {
18915        ActivityRecord srec;
18916        synchronized (this) {
18917            srec = ActivityRecord.forTokenLocked(activityToken);
18918        }
18919        if (srec == null) {
18920            return null;
18921        }
18922        return srec.launchedFromPackage;
18923    }
18924
18925    // =========================================================
18926    // LIFETIME MANAGEMENT
18927    // =========================================================
18928
18929    // Returns whether the app is receiving broadcast.
18930    // If receiving, fetch all broadcast queues which the app is
18931    // the current [or imminent] receiver on.
18932    private boolean isReceivingBroadcastLocked(ProcessRecord app,
18933            ArraySet<BroadcastQueue> receivingQueues) {
18934        if (!app.curReceivers.isEmpty()) {
18935            for (BroadcastRecord r : app.curReceivers) {
18936                receivingQueues.add(r.queue);
18937            }
18938            return true;
18939        }
18940
18941        // It's not the current receiver, but it might be starting up to become one
18942        for (BroadcastQueue queue : mBroadcastQueues) {
18943            final BroadcastRecord r = queue.mPendingBroadcast;
18944            if (r != null && r.curApp == app) {
18945                // found it; report which queue it's in
18946                receivingQueues.add(queue);
18947            }
18948        }
18949
18950        return !receivingQueues.isEmpty();
18951    }
18952
18953    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18954            int targetUid, ComponentName targetComponent, String targetProcess) {
18955        if (!mTrackingAssociations) {
18956            return null;
18957        }
18958        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18959                = mAssociations.get(targetUid);
18960        if (components == null) {
18961            components = new ArrayMap<>();
18962            mAssociations.put(targetUid, components);
18963        }
18964        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18965        if (sourceUids == null) {
18966            sourceUids = new SparseArray<>();
18967            components.put(targetComponent, sourceUids);
18968        }
18969        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18970        if (sourceProcesses == null) {
18971            sourceProcesses = new ArrayMap<>();
18972            sourceUids.put(sourceUid, sourceProcesses);
18973        }
18974        Association ass = sourceProcesses.get(sourceProcess);
18975        if (ass == null) {
18976            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18977                    targetProcess);
18978            sourceProcesses.put(sourceProcess, ass);
18979        }
18980        ass.mCount++;
18981        ass.mNesting++;
18982        if (ass.mNesting == 1) {
18983            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18984            ass.mLastState = sourceState;
18985        }
18986        return ass;
18987    }
18988
18989    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18990            ComponentName targetComponent) {
18991        if (!mTrackingAssociations) {
18992            return;
18993        }
18994        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18995                = mAssociations.get(targetUid);
18996        if (components == null) {
18997            return;
18998        }
18999        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19000        if (sourceUids == null) {
19001            return;
19002        }
19003        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19004        if (sourceProcesses == null) {
19005            return;
19006        }
19007        Association ass = sourceProcesses.get(sourceProcess);
19008        if (ass == null || ass.mNesting <= 0) {
19009            return;
19010        }
19011        ass.mNesting--;
19012        if (ass.mNesting == 0) {
19013            long uptime = SystemClock.uptimeMillis();
19014            ass.mTime += uptime - ass.mStartTime;
19015            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19016                    += uptime - ass.mLastStateUptime;
19017            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19018        }
19019    }
19020
19021    private void noteUidProcessState(final int uid, final int state) {
19022        mBatteryStatsService.noteUidProcessState(uid, state);
19023        if (mTrackingAssociations) {
19024            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19025                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19026                        = mAssociations.valueAt(i1);
19027                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19028                    SparseArray<ArrayMap<String, Association>> sourceUids
19029                            = targetComponents.valueAt(i2);
19030                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19031                    if (sourceProcesses != null) {
19032                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19033                            Association ass = sourceProcesses.valueAt(i4);
19034                            if (ass.mNesting >= 1) {
19035                                // currently associated
19036                                long uptime = SystemClock.uptimeMillis();
19037                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19038                                        += uptime - ass.mLastStateUptime;
19039                                ass.mLastState = state;
19040                                ass.mLastStateUptime = uptime;
19041                            }
19042                        }
19043                    }
19044                }
19045            }
19046        }
19047    }
19048
19049    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19050            boolean doingAll, long now) {
19051        if (mAdjSeq == app.adjSeq) {
19052            // This adjustment has already been computed.
19053            return app.curRawAdj;
19054        }
19055
19056        if (app.thread == null) {
19057            app.adjSeq = mAdjSeq;
19058            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19059            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19060            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19061        }
19062
19063        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19064        app.adjSource = null;
19065        app.adjTarget = null;
19066        app.empty = false;
19067        app.cached = false;
19068
19069        final int activitiesSize = app.activities.size();
19070
19071        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19072            // The max adjustment doesn't allow this app to be anything
19073            // below foreground, so it is not worth doing work for it.
19074            app.adjType = "fixed";
19075            app.adjSeq = mAdjSeq;
19076            app.curRawAdj = app.maxAdj;
19077            app.foregroundActivities = false;
19078            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19079            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19080            // System processes can do UI, and when they do we want to have
19081            // them trim their memory after the user leaves the UI.  To
19082            // facilitate this, here we need to determine whether or not it
19083            // is currently showing UI.
19084            app.systemNoUi = true;
19085            if (app == TOP_APP) {
19086                app.systemNoUi = false;
19087                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19088                app.adjType = "pers-top-activity";
19089            } else if (activitiesSize > 0) {
19090                for (int j = 0; j < activitiesSize; j++) {
19091                    final ActivityRecord r = app.activities.get(j);
19092                    if (r.visible) {
19093                        app.systemNoUi = false;
19094                    }
19095                }
19096            }
19097            if (!app.systemNoUi) {
19098                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19099            }
19100            return (app.curAdj=app.maxAdj);
19101        }
19102
19103        app.systemNoUi = false;
19104
19105        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19106
19107        // Determine the importance of the process, starting with most
19108        // important to least, and assign an appropriate OOM adjustment.
19109        int adj;
19110        int schedGroup;
19111        int procState;
19112        boolean foregroundActivities = false;
19113        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19114        if (app == TOP_APP) {
19115            // The last app on the list is the foreground app.
19116            adj = ProcessList.FOREGROUND_APP_ADJ;
19117            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19118            app.adjType = "top-activity";
19119            foregroundActivities = true;
19120            procState = PROCESS_STATE_CUR_TOP;
19121        } else if (app.instrumentationClass != null) {
19122            // Don't want to kill running instrumentation.
19123            adj = ProcessList.FOREGROUND_APP_ADJ;
19124            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19125            app.adjType = "instrumentation";
19126            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19127        } else if (isReceivingBroadcastLocked(app, queues)) {
19128            // An app that is currently receiving a broadcast also
19129            // counts as being in the foreground for OOM killer purposes.
19130            // It's placed in a sched group based on the nature of the
19131            // broadcast as reflected by which queue it's active in.
19132            adj = ProcessList.FOREGROUND_APP_ADJ;
19133            schedGroup = (queues.contains(mFgBroadcastQueue))
19134                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19135            app.adjType = "broadcast";
19136            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19137        } else if (app.executingServices.size() > 0) {
19138            // An app that is currently executing a service callback also
19139            // counts as being in the foreground.
19140            adj = ProcessList.FOREGROUND_APP_ADJ;
19141            schedGroup = app.execServicesFg ?
19142                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19143            app.adjType = "exec-service";
19144            procState = ActivityManager.PROCESS_STATE_SERVICE;
19145            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19146        } else {
19147            // As far as we know the process is empty.  We may change our mind later.
19148            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19149            // At this point we don't actually know the adjustment.  Use the cached adj
19150            // value that the caller wants us to.
19151            adj = cachedAdj;
19152            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19153            app.cached = true;
19154            app.empty = true;
19155            app.adjType = "cch-empty";
19156        }
19157
19158        // Examine all activities if not already foreground.
19159        if (!foregroundActivities && activitiesSize > 0) {
19160            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19161            for (int j = 0; j < activitiesSize; j++) {
19162                final ActivityRecord r = app.activities.get(j);
19163                if (r.app != app) {
19164                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19165                            + " instead of expected " + app);
19166                    if (r.app == null || (r.app.uid == app.uid)) {
19167                        // Only fix things up when they look sane
19168                        r.app = app;
19169                    } else {
19170                        continue;
19171                    }
19172                }
19173                if (r.visible) {
19174                    // App has a visible activity; only upgrade adjustment.
19175                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19176                        adj = ProcessList.VISIBLE_APP_ADJ;
19177                        app.adjType = "visible";
19178                    }
19179                    if (procState > PROCESS_STATE_CUR_TOP) {
19180                        procState = PROCESS_STATE_CUR_TOP;
19181                    }
19182                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19183                    app.cached = false;
19184                    app.empty = false;
19185                    foregroundActivities = true;
19186                    if (r.task != null && minLayer > 0) {
19187                        final int layer = r.task.mLayerRank;
19188                        if (layer >= 0 && minLayer > layer) {
19189                            minLayer = layer;
19190                        }
19191                    }
19192                    break;
19193                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19194                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19195                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19196                        app.adjType = "pausing";
19197                    }
19198                    if (procState > PROCESS_STATE_CUR_TOP) {
19199                        procState = PROCESS_STATE_CUR_TOP;
19200                    }
19201                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19202                    app.cached = false;
19203                    app.empty = false;
19204                    foregroundActivities = true;
19205                } else if (r.state == ActivityState.STOPPING) {
19206                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19207                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19208                        app.adjType = "stopping";
19209                    }
19210                    // For the process state, we will at this point consider the
19211                    // process to be cached.  It will be cached either as an activity
19212                    // or empty depending on whether the activity is finishing.  We do
19213                    // this so that we can treat the process as cached for purposes of
19214                    // memory trimming (determing current memory level, trim command to
19215                    // send to process) since there can be an arbitrary number of stopping
19216                    // processes and they should soon all go into the cached state.
19217                    if (!r.finishing) {
19218                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19219                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19220                        }
19221                    }
19222                    app.cached = false;
19223                    app.empty = false;
19224                    foregroundActivities = true;
19225                } else {
19226                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19227                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19228                        app.adjType = "cch-act";
19229                    }
19230                }
19231            }
19232            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19233                adj += minLayer;
19234            }
19235        }
19236
19237        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19238                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19239            if (app.foregroundServices) {
19240                // The user is aware of this app, so make it visible.
19241                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19242                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19243                app.cached = false;
19244                app.adjType = "fg-service";
19245                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19246            } else if (app.forcingToForeground != null) {
19247                // The user is aware of this app, so make it visible.
19248                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19249                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19250                app.cached = false;
19251                app.adjType = "force-fg";
19252                app.adjSource = app.forcingToForeground;
19253                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19254            }
19255        }
19256
19257        if (app == mHeavyWeightProcess) {
19258            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19259                // We don't want to kill the current heavy-weight process.
19260                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19261                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19262                app.cached = false;
19263                app.adjType = "heavy";
19264            }
19265            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19266                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19267            }
19268        }
19269
19270        if (app == mHomeProcess) {
19271            if (adj > ProcessList.HOME_APP_ADJ) {
19272                // This process is hosting what we currently consider to be the
19273                // home app, so we don't want to let it go into the background.
19274                adj = ProcessList.HOME_APP_ADJ;
19275                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19276                app.cached = false;
19277                app.adjType = "home";
19278            }
19279            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19280                procState = ActivityManager.PROCESS_STATE_HOME;
19281            }
19282        }
19283
19284        if (app == mPreviousProcess && app.activities.size() > 0) {
19285            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19286                // This was the previous process that showed UI to the user.
19287                // We want to try to keep it around more aggressively, to give
19288                // a good experience around switching between two apps.
19289                adj = ProcessList.PREVIOUS_APP_ADJ;
19290                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19291                app.cached = false;
19292                app.adjType = "previous";
19293            }
19294            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19295                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19296            }
19297        }
19298
19299        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19300                + " reason=" + app.adjType);
19301
19302        // By default, we use the computed adjustment.  It may be changed if
19303        // there are applications dependent on our services or providers, but
19304        // this gives us a baseline and makes sure we don't get into an
19305        // infinite recursion.
19306        app.adjSeq = mAdjSeq;
19307        app.curRawAdj = adj;
19308        app.hasStartedServices = false;
19309
19310        if (mBackupTarget != null && app == mBackupTarget.app) {
19311            // If possible we want to avoid killing apps while they're being backed up
19312            if (adj > ProcessList.BACKUP_APP_ADJ) {
19313                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19314                adj = ProcessList.BACKUP_APP_ADJ;
19315                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19316                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19317                }
19318                app.adjType = "backup";
19319                app.cached = false;
19320            }
19321            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19322                procState = ActivityManager.PROCESS_STATE_BACKUP;
19323            }
19324        }
19325
19326        boolean mayBeTop = false;
19327
19328        for (int is = app.services.size()-1;
19329                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19330                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19331                        || procState > ActivityManager.PROCESS_STATE_TOP);
19332                is--) {
19333            ServiceRecord s = app.services.valueAt(is);
19334            if (s.startRequested) {
19335                app.hasStartedServices = true;
19336                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19337                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19338                }
19339                if (app.hasShownUi && app != mHomeProcess) {
19340                    // If this process has shown some UI, let it immediately
19341                    // go to the LRU list because it may be pretty heavy with
19342                    // UI stuff.  We'll tag it with a label just to help
19343                    // debug and understand what is going on.
19344                    if (adj > ProcessList.SERVICE_ADJ) {
19345                        app.adjType = "cch-started-ui-services";
19346                    }
19347                } else {
19348                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19349                        // This service has seen some activity within
19350                        // recent memory, so we will keep its process ahead
19351                        // of the background processes.
19352                        if (adj > ProcessList.SERVICE_ADJ) {
19353                            adj = ProcessList.SERVICE_ADJ;
19354                            app.adjType = "started-services";
19355                            app.cached = false;
19356                        }
19357                    }
19358                    // If we have let the service slide into the background
19359                    // state, still have some text describing what it is doing
19360                    // even though the service no longer has an impact.
19361                    if (adj > ProcessList.SERVICE_ADJ) {
19362                        app.adjType = "cch-started-services";
19363                    }
19364                }
19365            }
19366
19367            for (int conni = s.connections.size()-1;
19368                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19369                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19370                            || procState > ActivityManager.PROCESS_STATE_TOP);
19371                    conni--) {
19372                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19373                for (int i = 0;
19374                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19375                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19376                                || procState > ActivityManager.PROCESS_STATE_TOP);
19377                        i++) {
19378                    // XXX should compute this based on the max of
19379                    // all connected clients.
19380                    ConnectionRecord cr = clist.get(i);
19381                    if (cr.binding.client == app) {
19382                        // Binding to ourself is not interesting.
19383                        continue;
19384                    }
19385
19386                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19387                        ProcessRecord client = cr.binding.client;
19388                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19389                                TOP_APP, doingAll, now);
19390                        int clientProcState = client.curProcState;
19391                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19392                            // If the other app is cached for any reason, for purposes here
19393                            // we are going to consider it empty.  The specific cached state
19394                            // doesn't propagate except under certain conditions.
19395                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19396                        }
19397                        String adjType = null;
19398                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19399                            // Not doing bind OOM management, so treat
19400                            // this guy more like a started service.
19401                            if (app.hasShownUi && app != mHomeProcess) {
19402                                // If this process has shown some UI, let it immediately
19403                                // go to the LRU list because it may be pretty heavy with
19404                                // UI stuff.  We'll tag it with a label just to help
19405                                // debug and understand what is going on.
19406                                if (adj > clientAdj) {
19407                                    adjType = "cch-bound-ui-services";
19408                                }
19409                                app.cached = false;
19410                                clientAdj = adj;
19411                                clientProcState = procState;
19412                            } else {
19413                                if (now >= (s.lastActivity
19414                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19415                                    // This service has not seen activity within
19416                                    // recent memory, so allow it to drop to the
19417                                    // LRU list if there is no other reason to keep
19418                                    // it around.  We'll also tag it with a label just
19419                                    // to help debug and undertand what is going on.
19420                                    if (adj > clientAdj) {
19421                                        adjType = "cch-bound-services";
19422                                    }
19423                                    clientAdj = adj;
19424                                }
19425                            }
19426                        }
19427                        if (adj > clientAdj) {
19428                            // If this process has recently shown UI, and
19429                            // the process that is binding to it is less
19430                            // important than being visible, then we don't
19431                            // care about the binding as much as we care
19432                            // about letting this process get into the LRU
19433                            // list to be killed and restarted if needed for
19434                            // memory.
19435                            if (app.hasShownUi && app != mHomeProcess
19436                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19437                                adjType = "cch-bound-ui-services";
19438                            } else {
19439                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19440                                        |Context.BIND_IMPORTANT)) != 0) {
19441                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19442                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19443                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19444                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19445                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19446                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19447                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19448                                    adj = clientAdj;
19449                                } else {
19450                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19451                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19452                                    }
19453                                }
19454                                if (!client.cached) {
19455                                    app.cached = false;
19456                                }
19457                                adjType = "service";
19458                            }
19459                        }
19460                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19461                            // This will treat important bound services identically to
19462                            // the top app, which may behave differently than generic
19463                            // foreground work.
19464                            if (client.curSchedGroup > schedGroup) {
19465                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19466                                    schedGroup = client.curSchedGroup;
19467                                } else {
19468                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19469                                }
19470                            }
19471                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19472                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19473                                    // Special handling of clients who are in the top state.
19474                                    // We *may* want to consider this process to be in the
19475                                    // top state as well, but only if there is not another
19476                                    // reason for it to be running.  Being on the top is a
19477                                    // special state, meaning you are specifically running
19478                                    // for the current top app.  If the process is already
19479                                    // running in the background for some other reason, it
19480                                    // is more important to continue considering it to be
19481                                    // in the background state.
19482                                    mayBeTop = true;
19483                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19484                                } else {
19485                                    // Special handling for above-top states (persistent
19486                                    // processes).  These should not bring the current process
19487                                    // into the top state, since they are not on top.  Instead
19488                                    // give them the best state after that.
19489                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19490                                        clientProcState =
19491                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19492                                    } else if (mWakefulness
19493                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19494                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19495                                                    != 0) {
19496                                        clientProcState =
19497                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19498                                    } else {
19499                                        clientProcState =
19500                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19501                                    }
19502                                }
19503                            }
19504                        } else {
19505                            if (clientProcState <
19506                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19507                                clientProcState =
19508                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19509                            }
19510                        }
19511                        if (procState > clientProcState) {
19512                            procState = clientProcState;
19513                        }
19514                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19515                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19516                            app.pendingUiClean = true;
19517                        }
19518                        if (adjType != null) {
19519                            app.adjType = adjType;
19520                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19521                                    .REASON_SERVICE_IN_USE;
19522                            app.adjSource = cr.binding.client;
19523                            app.adjSourceProcState = clientProcState;
19524                            app.adjTarget = s.name;
19525                        }
19526                    }
19527                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19528                        app.treatLikeActivity = true;
19529                    }
19530                    final ActivityRecord a = cr.activity;
19531                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19532                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19533                            (a.visible || a.state == ActivityState.RESUMED ||
19534                             a.state == ActivityState.PAUSING)) {
19535                            adj = ProcessList.FOREGROUND_APP_ADJ;
19536                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19537                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19538                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19539                                } else {
19540                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19541                                }
19542                            }
19543                            app.cached = false;
19544                            app.adjType = "service";
19545                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19546                                    .REASON_SERVICE_IN_USE;
19547                            app.adjSource = a;
19548                            app.adjSourceProcState = procState;
19549                            app.adjTarget = s.name;
19550                        }
19551                    }
19552                }
19553            }
19554        }
19555
19556        for (int provi = app.pubProviders.size()-1;
19557                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19558                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19559                        || procState > ActivityManager.PROCESS_STATE_TOP);
19560                provi--) {
19561            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19562            for (int i = cpr.connections.size()-1;
19563                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19564                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19565                            || procState > ActivityManager.PROCESS_STATE_TOP);
19566                    i--) {
19567                ContentProviderConnection conn = cpr.connections.get(i);
19568                ProcessRecord client = conn.client;
19569                if (client == app) {
19570                    // Being our own client is not interesting.
19571                    continue;
19572                }
19573                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19574                int clientProcState = client.curProcState;
19575                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19576                    // If the other app is cached for any reason, for purposes here
19577                    // we are going to consider it empty.
19578                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19579                }
19580                if (adj > clientAdj) {
19581                    if (app.hasShownUi && app != mHomeProcess
19582                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19583                        app.adjType = "cch-ui-provider";
19584                    } else {
19585                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19586                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19587                        app.adjType = "provider";
19588                    }
19589                    app.cached &= client.cached;
19590                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19591                            .REASON_PROVIDER_IN_USE;
19592                    app.adjSource = client;
19593                    app.adjSourceProcState = clientProcState;
19594                    app.adjTarget = cpr.name;
19595                }
19596                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19597                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19598                        // Special handling of clients who are in the top state.
19599                        // We *may* want to consider this process to be in the
19600                        // top state as well, but only if there is not another
19601                        // reason for it to be running.  Being on the top is a
19602                        // special state, meaning you are specifically running
19603                        // for the current top app.  If the process is already
19604                        // running in the background for some other reason, it
19605                        // is more important to continue considering it to be
19606                        // in the background state.
19607                        mayBeTop = true;
19608                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19609                    } else {
19610                        // Special handling for above-top states (persistent
19611                        // processes).  These should not bring the current process
19612                        // into the top state, since they are not on top.  Instead
19613                        // give them the best state after that.
19614                        clientProcState =
19615                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19616                    }
19617                }
19618                if (procState > clientProcState) {
19619                    procState = clientProcState;
19620                }
19621                if (client.curSchedGroup > schedGroup) {
19622                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19623                }
19624            }
19625            // If the provider has external (non-framework) process
19626            // dependencies, ensure that its adjustment is at least
19627            // FOREGROUND_APP_ADJ.
19628            if (cpr.hasExternalProcessHandles()) {
19629                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19630                    adj = ProcessList.FOREGROUND_APP_ADJ;
19631                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19632                    app.cached = false;
19633                    app.adjType = "provider";
19634                    app.adjTarget = cpr.name;
19635                }
19636                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19637                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19638                }
19639            }
19640        }
19641
19642        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19643            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19644                adj = ProcessList.PREVIOUS_APP_ADJ;
19645                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19646                app.cached = false;
19647                app.adjType = "provider";
19648            }
19649            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19650                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19651            }
19652        }
19653
19654        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19655            // A client of one of our services or providers is in the top state.  We
19656            // *may* want to be in the top state, but not if we are already running in
19657            // the background for some other reason.  For the decision here, we are going
19658            // to pick out a few specific states that we want to remain in when a client
19659            // is top (states that tend to be longer-term) and otherwise allow it to go
19660            // to the top state.
19661            switch (procState) {
19662                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19663                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19664                case ActivityManager.PROCESS_STATE_SERVICE:
19665                    // These all are longer-term states, so pull them up to the top
19666                    // of the background states, but not all the way to the top state.
19667                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19668                    break;
19669                default:
19670                    // Otherwise, top is a better choice, so take it.
19671                    procState = ActivityManager.PROCESS_STATE_TOP;
19672                    break;
19673            }
19674        }
19675
19676        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19677            if (app.hasClientActivities) {
19678                // This is a cached process, but with client activities.  Mark it so.
19679                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19680                app.adjType = "cch-client-act";
19681            } else if (app.treatLikeActivity) {
19682                // This is a cached process, but somebody wants us to treat it like it has
19683                // an activity, okay!
19684                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19685                app.adjType = "cch-as-act";
19686            }
19687        }
19688
19689        if (adj == ProcessList.SERVICE_ADJ) {
19690            if (doingAll) {
19691                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19692                mNewNumServiceProcs++;
19693                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19694                if (!app.serviceb) {
19695                    // This service isn't far enough down on the LRU list to
19696                    // normally be a B service, but if we are low on RAM and it
19697                    // is large we want to force it down since we would prefer to
19698                    // keep launcher over it.
19699                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19700                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19701                        app.serviceHighRam = true;
19702                        app.serviceb = true;
19703                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19704                    } else {
19705                        mNewNumAServiceProcs++;
19706                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19707                    }
19708                } else {
19709                    app.serviceHighRam = false;
19710                }
19711            }
19712            if (app.serviceb) {
19713                adj = ProcessList.SERVICE_B_ADJ;
19714            }
19715        }
19716
19717        app.curRawAdj = adj;
19718
19719        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19720        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19721        if (adj > app.maxAdj) {
19722            adj = app.maxAdj;
19723            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19724                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19725            }
19726        }
19727
19728        // Do final modification to adj.  Everything we do between here and applying
19729        // the final setAdj must be done in this function, because we will also use
19730        // it when computing the final cached adj later.  Note that we don't need to
19731        // worry about this for max adj above, since max adj will always be used to
19732        // keep it out of the cached vaues.
19733        app.curAdj = app.modifyRawOomAdj(adj);
19734        app.curSchedGroup = schedGroup;
19735        app.curProcState = procState;
19736        app.foregroundActivities = foregroundActivities;
19737
19738        return app.curRawAdj;
19739    }
19740
19741    /**
19742     * Record new PSS sample for a process.
19743     */
19744    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19745            long now) {
19746        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19747                swapPss * 1024);
19748        proc.lastPssTime = now;
19749        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19750        if (DEBUG_PSS) Slog.d(TAG_PSS,
19751                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19752                + " state=" + ProcessList.makeProcStateString(procState));
19753        if (proc.initialIdlePss == 0) {
19754            proc.initialIdlePss = pss;
19755        }
19756        proc.lastPss = pss;
19757        proc.lastSwapPss = swapPss;
19758        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19759            proc.lastCachedPss = pss;
19760            proc.lastCachedSwapPss = swapPss;
19761        }
19762
19763        final SparseArray<Pair<Long, String>> watchUids
19764                = mMemWatchProcesses.getMap().get(proc.processName);
19765        Long check = null;
19766        if (watchUids != null) {
19767            Pair<Long, String> val = watchUids.get(proc.uid);
19768            if (val == null) {
19769                val = watchUids.get(0);
19770            }
19771            if (val != null) {
19772                check = val.first;
19773            }
19774        }
19775        if (check != null) {
19776            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19777                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19778                if (!isDebuggable) {
19779                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19780                        isDebuggable = true;
19781                    }
19782                }
19783                if (isDebuggable) {
19784                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19785                    final ProcessRecord myProc = proc;
19786                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19787                    mMemWatchDumpProcName = proc.processName;
19788                    mMemWatchDumpFile = heapdumpFile.toString();
19789                    mMemWatchDumpPid = proc.pid;
19790                    mMemWatchDumpUid = proc.uid;
19791                    BackgroundThread.getHandler().post(new Runnable() {
19792                        @Override
19793                        public void run() {
19794                            revokeUriPermission(ActivityThread.currentActivityThread()
19795                                            .getApplicationThread(),
19796                                    DumpHeapActivity.JAVA_URI,
19797                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19798                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19799                                    UserHandle.myUserId());
19800                            ParcelFileDescriptor fd = null;
19801                            try {
19802                                heapdumpFile.delete();
19803                                fd = ParcelFileDescriptor.open(heapdumpFile,
19804                                        ParcelFileDescriptor.MODE_CREATE |
19805                                                ParcelFileDescriptor.MODE_TRUNCATE |
19806                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19807                                                ParcelFileDescriptor.MODE_APPEND);
19808                                IApplicationThread thread = myProc.thread;
19809                                if (thread != null) {
19810                                    try {
19811                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19812                                                "Requesting dump heap from "
19813                                                + myProc + " to " + heapdumpFile);
19814                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19815                                    } catch (RemoteException e) {
19816                                    }
19817                                }
19818                            } catch (FileNotFoundException e) {
19819                                e.printStackTrace();
19820                            } finally {
19821                                if (fd != null) {
19822                                    try {
19823                                        fd.close();
19824                                    } catch (IOException e) {
19825                                    }
19826                                }
19827                            }
19828                        }
19829                    });
19830                } else {
19831                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19832                            + ", but debugging not enabled");
19833                }
19834            }
19835        }
19836    }
19837
19838    /**
19839     * Schedule PSS collection of a process.
19840     */
19841    void requestPssLocked(ProcessRecord proc, int procState) {
19842        if (mPendingPssProcesses.contains(proc)) {
19843            return;
19844        }
19845        if (mPendingPssProcesses.size() == 0) {
19846            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19847        }
19848        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19849        proc.pssProcState = procState;
19850        mPendingPssProcesses.add(proc);
19851    }
19852
19853    /**
19854     * Schedule PSS collection of all processes.
19855     */
19856    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19857        if (!always) {
19858            if (now < (mLastFullPssTime +
19859                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19860                return;
19861            }
19862        }
19863        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19864        mLastFullPssTime = now;
19865        mFullPssPending = true;
19866        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19867        mPendingPssProcesses.clear();
19868        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19869            ProcessRecord app = mLruProcesses.get(i);
19870            if (app.thread == null
19871                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19872                continue;
19873            }
19874            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19875                app.pssProcState = app.setProcState;
19876                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19877                        mTestPssMode, isSleepingLocked(), now);
19878                mPendingPssProcesses.add(app);
19879            }
19880        }
19881        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19882    }
19883
19884    public void setTestPssMode(boolean enabled) {
19885        synchronized (this) {
19886            mTestPssMode = enabled;
19887            if (enabled) {
19888                // Whenever we enable the mode, we want to take a snapshot all of current
19889                // process mem use.
19890                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19891            }
19892        }
19893    }
19894
19895    /**
19896     * Ask a given process to GC right now.
19897     */
19898    final void performAppGcLocked(ProcessRecord app) {
19899        try {
19900            app.lastRequestedGc = SystemClock.uptimeMillis();
19901            if (app.thread != null) {
19902                if (app.reportLowMemory) {
19903                    app.reportLowMemory = false;
19904                    app.thread.scheduleLowMemory();
19905                } else {
19906                    app.thread.processInBackground();
19907                }
19908            }
19909        } catch (Exception e) {
19910            // whatever.
19911        }
19912    }
19913
19914    /**
19915     * Returns true if things are idle enough to perform GCs.
19916     */
19917    private final boolean canGcNowLocked() {
19918        boolean processingBroadcasts = false;
19919        for (BroadcastQueue q : mBroadcastQueues) {
19920            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19921                processingBroadcasts = true;
19922            }
19923        }
19924        return !processingBroadcasts
19925                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19926    }
19927
19928    /**
19929     * Perform GCs on all processes that are waiting for it, but only
19930     * if things are idle.
19931     */
19932    final void performAppGcsLocked() {
19933        final int N = mProcessesToGc.size();
19934        if (N <= 0) {
19935            return;
19936        }
19937        if (canGcNowLocked()) {
19938            while (mProcessesToGc.size() > 0) {
19939                ProcessRecord proc = mProcessesToGc.remove(0);
19940                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19941                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19942                            <= SystemClock.uptimeMillis()) {
19943                        // To avoid spamming the system, we will GC processes one
19944                        // at a time, waiting a few seconds between each.
19945                        performAppGcLocked(proc);
19946                        scheduleAppGcsLocked();
19947                        return;
19948                    } else {
19949                        // It hasn't been long enough since we last GCed this
19950                        // process...  put it in the list to wait for its time.
19951                        addProcessToGcListLocked(proc);
19952                        break;
19953                    }
19954                }
19955            }
19956
19957            scheduleAppGcsLocked();
19958        }
19959    }
19960
19961    /**
19962     * If all looks good, perform GCs on all processes waiting for them.
19963     */
19964    final void performAppGcsIfAppropriateLocked() {
19965        if (canGcNowLocked()) {
19966            performAppGcsLocked();
19967            return;
19968        }
19969        // Still not idle, wait some more.
19970        scheduleAppGcsLocked();
19971    }
19972
19973    /**
19974     * Schedule the execution of all pending app GCs.
19975     */
19976    final void scheduleAppGcsLocked() {
19977        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19978
19979        if (mProcessesToGc.size() > 0) {
19980            // Schedule a GC for the time to the next process.
19981            ProcessRecord proc = mProcessesToGc.get(0);
19982            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19983
19984            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19985            long now = SystemClock.uptimeMillis();
19986            if (when < (now+GC_TIMEOUT)) {
19987                when = now + GC_TIMEOUT;
19988            }
19989            mHandler.sendMessageAtTime(msg, when);
19990        }
19991    }
19992
19993    /**
19994     * Add a process to the array of processes waiting to be GCed.  Keeps the
19995     * list in sorted order by the last GC time.  The process can't already be
19996     * on the list.
19997     */
19998    final void addProcessToGcListLocked(ProcessRecord proc) {
19999        boolean added = false;
20000        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20001            if (mProcessesToGc.get(i).lastRequestedGc <
20002                    proc.lastRequestedGc) {
20003                added = true;
20004                mProcessesToGc.add(i+1, proc);
20005                break;
20006            }
20007        }
20008        if (!added) {
20009            mProcessesToGc.add(0, proc);
20010        }
20011    }
20012
20013    /**
20014     * Set up to ask a process to GC itself.  This will either do it
20015     * immediately, or put it on the list of processes to gc the next
20016     * time things are idle.
20017     */
20018    final void scheduleAppGcLocked(ProcessRecord app) {
20019        long now = SystemClock.uptimeMillis();
20020        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20021            return;
20022        }
20023        if (!mProcessesToGc.contains(app)) {
20024            addProcessToGcListLocked(app);
20025            scheduleAppGcsLocked();
20026        }
20027    }
20028
20029    final void checkExcessivePowerUsageLocked(boolean doKills) {
20030        updateCpuStatsNow();
20031
20032        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20033        boolean doWakeKills = doKills;
20034        boolean doCpuKills = doKills;
20035        if (mLastPowerCheckRealtime == 0) {
20036            doWakeKills = false;
20037        }
20038        if (mLastPowerCheckUptime == 0) {
20039            doCpuKills = false;
20040        }
20041        if (stats.isScreenOn()) {
20042            doWakeKills = false;
20043        }
20044        final long curRealtime = SystemClock.elapsedRealtime();
20045        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20046        final long curUptime = SystemClock.uptimeMillis();
20047        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20048        mLastPowerCheckRealtime = curRealtime;
20049        mLastPowerCheckUptime = curUptime;
20050        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20051            doWakeKills = false;
20052        }
20053        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20054            doCpuKills = false;
20055        }
20056        int i = mLruProcesses.size();
20057        while (i > 0) {
20058            i--;
20059            ProcessRecord app = mLruProcesses.get(i);
20060            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20061                long wtime;
20062                synchronized (stats) {
20063                    wtime = stats.getProcessWakeTime(app.info.uid,
20064                            app.pid, curRealtime);
20065                }
20066                long wtimeUsed = wtime - app.lastWakeTime;
20067                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20068                if (DEBUG_POWER) {
20069                    StringBuilder sb = new StringBuilder(128);
20070                    sb.append("Wake for ");
20071                    app.toShortString(sb);
20072                    sb.append(": over ");
20073                    TimeUtils.formatDuration(realtimeSince, sb);
20074                    sb.append(" used ");
20075                    TimeUtils.formatDuration(wtimeUsed, sb);
20076                    sb.append(" (");
20077                    sb.append((wtimeUsed*100)/realtimeSince);
20078                    sb.append("%)");
20079                    Slog.i(TAG_POWER, sb.toString());
20080                    sb.setLength(0);
20081                    sb.append("CPU for ");
20082                    app.toShortString(sb);
20083                    sb.append(": over ");
20084                    TimeUtils.formatDuration(uptimeSince, sb);
20085                    sb.append(" used ");
20086                    TimeUtils.formatDuration(cputimeUsed, sb);
20087                    sb.append(" (");
20088                    sb.append((cputimeUsed*100)/uptimeSince);
20089                    sb.append("%)");
20090                    Slog.i(TAG_POWER, sb.toString());
20091                }
20092                // If a process has held a wake lock for more
20093                // than 50% of the time during this period,
20094                // that sounds bad.  Kill!
20095                if (doWakeKills && realtimeSince > 0
20096                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20097                    synchronized (stats) {
20098                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20099                                realtimeSince, wtimeUsed);
20100                    }
20101                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20102                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20103                } else if (doCpuKills && uptimeSince > 0
20104                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20105                    synchronized (stats) {
20106                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20107                                uptimeSince, cputimeUsed);
20108                    }
20109                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20110                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20111                } else {
20112                    app.lastWakeTime = wtime;
20113                    app.lastCpuTime = app.curCpuTime;
20114                }
20115            }
20116        }
20117    }
20118
20119    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20120            long nowElapsed) {
20121        boolean success = true;
20122
20123        if (app.curRawAdj != app.setRawAdj) {
20124            app.setRawAdj = app.curRawAdj;
20125        }
20126
20127        int changes = 0;
20128
20129        if (app.curAdj != app.setAdj) {
20130            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20131            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20132                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20133                    + app.adjType);
20134            app.setAdj = app.curAdj;
20135            app.verifiedAdj = ProcessList.INVALID_ADJ;
20136        }
20137
20138        if (app.setSchedGroup != app.curSchedGroup) {
20139            app.setSchedGroup = app.curSchedGroup;
20140            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20141                    "Setting sched group of " + app.processName
20142                    + " to " + app.curSchedGroup);
20143            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20144                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20145                app.kill(app.waitingToKill, true);
20146                success = false;
20147            } else {
20148                int processGroup;
20149                switch (app.curSchedGroup) {
20150                    case ProcessList.SCHED_GROUP_BACKGROUND:
20151                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20152                        break;
20153                    case ProcessList.SCHED_GROUP_TOP_APP:
20154                        processGroup = Process.THREAD_GROUP_TOP_APP;
20155                        break;
20156                    default:
20157                        processGroup = Process.THREAD_GROUP_DEFAULT;
20158                        break;
20159                }
20160                if (true) {
20161                    long oldId = Binder.clearCallingIdentity();
20162                    try {
20163                        Process.setProcessGroup(app.pid, processGroup);
20164                    } catch (Exception e) {
20165                        Slog.w(TAG, "Failed setting process group of " + app.pid
20166                                + " to " + app.curSchedGroup);
20167                        e.printStackTrace();
20168                    } finally {
20169                        Binder.restoreCallingIdentity(oldId);
20170                    }
20171                } else {
20172                    if (app.thread != null) {
20173                        try {
20174                            app.thread.setSchedulingGroup(processGroup);
20175                        } catch (RemoteException e) {
20176                        }
20177                    }
20178                }
20179            }
20180        }
20181        if (app.repForegroundActivities != app.foregroundActivities) {
20182            app.repForegroundActivities = app.foregroundActivities;
20183            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20184        }
20185        if (app.repProcState != app.curProcState) {
20186            app.repProcState = app.curProcState;
20187            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20188            if (app.thread != null) {
20189                try {
20190                    if (false) {
20191                        //RuntimeException h = new RuntimeException("here");
20192                        Slog.i(TAG, "Sending new process state " + app.repProcState
20193                                + " to " + app /*, h*/);
20194                    }
20195                    app.thread.setProcessState(app.repProcState);
20196                } catch (RemoteException e) {
20197                }
20198            }
20199        }
20200        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20201                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20202            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20203                // Experimental code to more aggressively collect pss while
20204                // running test...  the problem is that this tends to collect
20205                // the data right when a process is transitioning between process
20206                // states, which well tend to give noisy data.
20207                long start = SystemClock.uptimeMillis();
20208                long pss = Debug.getPss(app.pid, mTmpLong, null);
20209                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20210                mPendingPssProcesses.remove(app);
20211                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20212                        + " to " + app.curProcState + ": "
20213                        + (SystemClock.uptimeMillis()-start) + "ms");
20214            }
20215            app.lastStateTime = now;
20216            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20217                    mTestPssMode, isSleepingLocked(), now);
20218            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20219                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20220                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20221                    + (app.nextPssTime-now) + ": " + app);
20222        } else {
20223            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20224                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20225                    mTestPssMode)))) {
20226                requestPssLocked(app, app.setProcState);
20227                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20228                        mTestPssMode, isSleepingLocked(), now);
20229            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20230                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20231        }
20232        if (app.setProcState != app.curProcState) {
20233            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20234                    "Proc state change of " + app.processName
20235                            + " to " + app.curProcState);
20236            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20237            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20238            if (setImportant && !curImportant) {
20239                // This app is no longer something we consider important enough to allow to
20240                // use arbitrary amounts of battery power.  Note
20241                // its current wake lock time to later know to kill it if
20242                // it is not behaving well.
20243                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20244                synchronized (stats) {
20245                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20246                            app.pid, nowElapsed);
20247                }
20248                app.lastCpuTime = app.curCpuTime;
20249
20250            }
20251            // Inform UsageStats of important process state change
20252            // Must be called before updating setProcState
20253            maybeUpdateUsageStatsLocked(app, nowElapsed);
20254
20255            app.setProcState = app.curProcState;
20256            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20257                app.notCachedSinceIdle = false;
20258            }
20259            if (!doingAll) {
20260                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20261            } else {
20262                app.procStateChanged = true;
20263            }
20264        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20265                > USAGE_STATS_INTERACTION_INTERVAL) {
20266            // For apps that sit around for a long time in the interactive state, we need
20267            // to report this at least once a day so they don't go idle.
20268            maybeUpdateUsageStatsLocked(app, nowElapsed);
20269        }
20270
20271        if (changes != 0) {
20272            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20273                    "Changes in " + app + ": " + changes);
20274            int i = mPendingProcessChanges.size()-1;
20275            ProcessChangeItem item = null;
20276            while (i >= 0) {
20277                item = mPendingProcessChanges.get(i);
20278                if (item.pid == app.pid) {
20279                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20280                            "Re-using existing item: " + item);
20281                    break;
20282                }
20283                i--;
20284            }
20285            if (i < 0) {
20286                // No existing item in pending changes; need a new one.
20287                final int NA = mAvailProcessChanges.size();
20288                if (NA > 0) {
20289                    item = mAvailProcessChanges.remove(NA-1);
20290                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20291                            "Retrieving available item: " + item);
20292                } else {
20293                    item = new ProcessChangeItem();
20294                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20295                            "Allocating new item: " + item);
20296                }
20297                item.changes = 0;
20298                item.pid = app.pid;
20299                item.uid = app.info.uid;
20300                if (mPendingProcessChanges.size() == 0) {
20301                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20302                            "*** Enqueueing dispatch processes changed!");
20303                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20304                }
20305                mPendingProcessChanges.add(item);
20306            }
20307            item.changes |= changes;
20308            item.processState = app.repProcState;
20309            item.foregroundActivities = app.repForegroundActivities;
20310            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20311                    "Item " + Integer.toHexString(System.identityHashCode(item))
20312                    + " " + app.toShortString() + ": changes=" + item.changes
20313                    + " procState=" + item.processState
20314                    + " foreground=" + item.foregroundActivities
20315                    + " type=" + app.adjType + " source=" + app.adjSource
20316                    + " target=" + app.adjTarget);
20317        }
20318
20319        return success;
20320    }
20321
20322    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20323        final UidRecord.ChangeItem pendingChange;
20324        if (uidRec == null || uidRec.pendingChange == null) {
20325            if (mPendingUidChanges.size() == 0) {
20326                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20327                        "*** Enqueueing dispatch uid changed!");
20328                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20329            }
20330            final int NA = mAvailUidChanges.size();
20331            if (NA > 0) {
20332                pendingChange = mAvailUidChanges.remove(NA-1);
20333                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20334                        "Retrieving available item: " + pendingChange);
20335            } else {
20336                pendingChange = new UidRecord.ChangeItem();
20337                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20338                        "Allocating new item: " + pendingChange);
20339            }
20340            if (uidRec != null) {
20341                uidRec.pendingChange = pendingChange;
20342                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20343                    // If this uid is going away, and we haven't yet reported it is gone,
20344                    // then do so now.
20345                    change = UidRecord.CHANGE_GONE_IDLE;
20346                }
20347            } else if (uid < 0) {
20348                throw new IllegalArgumentException("No UidRecord or uid");
20349            }
20350            pendingChange.uidRecord = uidRec;
20351            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20352            mPendingUidChanges.add(pendingChange);
20353        } else {
20354            pendingChange = uidRec.pendingChange;
20355            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20356                change = UidRecord.CHANGE_GONE_IDLE;
20357            }
20358        }
20359        pendingChange.change = change;
20360        pendingChange.processState = uidRec != null
20361                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20362    }
20363
20364    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20365            String authority) {
20366        if (app == null) return;
20367        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20368            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20369            if (userState == null) return;
20370            final long now = SystemClock.elapsedRealtime();
20371            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20372            if (lastReported == null || lastReported < now - 60 * 1000L) {
20373                mUsageStatsService.reportContentProviderUsage(
20374                        authority, providerPkgName, app.userId);
20375                userState.mProviderLastReportedFg.put(authority, now);
20376            }
20377        }
20378    }
20379
20380    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20381        if (DEBUG_USAGE_STATS) {
20382            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20383                    + "] state changes: old = " + app.setProcState + ", new = "
20384                    + app.curProcState);
20385        }
20386        if (mUsageStatsService == null) {
20387            return;
20388        }
20389        boolean isInteraction;
20390        // To avoid some abuse patterns, we are going to be careful about what we consider
20391        // to be an app interaction.  Being the top activity doesn't count while the display
20392        // is sleeping, nor do short foreground services.
20393        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20394            isInteraction = true;
20395            app.fgInteractionTime = 0;
20396        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20397            if (app.fgInteractionTime == 0) {
20398                app.fgInteractionTime = nowElapsed;
20399                isInteraction = false;
20400            } else {
20401                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20402            }
20403        } else {
20404            isInteraction = app.curProcState
20405                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20406            app.fgInteractionTime = 0;
20407        }
20408        if (isInteraction && (!app.reportedInteraction
20409                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20410            app.interactionEventTime = nowElapsed;
20411            String[] packages = app.getPackageList();
20412            if (packages != null) {
20413                for (int i = 0; i < packages.length; i++) {
20414                    mUsageStatsService.reportEvent(packages[i], app.userId,
20415                            UsageEvents.Event.SYSTEM_INTERACTION);
20416                }
20417            }
20418        }
20419        app.reportedInteraction = isInteraction;
20420        if (!isInteraction) {
20421            app.interactionEventTime = 0;
20422        }
20423    }
20424
20425    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20426        if (proc.thread != null) {
20427            if (proc.baseProcessTracker != null) {
20428                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20429            }
20430        }
20431    }
20432
20433    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20434            ProcessRecord TOP_APP, boolean doingAll, long now) {
20435        if (app.thread == null) {
20436            return false;
20437        }
20438
20439        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20440
20441        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20442    }
20443
20444    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20445            boolean oomAdj) {
20446        if (isForeground != proc.foregroundServices) {
20447            proc.foregroundServices = isForeground;
20448            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20449                    proc.info.uid);
20450            if (isForeground) {
20451                if (curProcs == null) {
20452                    curProcs = new ArrayList<ProcessRecord>();
20453                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20454                }
20455                if (!curProcs.contains(proc)) {
20456                    curProcs.add(proc);
20457                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20458                            proc.info.packageName, proc.info.uid);
20459                }
20460            } else {
20461                if (curProcs != null) {
20462                    if (curProcs.remove(proc)) {
20463                        mBatteryStatsService.noteEvent(
20464                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20465                                proc.info.packageName, proc.info.uid);
20466                        if (curProcs.size() <= 0) {
20467                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20468                        }
20469                    }
20470                }
20471            }
20472            if (oomAdj) {
20473                updateOomAdjLocked();
20474            }
20475        }
20476    }
20477
20478    private final ActivityRecord resumedAppLocked() {
20479        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20480        String pkg;
20481        int uid;
20482        if (act != null) {
20483            pkg = act.packageName;
20484            uid = act.info.applicationInfo.uid;
20485        } else {
20486            pkg = null;
20487            uid = -1;
20488        }
20489        // Has the UID or resumed package name changed?
20490        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20491                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20492            if (mCurResumedPackage != null) {
20493                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20494                        mCurResumedPackage, mCurResumedUid);
20495            }
20496            mCurResumedPackage = pkg;
20497            mCurResumedUid = uid;
20498            if (mCurResumedPackage != null) {
20499                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20500                        mCurResumedPackage, mCurResumedUid);
20501            }
20502        }
20503        return act;
20504    }
20505
20506    final boolean updateOomAdjLocked(ProcessRecord app) {
20507        final ActivityRecord TOP_ACT = resumedAppLocked();
20508        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20509        final boolean wasCached = app.cached;
20510
20511        mAdjSeq++;
20512
20513        // This is the desired cached adjusment we want to tell it to use.
20514        // If our app is currently cached, we know it, and that is it.  Otherwise,
20515        // we don't know it yet, and it needs to now be cached we will then
20516        // need to do a complete oom adj.
20517        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20518                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20519        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20520                SystemClock.uptimeMillis());
20521        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20522            // Changed to/from cached state, so apps after it in the LRU
20523            // list may also be changed.
20524            updateOomAdjLocked();
20525        }
20526        return success;
20527    }
20528
20529    final void updateOomAdjLocked() {
20530        final ActivityRecord TOP_ACT = resumedAppLocked();
20531        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20532        final long now = SystemClock.uptimeMillis();
20533        final long nowElapsed = SystemClock.elapsedRealtime();
20534        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20535        final int N = mLruProcesses.size();
20536
20537        if (false) {
20538            RuntimeException e = new RuntimeException();
20539            e.fillInStackTrace();
20540            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20541        }
20542
20543        // Reset state in all uid records.
20544        for (int i=mActiveUids.size()-1; i>=0; i--) {
20545            final UidRecord uidRec = mActiveUids.valueAt(i);
20546            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20547                    "Starting update of " + uidRec);
20548            uidRec.reset();
20549        }
20550
20551        mStackSupervisor.rankTaskLayersIfNeeded();
20552
20553        mAdjSeq++;
20554        mNewNumServiceProcs = 0;
20555        mNewNumAServiceProcs = 0;
20556
20557        final int emptyProcessLimit;
20558        final int cachedProcessLimit;
20559        if (mProcessLimit <= 0) {
20560            emptyProcessLimit = cachedProcessLimit = 0;
20561        } else if (mProcessLimit == 1) {
20562            emptyProcessLimit = 1;
20563            cachedProcessLimit = 0;
20564        } else {
20565            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20566            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20567        }
20568
20569        // Let's determine how many processes we have running vs.
20570        // how many slots we have for background processes; we may want
20571        // to put multiple processes in a slot of there are enough of
20572        // them.
20573        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20574                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20575        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20576        if (numEmptyProcs > cachedProcessLimit) {
20577            // If there are more empty processes than our limit on cached
20578            // processes, then use the cached process limit for the factor.
20579            // This ensures that the really old empty processes get pushed
20580            // down to the bottom, so if we are running low on memory we will
20581            // have a better chance at keeping around more cached processes
20582            // instead of a gazillion empty processes.
20583            numEmptyProcs = cachedProcessLimit;
20584        }
20585        int emptyFactor = numEmptyProcs/numSlots;
20586        if (emptyFactor < 1) emptyFactor = 1;
20587        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20588        if (cachedFactor < 1) cachedFactor = 1;
20589        int stepCached = 0;
20590        int stepEmpty = 0;
20591        int numCached = 0;
20592        int numEmpty = 0;
20593        int numTrimming = 0;
20594
20595        mNumNonCachedProcs = 0;
20596        mNumCachedHiddenProcs = 0;
20597
20598        // First update the OOM adjustment for each of the
20599        // application processes based on their current state.
20600        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20601        int nextCachedAdj = curCachedAdj+1;
20602        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20603        int nextEmptyAdj = curEmptyAdj+2;
20604        for (int i=N-1; i>=0; i--) {
20605            ProcessRecord app = mLruProcesses.get(i);
20606            if (!app.killedByAm && app.thread != null) {
20607                app.procStateChanged = false;
20608                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20609
20610                // If we haven't yet assigned the final cached adj
20611                // to the process, do that now.
20612                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20613                    switch (app.curProcState) {
20614                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20615                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20616                            // This process is a cached process holding activities...
20617                            // assign it the next cached value for that type, and then
20618                            // step that cached level.
20619                            app.curRawAdj = curCachedAdj;
20620                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20621                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20622                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20623                                    + ")");
20624                            if (curCachedAdj != nextCachedAdj) {
20625                                stepCached++;
20626                                if (stepCached >= cachedFactor) {
20627                                    stepCached = 0;
20628                                    curCachedAdj = nextCachedAdj;
20629                                    nextCachedAdj += 2;
20630                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20631                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20632                                    }
20633                                }
20634                            }
20635                            break;
20636                        default:
20637                            // For everything else, assign next empty cached process
20638                            // level and bump that up.  Note that this means that
20639                            // long-running services that have dropped down to the
20640                            // cached level will be treated as empty (since their process
20641                            // state is still as a service), which is what we want.
20642                            app.curRawAdj = curEmptyAdj;
20643                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20644                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20645                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20646                                    + ")");
20647                            if (curEmptyAdj != nextEmptyAdj) {
20648                                stepEmpty++;
20649                                if (stepEmpty >= emptyFactor) {
20650                                    stepEmpty = 0;
20651                                    curEmptyAdj = nextEmptyAdj;
20652                                    nextEmptyAdj += 2;
20653                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20654                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20655                                    }
20656                                }
20657                            }
20658                            break;
20659                    }
20660                }
20661
20662                applyOomAdjLocked(app, true, now, nowElapsed);
20663
20664                // Count the number of process types.
20665                switch (app.curProcState) {
20666                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20667                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20668                        mNumCachedHiddenProcs++;
20669                        numCached++;
20670                        if (numCached > cachedProcessLimit) {
20671                            app.kill("cached #" + numCached, true);
20672                        }
20673                        break;
20674                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20675                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20676                                && app.lastActivityTime < oldTime) {
20677                            app.kill("empty for "
20678                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20679                                    / 1000) + "s", true);
20680                        } else {
20681                            numEmpty++;
20682                            if (numEmpty > emptyProcessLimit) {
20683                                app.kill("empty #" + numEmpty, true);
20684                            }
20685                        }
20686                        break;
20687                    default:
20688                        mNumNonCachedProcs++;
20689                        break;
20690                }
20691
20692                if (app.isolated && app.services.size() <= 0) {
20693                    // If this is an isolated process, and there are no
20694                    // services running in it, then the process is no longer
20695                    // needed.  We agressively kill these because we can by
20696                    // definition not re-use the same process again, and it is
20697                    // good to avoid having whatever code was running in them
20698                    // left sitting around after no longer needed.
20699                    app.kill("isolated not needed", true);
20700                } else {
20701                    // Keeping this process, update its uid.
20702                    final UidRecord uidRec = app.uidRecord;
20703                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20704                        uidRec.curProcState = app.curProcState;
20705                    }
20706                }
20707
20708                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20709                        && !app.killedByAm) {
20710                    numTrimming++;
20711                }
20712            }
20713        }
20714
20715        mNumServiceProcs = mNewNumServiceProcs;
20716
20717        // Now determine the memory trimming level of background processes.
20718        // Unfortunately we need to start at the back of the list to do this
20719        // properly.  We only do this if the number of background apps we
20720        // are managing to keep around is less than half the maximum we desire;
20721        // if we are keeping a good number around, we'll let them use whatever
20722        // memory they want.
20723        final int numCachedAndEmpty = numCached + numEmpty;
20724        int memFactor;
20725        if (numCached <= ProcessList.TRIM_CACHED_APPS
20726                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20727            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20728                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20729            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20730                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20731            } else {
20732                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20733            }
20734        } else {
20735            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20736        }
20737        // We always allow the memory level to go up (better).  We only allow it to go
20738        // down if we are in a state where that is allowed, *and* the total number of processes
20739        // has gone down since last time.
20740        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20741                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20742                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20743        if (memFactor > mLastMemoryLevel) {
20744            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20745                memFactor = mLastMemoryLevel;
20746                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20747            }
20748        }
20749        if (memFactor != mLastMemoryLevel) {
20750            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20751        }
20752        mLastMemoryLevel = memFactor;
20753        mLastNumProcesses = mLruProcesses.size();
20754        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20755        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20756        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20757            if (mLowRamStartTime == 0) {
20758                mLowRamStartTime = now;
20759            }
20760            int step = 0;
20761            int fgTrimLevel;
20762            switch (memFactor) {
20763                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20764                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20765                    break;
20766                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20767                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20768                    break;
20769                default:
20770                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20771                    break;
20772            }
20773            int factor = numTrimming/3;
20774            int minFactor = 2;
20775            if (mHomeProcess != null) minFactor++;
20776            if (mPreviousProcess != null) minFactor++;
20777            if (factor < minFactor) factor = minFactor;
20778            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20779            for (int i=N-1; i>=0; i--) {
20780                ProcessRecord app = mLruProcesses.get(i);
20781                if (allChanged || app.procStateChanged) {
20782                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20783                    app.procStateChanged = false;
20784                }
20785                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20786                        && !app.killedByAm) {
20787                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20788                        try {
20789                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20790                                    "Trimming memory of " + app.processName + " to " + curLevel);
20791                            app.thread.scheduleTrimMemory(curLevel);
20792                        } catch (RemoteException e) {
20793                        }
20794                        if (false) {
20795                            // For now we won't do this; our memory trimming seems
20796                            // to be good enough at this point that destroying
20797                            // activities causes more harm than good.
20798                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20799                                    && app != mHomeProcess && app != mPreviousProcess) {
20800                                // Need to do this on its own message because the stack may not
20801                                // be in a consistent state at this point.
20802                                // For these apps we will also finish their activities
20803                                // to help them free memory.
20804                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20805                            }
20806                        }
20807                    }
20808                    app.trimMemoryLevel = curLevel;
20809                    step++;
20810                    if (step >= factor) {
20811                        step = 0;
20812                        switch (curLevel) {
20813                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20814                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20815                                break;
20816                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20817                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20818                                break;
20819                        }
20820                    }
20821                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20822                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20823                            && app.thread != null) {
20824                        try {
20825                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20826                                    "Trimming memory of heavy-weight " + app.processName
20827                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20828                            app.thread.scheduleTrimMemory(
20829                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20830                        } catch (RemoteException e) {
20831                        }
20832                    }
20833                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20834                } else {
20835                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20836                            || app.systemNoUi) && app.pendingUiClean) {
20837                        // If this application is now in the background and it
20838                        // had done UI, then give it the special trim level to
20839                        // have it free UI resources.
20840                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20841                        if (app.trimMemoryLevel < level && app.thread != null) {
20842                            try {
20843                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20844                                        "Trimming memory of bg-ui " + app.processName
20845                                        + " to " + level);
20846                                app.thread.scheduleTrimMemory(level);
20847                            } catch (RemoteException e) {
20848                            }
20849                        }
20850                        app.pendingUiClean = false;
20851                    }
20852                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20853                        try {
20854                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20855                                    "Trimming memory of fg " + app.processName
20856                                    + " to " + fgTrimLevel);
20857                            app.thread.scheduleTrimMemory(fgTrimLevel);
20858                        } catch (RemoteException e) {
20859                        }
20860                    }
20861                    app.trimMemoryLevel = fgTrimLevel;
20862                }
20863            }
20864        } else {
20865            if (mLowRamStartTime != 0) {
20866                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20867                mLowRamStartTime = 0;
20868            }
20869            for (int i=N-1; i>=0; i--) {
20870                ProcessRecord app = mLruProcesses.get(i);
20871                if (allChanged || app.procStateChanged) {
20872                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20873                    app.procStateChanged = false;
20874                }
20875                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20876                        || app.systemNoUi) && app.pendingUiClean) {
20877                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20878                            && app.thread != null) {
20879                        try {
20880                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20881                                    "Trimming memory of ui hidden " + app.processName
20882                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20883                            app.thread.scheduleTrimMemory(
20884                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20885                        } catch (RemoteException e) {
20886                        }
20887                    }
20888                    app.pendingUiClean = false;
20889                }
20890                app.trimMemoryLevel = 0;
20891            }
20892        }
20893
20894        if (mAlwaysFinishActivities) {
20895            // Need to do this on its own message because the stack may not
20896            // be in a consistent state at this point.
20897            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20898        }
20899
20900        if (allChanged) {
20901            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20902        }
20903
20904        // Update from any uid changes.
20905        for (int i=mActiveUids.size()-1; i>=0; i--) {
20906            final UidRecord uidRec = mActiveUids.valueAt(i);
20907            int uidChange = UidRecord.CHANGE_PROCSTATE;
20908            if (uidRec.setProcState != uidRec.curProcState) {
20909                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20910                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20911                        + " to " + uidRec.curProcState);
20912                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20913                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20914                        uidRec.lastBackgroundTime = nowElapsed;
20915                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20916                            // Note: the background settle time is in elapsed realtime, while
20917                            // the handler time base is uptime.  All this means is that we may
20918                            // stop background uids later than we had intended, but that only
20919                            // happens because the device was sleeping so we are okay anyway.
20920                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20921                        }
20922                    }
20923                } else {
20924                    if (uidRec.idle) {
20925                        uidChange = UidRecord.CHANGE_ACTIVE;
20926                        uidRec.idle = false;
20927                    }
20928                    uidRec.lastBackgroundTime = 0;
20929                }
20930                uidRec.setProcState = uidRec.curProcState;
20931                enqueueUidChangeLocked(uidRec, -1, uidChange);
20932                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20933            }
20934        }
20935
20936        if (mProcessStats.shouldWriteNowLocked(now)) {
20937            mHandler.post(new Runnable() {
20938                @Override public void run() {
20939                    synchronized (ActivityManagerService.this) {
20940                        mProcessStats.writeStateAsyncLocked();
20941                    }
20942                }
20943            });
20944        }
20945
20946        if (DEBUG_OOM_ADJ) {
20947            final long duration = SystemClock.uptimeMillis() - now;
20948            if (false) {
20949                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20950                        new RuntimeException("here").fillInStackTrace());
20951            } else {
20952                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20953            }
20954        }
20955    }
20956
20957    final void idleUids() {
20958        synchronized (this) {
20959            final long nowElapsed = SystemClock.elapsedRealtime();
20960            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20961            long nextTime = 0;
20962            for (int i=mActiveUids.size()-1; i>=0; i--) {
20963                final UidRecord uidRec = mActiveUids.valueAt(i);
20964                final long bgTime = uidRec.lastBackgroundTime;
20965                if (bgTime > 0 && !uidRec.idle) {
20966                    if (bgTime <= maxBgTime) {
20967                        uidRec.idle = true;
20968                        doStopUidLocked(uidRec.uid, uidRec);
20969                    } else {
20970                        if (nextTime == 0 || nextTime > bgTime) {
20971                            nextTime = bgTime;
20972                        }
20973                    }
20974                }
20975            }
20976            if (nextTime > 0) {
20977                mHandler.removeMessages(IDLE_UIDS_MSG);
20978                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20979                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20980            }
20981        }
20982    }
20983
20984    final void runInBackgroundDisabled(int uid) {
20985        synchronized (this) {
20986            UidRecord uidRec = mActiveUids.get(uid);
20987            if (uidRec != null) {
20988                // This uid is actually running...  should it be considered background now?
20989                if (uidRec.idle) {
20990                    doStopUidLocked(uidRec.uid, uidRec);
20991                }
20992            } else {
20993                // This uid isn't actually running...  still send a report about it being "stopped".
20994                doStopUidLocked(uid, null);
20995            }
20996        }
20997    }
20998
20999    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21000        mServices.stopInBackgroundLocked(uid);
21001        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21002    }
21003
21004    final void trimApplications() {
21005        synchronized (this) {
21006            int i;
21007
21008            // First remove any unused application processes whose package
21009            // has been removed.
21010            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21011                final ProcessRecord app = mRemovedProcesses.get(i);
21012                if (app.activities.size() == 0
21013                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21014                    Slog.i(
21015                        TAG, "Exiting empty application process "
21016                        + app.toShortString() + " ("
21017                        + (app.thread != null ? app.thread.asBinder() : null)
21018                        + ")\n");
21019                    if (app.pid > 0 && app.pid != MY_PID) {
21020                        app.kill("empty", false);
21021                    } else {
21022                        try {
21023                            app.thread.scheduleExit();
21024                        } catch (Exception e) {
21025                            // Ignore exceptions.
21026                        }
21027                    }
21028                    cleanUpApplicationRecordLocked(app, false, true, -1);
21029                    mRemovedProcesses.remove(i);
21030
21031                    if (app.persistent) {
21032                        addAppLocked(app.info, false, null /* ABI override */);
21033                    }
21034                }
21035            }
21036
21037            // Now update the oom adj for all processes.
21038            updateOomAdjLocked();
21039        }
21040    }
21041
21042    /** This method sends the specified signal to each of the persistent apps */
21043    public void signalPersistentProcesses(int sig) throws RemoteException {
21044        if (sig != Process.SIGNAL_USR1) {
21045            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21046        }
21047
21048        synchronized (this) {
21049            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21050                    != PackageManager.PERMISSION_GRANTED) {
21051                throw new SecurityException("Requires permission "
21052                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21053            }
21054
21055            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21056                ProcessRecord r = mLruProcesses.get(i);
21057                if (r.thread != null && r.persistent) {
21058                    Process.sendSignal(r.pid, sig);
21059                }
21060            }
21061        }
21062    }
21063
21064    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21065        if (proc == null || proc == mProfileProc) {
21066            proc = mProfileProc;
21067            profileType = mProfileType;
21068            clearProfilerLocked();
21069        }
21070        if (proc == null) {
21071            return;
21072        }
21073        try {
21074            proc.thread.profilerControl(false, null, profileType);
21075        } catch (RemoteException e) {
21076            throw new IllegalStateException("Process disappeared");
21077        }
21078    }
21079
21080    private void clearProfilerLocked() {
21081        if (mProfileFd != null) {
21082            try {
21083                mProfileFd.close();
21084            } catch (IOException e) {
21085            }
21086        }
21087        mProfileApp = null;
21088        mProfileProc = null;
21089        mProfileFile = null;
21090        mProfileType = 0;
21091        mAutoStopProfiler = false;
21092        mSamplingInterval = 0;
21093    }
21094
21095    public boolean profileControl(String process, int userId, boolean start,
21096            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21097
21098        try {
21099            synchronized (this) {
21100                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21101                // its own permission.
21102                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21103                        != PackageManager.PERMISSION_GRANTED) {
21104                    throw new SecurityException("Requires permission "
21105                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21106                }
21107
21108                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21109                    throw new IllegalArgumentException("null profile info or fd");
21110                }
21111
21112                ProcessRecord proc = null;
21113                if (process != null) {
21114                    proc = findProcessLocked(process, userId, "profileControl");
21115                }
21116
21117                if (start && (proc == null || proc.thread == null)) {
21118                    throw new IllegalArgumentException("Unknown process: " + process);
21119                }
21120
21121                if (start) {
21122                    stopProfilerLocked(null, 0);
21123                    setProfileApp(proc.info, proc.processName, profilerInfo);
21124                    mProfileProc = proc;
21125                    mProfileType = profileType;
21126                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21127                    try {
21128                        fd = fd.dup();
21129                    } catch (IOException e) {
21130                        fd = null;
21131                    }
21132                    profilerInfo.profileFd = fd;
21133                    proc.thread.profilerControl(start, profilerInfo, profileType);
21134                    fd = null;
21135                    mProfileFd = null;
21136                } else {
21137                    stopProfilerLocked(proc, profileType);
21138                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21139                        try {
21140                            profilerInfo.profileFd.close();
21141                        } catch (IOException e) {
21142                        }
21143                    }
21144                }
21145
21146                return true;
21147            }
21148        } catch (RemoteException e) {
21149            throw new IllegalStateException("Process disappeared");
21150        } finally {
21151            if (profilerInfo != null && profilerInfo.profileFd != null) {
21152                try {
21153                    profilerInfo.profileFd.close();
21154                } catch (IOException e) {
21155                }
21156            }
21157        }
21158    }
21159
21160    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21161        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21162                userId, true, ALLOW_FULL_ONLY, callName, null);
21163        ProcessRecord proc = null;
21164        try {
21165            int pid = Integer.parseInt(process);
21166            synchronized (mPidsSelfLocked) {
21167                proc = mPidsSelfLocked.get(pid);
21168            }
21169        } catch (NumberFormatException e) {
21170        }
21171
21172        if (proc == null) {
21173            ArrayMap<String, SparseArray<ProcessRecord>> all
21174                    = mProcessNames.getMap();
21175            SparseArray<ProcessRecord> procs = all.get(process);
21176            if (procs != null && procs.size() > 0) {
21177                proc = procs.valueAt(0);
21178                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21179                    for (int i=1; i<procs.size(); i++) {
21180                        ProcessRecord thisProc = procs.valueAt(i);
21181                        if (thisProc.userId == userId) {
21182                            proc = thisProc;
21183                            break;
21184                        }
21185                    }
21186                }
21187            }
21188        }
21189
21190        return proc;
21191    }
21192
21193    public boolean dumpHeap(String process, int userId, boolean managed,
21194            String path, ParcelFileDescriptor fd) throws RemoteException {
21195
21196        try {
21197            synchronized (this) {
21198                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21199                // its own permission (same as profileControl).
21200                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21201                        != PackageManager.PERMISSION_GRANTED) {
21202                    throw new SecurityException("Requires permission "
21203                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21204                }
21205
21206                if (fd == null) {
21207                    throw new IllegalArgumentException("null fd");
21208                }
21209
21210                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21211                if (proc == null || proc.thread == null) {
21212                    throw new IllegalArgumentException("Unknown process: " + process);
21213                }
21214
21215                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21216                if (!isDebuggable) {
21217                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21218                        throw new SecurityException("Process not debuggable: " + proc);
21219                    }
21220                }
21221
21222                proc.thread.dumpHeap(managed, path, fd);
21223                fd = null;
21224                return true;
21225            }
21226        } catch (RemoteException e) {
21227            throw new IllegalStateException("Process disappeared");
21228        } finally {
21229            if (fd != null) {
21230                try {
21231                    fd.close();
21232                } catch (IOException e) {
21233                }
21234            }
21235        }
21236    }
21237
21238    @Override
21239    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21240            String reportPackage) {
21241        if (processName != null) {
21242            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21243                    "setDumpHeapDebugLimit()");
21244        } else {
21245            synchronized (mPidsSelfLocked) {
21246                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21247                if (proc == null) {
21248                    throw new SecurityException("No process found for calling pid "
21249                            + Binder.getCallingPid());
21250                }
21251                if (!Build.IS_DEBUGGABLE
21252                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21253                    throw new SecurityException("Not running a debuggable build");
21254                }
21255                processName = proc.processName;
21256                uid = proc.uid;
21257                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21258                    throw new SecurityException("Package " + reportPackage + " is not running in "
21259                            + proc);
21260                }
21261            }
21262        }
21263        synchronized (this) {
21264            if (maxMemSize > 0) {
21265                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21266            } else {
21267                if (uid != 0) {
21268                    mMemWatchProcesses.remove(processName, uid);
21269                } else {
21270                    mMemWatchProcesses.getMap().remove(processName);
21271                }
21272            }
21273        }
21274    }
21275
21276    @Override
21277    public void dumpHeapFinished(String path) {
21278        synchronized (this) {
21279            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21280                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21281                        + " does not match last pid " + mMemWatchDumpPid);
21282                return;
21283            }
21284            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21285                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21286                        + " does not match last path " + mMemWatchDumpFile);
21287                return;
21288            }
21289            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21290            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21291        }
21292    }
21293
21294    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21295    public void monitor() {
21296        synchronized (this) { }
21297    }
21298
21299    void onCoreSettingsChange(Bundle settings) {
21300        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21301            ProcessRecord processRecord = mLruProcesses.get(i);
21302            try {
21303                if (processRecord.thread != null) {
21304                    processRecord.thread.setCoreSettings(settings);
21305                }
21306            } catch (RemoteException re) {
21307                /* ignore */
21308            }
21309        }
21310    }
21311
21312    // Multi-user methods
21313
21314    /**
21315     * Start user, if its not already running, but don't bring it to foreground.
21316     */
21317    @Override
21318    public boolean startUserInBackground(final int userId) {
21319        return mUserController.startUser(userId, /* foreground */ false);
21320    }
21321
21322    @Override
21323    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21324        return mUserController.unlockUser(userId, token, secret, listener);
21325    }
21326
21327    @Override
21328    public boolean switchUser(final int targetUserId) {
21329        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21330        UserInfo currentUserInfo;
21331        UserInfo targetUserInfo;
21332        synchronized (this) {
21333            int currentUserId = mUserController.getCurrentUserIdLocked();
21334            currentUserInfo = mUserController.getUserInfo(currentUserId);
21335            targetUserInfo = mUserController.getUserInfo(targetUserId);
21336            if (targetUserInfo == null) {
21337                Slog.w(TAG, "No user info for user #" + targetUserId);
21338                return false;
21339            }
21340            if (!targetUserInfo.supportsSwitchTo()) {
21341                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21342                return false;
21343            }
21344            if (targetUserInfo.isManagedProfile()) {
21345                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21346                return false;
21347            }
21348            mUserController.setTargetUserIdLocked(targetUserId);
21349        }
21350        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21351        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21352        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21353        return true;
21354    }
21355
21356    void scheduleStartProfilesLocked() {
21357        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21358            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21359                    DateUtils.SECOND_IN_MILLIS);
21360        }
21361    }
21362
21363    @Override
21364    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21365        return mUserController.stopUser(userId, force, callback);
21366    }
21367
21368    @Override
21369    public UserInfo getCurrentUser() {
21370        return mUserController.getCurrentUser();
21371    }
21372
21373    @Override
21374    public boolean isUserRunning(int userId, int flags) {
21375        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21376                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21377            String msg = "Permission Denial: isUserRunning() from pid="
21378                    + Binder.getCallingPid()
21379                    + ", uid=" + Binder.getCallingUid()
21380                    + " requires " + INTERACT_ACROSS_USERS;
21381            Slog.w(TAG, msg);
21382            throw new SecurityException(msg);
21383        }
21384        synchronized (this) {
21385            return mUserController.isUserRunningLocked(userId, flags);
21386        }
21387    }
21388
21389    @Override
21390    public int[] getRunningUserIds() {
21391        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21392                != PackageManager.PERMISSION_GRANTED) {
21393            String msg = "Permission Denial: isUserRunning() from pid="
21394                    + Binder.getCallingPid()
21395                    + ", uid=" + Binder.getCallingUid()
21396                    + " requires " + INTERACT_ACROSS_USERS;
21397            Slog.w(TAG, msg);
21398            throw new SecurityException(msg);
21399        }
21400        synchronized (this) {
21401            return mUserController.getStartedUserArrayLocked();
21402        }
21403    }
21404
21405    @Override
21406    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21407        mUserController.registerUserSwitchObserver(observer);
21408    }
21409
21410    @Override
21411    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21412        mUserController.unregisterUserSwitchObserver(observer);
21413    }
21414
21415    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21416        if (info == null) return null;
21417        ApplicationInfo newInfo = new ApplicationInfo(info);
21418        newInfo.initForUser(userId);
21419        return newInfo;
21420    }
21421
21422    public boolean isUserStopped(int userId) {
21423        synchronized (this) {
21424            return mUserController.getStartedUserStateLocked(userId) == null;
21425        }
21426    }
21427
21428    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21429        if (aInfo == null
21430                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21431            return aInfo;
21432        }
21433
21434        ActivityInfo info = new ActivityInfo(aInfo);
21435        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21436        return info;
21437    }
21438
21439    private boolean processSanityChecksLocked(ProcessRecord process) {
21440        if (process == null || process.thread == null) {
21441            return false;
21442        }
21443
21444        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21445        if (!isDebuggable) {
21446            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21447                return false;
21448            }
21449        }
21450
21451        return true;
21452    }
21453
21454    public boolean startBinderTracking() throws RemoteException {
21455        synchronized (this) {
21456            mBinderTransactionTrackingEnabled = true;
21457            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21458            // permission (same as profileControl).
21459            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21460                    != PackageManager.PERMISSION_GRANTED) {
21461                throw new SecurityException("Requires permission "
21462                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21463            }
21464
21465            for (int i = 0; i < mLruProcesses.size(); i++) {
21466                ProcessRecord process = mLruProcesses.get(i);
21467                if (!processSanityChecksLocked(process)) {
21468                    continue;
21469                }
21470                try {
21471                    process.thread.startBinderTracking();
21472                } catch (RemoteException e) {
21473                    Log.v(TAG, "Process disappared");
21474                }
21475            }
21476            return true;
21477        }
21478    }
21479
21480    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21481        try {
21482            synchronized (this) {
21483                mBinderTransactionTrackingEnabled = false;
21484                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21485                // permission (same as profileControl).
21486                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21487                        != PackageManager.PERMISSION_GRANTED) {
21488                    throw new SecurityException("Requires permission "
21489                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21490                }
21491
21492                if (fd == null) {
21493                    throw new IllegalArgumentException("null fd");
21494                }
21495
21496                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21497                pw.println("Binder transaction traces for all processes.\n");
21498                for (ProcessRecord process : mLruProcesses) {
21499                    if (!processSanityChecksLocked(process)) {
21500                        continue;
21501                    }
21502
21503                    pw.println("Traces for process: " + process.processName);
21504                    pw.flush();
21505                    try {
21506                        TransferPipe tp = new TransferPipe();
21507                        try {
21508                            process.thread.stopBinderTrackingAndDump(
21509                                    tp.getWriteFd().getFileDescriptor());
21510                            tp.go(fd.getFileDescriptor());
21511                        } finally {
21512                            tp.kill();
21513                        }
21514                    } catch (IOException e) {
21515                        pw.println("Failure while dumping IPC traces from " + process +
21516                                ".  Exception: " + e);
21517                        pw.flush();
21518                    } catch (RemoteException e) {
21519                        pw.println("Got a RemoteException while dumping IPC traces from " +
21520                                process + ".  Exception: " + e);
21521                        pw.flush();
21522                    }
21523                }
21524                fd = null;
21525                return true;
21526            }
21527        } finally {
21528            if (fd != null) {
21529                try {
21530                    fd.close();
21531                } catch (IOException e) {
21532                }
21533            }
21534        }
21535    }
21536
21537    private final class LocalService extends ActivityManagerInternal {
21538        @Override
21539        public void onWakefulnessChanged(int wakefulness) {
21540            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21541        }
21542
21543        @Override
21544        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21545                String processName, String abiOverride, int uid, Runnable crashHandler) {
21546            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21547                    processName, abiOverride, uid, crashHandler);
21548        }
21549
21550        @Override
21551        public SleepToken acquireSleepToken(String tag) {
21552            Preconditions.checkNotNull(tag);
21553
21554            ComponentName requestedVrService = null;
21555            ComponentName callingVrActivity = null;
21556            int userId = -1;
21557            synchronized (ActivityManagerService.this) {
21558                if (mFocusedActivity != null) {
21559                    requestedVrService = mFocusedActivity.requestedVrComponent;
21560                    callingVrActivity = mFocusedActivity.info.getComponentName();
21561                    userId = mFocusedActivity.userId;
21562                }
21563            }
21564
21565            if (requestedVrService != null) {
21566                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21567            }
21568
21569            synchronized (ActivityManagerService.this) {
21570                SleepTokenImpl token = new SleepTokenImpl(tag);
21571                mSleepTokens.add(token);
21572                updateSleepIfNeededLocked();
21573                return token;
21574            }
21575        }
21576
21577        @Override
21578        public ComponentName getHomeActivityForUser(int userId) {
21579            synchronized (ActivityManagerService.this) {
21580                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21581                return homeActivity == null ? null : homeActivity.realActivity;
21582            }
21583        }
21584
21585        @Override
21586        public void onUserRemoved(int userId) {
21587            synchronized (ActivityManagerService.this) {
21588                ActivityManagerService.this.onUserStoppedLocked(userId);
21589            }
21590        }
21591
21592        @Override
21593        public void onLocalVoiceInteractionStarted(IBinder activity,
21594                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21595            synchronized (ActivityManagerService.this) {
21596                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21597                        voiceSession, voiceInteractor);
21598            }
21599        }
21600
21601        @Override
21602        public void notifyStartingWindowDrawn() {
21603            synchronized (ActivityManagerService.this) {
21604                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21605            }
21606        }
21607
21608        @Override
21609        public void notifyAppTransitionStarting(int reason) {
21610            synchronized (ActivityManagerService.this) {
21611                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21612            }
21613        }
21614
21615        @Override
21616        public void notifyAppTransitionFinished() {
21617            synchronized (ActivityManagerService.this) {
21618                mStackSupervisor.notifyAppTransitionDone();
21619            }
21620        }
21621
21622        @Override
21623        public void notifyAppTransitionCancelled() {
21624            synchronized (ActivityManagerService.this) {
21625                mStackSupervisor.notifyAppTransitionDone();
21626            }
21627        }
21628
21629        @Override
21630        public List<IBinder> getTopVisibleActivities() {
21631            synchronized (ActivityManagerService.this) {
21632                return mStackSupervisor.getTopVisibleActivities();
21633            }
21634        }
21635
21636        @Override
21637        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21638            synchronized (ActivityManagerService.this) {
21639                mStackSupervisor.setDockedStackMinimized(minimized);
21640            }
21641        }
21642
21643        @Override
21644        public void killForegroundAppsForUser(int userHandle) {
21645            synchronized (ActivityManagerService.this) {
21646                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21647                final int NP = mProcessNames.getMap().size();
21648                for (int ip = 0; ip < NP; ip++) {
21649                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21650                    final int NA = apps.size();
21651                    for (int ia = 0; ia < NA; ia++) {
21652                        final ProcessRecord app = apps.valueAt(ia);
21653                        if (app.persistent) {
21654                            // We don't kill persistent processes.
21655                            continue;
21656                        }
21657                        if (app.removed) {
21658                            procs.add(app);
21659                        } else if (app.userId == userHandle && app.foregroundActivities) {
21660                            app.removed = true;
21661                            procs.add(app);
21662                        }
21663                    }
21664                }
21665
21666                final int N = procs.size();
21667                for (int i = 0; i < N; i++) {
21668                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21669                }
21670            }
21671        }
21672
21673        @Override
21674        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21675            if (!(target instanceof PendingIntentRecord)) {
21676                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21677                return;
21678            }
21679            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21680        }
21681    }
21682
21683    private final class SleepTokenImpl extends SleepToken {
21684        private final String mTag;
21685        private final long mAcquireTime;
21686
21687        public SleepTokenImpl(String tag) {
21688            mTag = tag;
21689            mAcquireTime = SystemClock.uptimeMillis();
21690        }
21691
21692        @Override
21693        public void release() {
21694            synchronized (ActivityManagerService.this) {
21695                if (mSleepTokens.remove(this)) {
21696                    updateSleepIfNeededLocked();
21697                }
21698            }
21699        }
21700
21701        @Override
21702        public String toString() {
21703            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21704        }
21705    }
21706
21707    /**
21708     * An implementation of IAppTask, that allows an app to manage its own tasks via
21709     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21710     * only the process that calls getAppTasks() can call the AppTask methods.
21711     */
21712    class AppTaskImpl extends IAppTask.Stub {
21713        private int mTaskId;
21714        private int mCallingUid;
21715
21716        public AppTaskImpl(int taskId, int callingUid) {
21717            mTaskId = taskId;
21718            mCallingUid = callingUid;
21719        }
21720
21721        private void checkCaller() {
21722            if (mCallingUid != Binder.getCallingUid()) {
21723                throw new SecurityException("Caller " + mCallingUid
21724                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21725            }
21726        }
21727
21728        @Override
21729        public void finishAndRemoveTask() {
21730            checkCaller();
21731
21732            synchronized (ActivityManagerService.this) {
21733                long origId = Binder.clearCallingIdentity();
21734                try {
21735                    // We remove the task from recents to preserve backwards
21736                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21737                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21738                    }
21739                } finally {
21740                    Binder.restoreCallingIdentity(origId);
21741                }
21742            }
21743        }
21744
21745        @Override
21746        public ActivityManager.RecentTaskInfo getTaskInfo() {
21747            checkCaller();
21748
21749            synchronized (ActivityManagerService.this) {
21750                long origId = Binder.clearCallingIdentity();
21751                try {
21752                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21753                    if (tr == null) {
21754                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21755                    }
21756                    return createRecentTaskInfoFromTaskRecord(tr);
21757                } finally {
21758                    Binder.restoreCallingIdentity(origId);
21759                }
21760            }
21761        }
21762
21763        @Override
21764        public void moveToFront() {
21765            checkCaller();
21766            // Will bring task to front if it already has a root activity.
21767            final long origId = Binder.clearCallingIdentity();
21768            try {
21769                synchronized (this) {
21770                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21771                }
21772            } finally {
21773                Binder.restoreCallingIdentity(origId);
21774            }
21775        }
21776
21777        @Override
21778        public int startActivity(IBinder whoThread, String callingPackage,
21779                Intent intent, String resolvedType, Bundle bOptions) {
21780            checkCaller();
21781
21782            int callingUser = UserHandle.getCallingUserId();
21783            TaskRecord tr;
21784            IApplicationThread appThread;
21785            synchronized (ActivityManagerService.this) {
21786                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21787                if (tr == null) {
21788                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21789                }
21790                appThread = ApplicationThreadNative.asInterface(whoThread);
21791                if (appThread == null) {
21792                    throw new IllegalArgumentException("Bad app thread " + appThread);
21793                }
21794            }
21795            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21796                    resolvedType, null, null, null, null, 0, 0, null, null,
21797                    null, bOptions, false, callingUser, null, tr);
21798        }
21799
21800        @Override
21801        public void setExcludeFromRecents(boolean exclude) {
21802            checkCaller();
21803
21804            synchronized (ActivityManagerService.this) {
21805                long origId = Binder.clearCallingIdentity();
21806                try {
21807                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21808                    if (tr == null) {
21809                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21810                    }
21811                    Intent intent = tr.getBaseIntent();
21812                    if (exclude) {
21813                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21814                    } else {
21815                        intent.setFlags(intent.getFlags()
21816                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21817                    }
21818                } finally {
21819                    Binder.restoreCallingIdentity(origId);
21820                }
21821            }
21822        }
21823    }
21824
21825    /**
21826     * Kill processes for the user with id userId and that depend on the package named packageName
21827     */
21828    @Override
21829    public void killPackageDependents(String packageName, int userId) {
21830        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21831        if (packageName == null) {
21832            throw new NullPointerException(
21833                    "Cannot kill the dependents of a package without its name.");
21834        }
21835
21836        long callingId = Binder.clearCallingIdentity();
21837        IPackageManager pm = AppGlobals.getPackageManager();
21838        int pkgUid = -1;
21839        try {
21840            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21841        } catch (RemoteException e) {
21842        }
21843        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21844            throw new IllegalArgumentException(
21845                    "Cannot kill dependents of non-existing package " + packageName);
21846        }
21847        try {
21848            synchronized(this) {
21849                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21850                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21851                        "dep: " + packageName);
21852            }
21853        } finally {
21854            Binder.restoreCallingIdentity(callingId);
21855        }
21856    }
21857
21858    /**
21859     * Attach an agent to the specified process (proces name or PID)
21860     */
21861    public void attachAgent(String process, String path) {
21862        try {
21863            synchronized (this) {
21864                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
21865                if (proc == null || proc.thread == null) {
21866                    throw new IllegalArgumentException("Unknown process: " + process);
21867                }
21868
21869                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21870                if (!isDebuggable) {
21871                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21872                        throw new SecurityException("Process not debuggable: " + proc);
21873                    }
21874                }
21875
21876                proc.thread.attachAgent(path);
21877            }
21878        } catch (RemoteException e) {
21879            throw new IllegalStateException("Process disappeared");
21880        }
21881    }
21882}
21883