ActivityManagerService.java revision 034ec49b19058284c7e123cfe8d239761a75b632
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.NonNull;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.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    // Whether we should use SCHED_FIFO for UI and RenderThreads.
572    private boolean mUseFifoUiScheduling = false;
573
574    BroadcastQueue mFgBroadcastQueue;
575    BroadcastQueue mBgBroadcastQueue;
576    // Convenient for easy iteration over the queues. Foreground is first
577    // so that dispatch of foreground broadcasts gets precedence.
578    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
579
580    BroadcastStats mLastBroadcastStats;
581    BroadcastStats mCurBroadcastStats;
582
583    BroadcastQueue broadcastQueueForIntent(Intent intent) {
584        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
585        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
586                "Broadcast intent " + intent + " on "
587                + (isFg ? "foreground" : "background") + " queue");
588        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
589    }
590
591    /**
592     * Activity we have told the window manager to have key focus.
593     */
594    ActivityRecord mFocusedActivity = null;
595
596    /**
597     * User id of the last activity mFocusedActivity was set to.
598     */
599    private int mLastFocusedUserId;
600
601    /**
602     * If non-null, we are tracking the time the user spends in the currently focused app.
603     */
604    private AppTimeTracker mCurAppTimeTracker;
605
606    /**
607     * List of intents that were used to start the most recent tasks.
608     */
609    final RecentTasks mRecentTasks;
610
611    /**
612     * For addAppTask: cached of the last activity component that was added.
613     */
614    ComponentName mLastAddedTaskComponent;
615
616    /**
617     * For addAppTask: cached of the last activity uid that was added.
618     */
619    int mLastAddedTaskUid;
620
621    /**
622     * For addAppTask: cached of the last ActivityInfo that was added.
623     */
624    ActivityInfo mLastAddedTaskActivity;
625
626    /**
627     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
628     */
629    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
630
631    /**
632     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
633     */
634    String mDeviceOwnerName;
635
636    final UserController mUserController;
637
638    final AppErrors mAppErrors;
639
640    boolean mDoingSetFocusedActivity;
641
642    public boolean canShowErrorDialogs() {
643        return mShowDialogs && !mSleeping && !mShuttingDown;
644    }
645
646    private static final class PriorityState {
647        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
648        // the current thread is currently in. When it drops down to zero, we will no longer boost
649        // the thread's priority.
650        private int regionCounter = 0;
651
652        // The thread's previous priority before boosting.
653        private int prevPriority = Integer.MIN_VALUE;
654    }
655
656    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
657        @Override protected PriorityState initialValue() {
658            return new PriorityState();
659        }
660    };
661
662    static void boostPriorityForLockedSection() {
663        int tid = Process.myTid();
664        int prevPriority = Process.getThreadPriority(tid);
665        PriorityState state = sThreadPriorityState.get();
666        if (state.regionCounter == 0 && prevPriority > -2) {
667            state.prevPriority = prevPriority;
668            Process.setThreadPriority(tid, -2);
669        }
670        state.regionCounter++;
671    }
672
673    static void resetPriorityAfterLockedSection() {
674        PriorityState state = sThreadPriorityState.get();
675        state.regionCounter--;
676        if (state.regionCounter == 0 && state.prevPriority > -2) {
677            Process.setThreadPriority(Process.myTid(), state.prevPriority);
678        }
679    }
680
681    public class PendingAssistExtras extends Binder implements Runnable {
682        public final ActivityRecord activity;
683        public final Bundle extras;
684        public final Intent intent;
685        public final String hint;
686        public final IResultReceiver receiver;
687        public final int userHandle;
688        public boolean haveResult = false;
689        public Bundle result = null;
690        public AssistStructure structure = null;
691        public AssistContent content = null;
692        public Bundle receiverExtras;
693
694        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
695                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
696            activity = _activity;
697            extras = _extras;
698            intent = _intent;
699            hint = _hint;
700            receiver = _receiver;
701            receiverExtras = _receiverExtras;
702            userHandle = _userHandle;
703        }
704        @Override
705        public void run() {
706            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
707            synchronized (this) {
708                haveResult = true;
709                notifyAll();
710            }
711            pendingAssistExtrasTimedOut(this);
712        }
713    }
714
715    final ArrayList<PendingAssistExtras> mPendingAssistExtras
716            = new ArrayList<PendingAssistExtras>();
717
718    /**
719     * Process management.
720     */
721    final ProcessList mProcessList = new ProcessList();
722
723    /**
724     * All of the applications we currently have running organized by name.
725     * The keys are strings of the application package name (as
726     * returned by the package manager), and the keys are ApplicationRecord
727     * objects.
728     */
729    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
730
731    /**
732     * Tracking long-term execution of processes to look for abuse and other
733     * bad app behavior.
734     */
735    final ProcessStatsService mProcessStats;
736
737    /**
738     * The currently running isolated processes.
739     */
740    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
741
742    /**
743     * Counter for assigning isolated process uids, to avoid frequently reusing the
744     * same ones.
745     */
746    int mNextIsolatedProcessUid = 0;
747
748    /**
749     * The currently running heavy-weight process, if any.
750     */
751    ProcessRecord mHeavyWeightProcess = null;
752
753    /**
754     * All of the processes we currently have running organized by pid.
755     * The keys are the pid running the application.
756     *
757     * <p>NOTE: This object is protected by its own lock, NOT the global
758     * activity manager lock!
759     */
760    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
761
762    /**
763     * All of the processes that have been forced to be foreground.  The key
764     * is the pid of the caller who requested it (we hold a death
765     * link on it).
766     */
767    abstract class ForegroundToken implements IBinder.DeathRecipient {
768        int pid;
769        IBinder token;
770    }
771    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
772
773    /**
774     * List of records for processes that someone had tried to start before the
775     * system was ready.  We don't start them at that point, but ensure they
776     * are started by the time booting is complete.
777     */
778    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
779
780    /**
781     * List of persistent applications that are in the process
782     * of being started.
783     */
784    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
785
786    /**
787     * Processes that are being forcibly torn down.
788     */
789    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
790
791    /**
792     * List of running applications, sorted by recent usage.
793     * The first entry in the list is the least recently used.
794     */
795    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
796
797    /**
798     * Where in mLruProcesses that the processes hosting activities start.
799     */
800    int mLruProcessActivityStart = 0;
801
802    /**
803     * Where in mLruProcesses that the processes hosting services start.
804     * This is after (lower index) than mLruProcessesActivityStart.
805     */
806    int mLruProcessServiceStart = 0;
807
808    /**
809     * List of processes that should gc as soon as things are idle.
810     */
811    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
812
813    /**
814     * Processes we want to collect PSS data from.
815     */
816    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
817
818    private boolean mBinderTransactionTrackingEnabled = false;
819
820    /**
821     * Last time we requested PSS data of all processes.
822     */
823    long mLastFullPssTime = SystemClock.uptimeMillis();
824
825    /**
826     * If set, the next time we collect PSS data we should do a full collection
827     * with data from native processes and the kernel.
828     */
829    boolean mFullPssPending = false;
830
831    /**
832     * This is the process holding what we currently consider to be
833     * the "home" activity.
834     */
835    ProcessRecord mHomeProcess;
836
837    /**
838     * This is the process holding the activity the user last visited that
839     * is in a different process from the one they are currently in.
840     */
841    ProcessRecord mPreviousProcess;
842
843    /**
844     * The time at which the previous process was last visible.
845     */
846    long mPreviousProcessVisibleTime;
847
848    /**
849     * Track all uids that have actively running processes.
850     */
851    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
852
853    /**
854     * This is for verifying the UID report flow.
855     */
856    static final boolean VALIDATE_UID_STATES = true;
857    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
858
859    /**
860     * Packages that the user has asked to have run in screen size
861     * compatibility mode instead of filling the screen.
862     */
863    final CompatModePackages mCompatModePackages;
864
865    /**
866     * Set of IntentSenderRecord objects that are currently active.
867     */
868    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
869            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
870
871    /**
872     * Fingerprints (hashCode()) of stack traces that we've
873     * already logged DropBox entries for.  Guarded by itself.  If
874     * something (rogue user app) forces this over
875     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
876     */
877    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
878    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
879
880    /**
881     * Strict Mode background batched logging state.
882     *
883     * The string buffer is guarded by itself, and its lock is also
884     * used to determine if another batched write is already
885     * in-flight.
886     */
887    private final StringBuilder mStrictModeBuffer = new StringBuilder();
888
889    /**
890     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
891     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
892     */
893    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
894
895    /**
896     * Resolver for broadcast intents to registered receivers.
897     * Holds BroadcastFilter (subclass of IntentFilter).
898     */
899    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
900            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
901        @Override
902        protected boolean allowFilterResult(
903                BroadcastFilter filter, List<BroadcastFilter> dest) {
904            IBinder target = filter.receiverList.receiver.asBinder();
905            for (int i = dest.size() - 1; i >= 0; i--) {
906                if (dest.get(i).receiverList.receiver.asBinder() == target) {
907                    return false;
908                }
909            }
910            return true;
911        }
912
913        @Override
914        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
915            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
916                    || userId == filter.owningUserId) {
917                return super.newResult(filter, match, userId);
918            }
919            return null;
920        }
921
922        @Override
923        protected BroadcastFilter[] newArray(int size) {
924            return new BroadcastFilter[size];
925        }
926
927        @Override
928        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
929            return packageName.equals(filter.packageName);
930        }
931    };
932
933    /**
934     * State of all active sticky broadcasts per user.  Keys are the action of the
935     * sticky Intent, values are an ArrayList of all broadcasted intents with
936     * that action (which should usually be one).  The SparseArray is keyed
937     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
938     * for stickies that are sent to all users.
939     */
940    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
941            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
942
943    final ActiveServices mServices;
944
945    final static class Association {
946        final int mSourceUid;
947        final String mSourceProcess;
948        final int mTargetUid;
949        final ComponentName mTargetComponent;
950        final String mTargetProcess;
951
952        int mCount;
953        long mTime;
954
955        int mNesting;
956        long mStartTime;
957
958        // states of the source process when the bind occurred.
959        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
960        long mLastStateUptime;
961        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
962                - ActivityManager.MIN_PROCESS_STATE+1];
963
964        Association(int sourceUid, String sourceProcess, int targetUid,
965                ComponentName targetComponent, String targetProcess) {
966            mSourceUid = sourceUid;
967            mSourceProcess = sourceProcess;
968            mTargetUid = targetUid;
969            mTargetComponent = targetComponent;
970            mTargetProcess = targetProcess;
971        }
972    }
973
974    /**
975     * When service association tracking is enabled, this is all of the associations we
976     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
977     * -> association data.
978     */
979    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
980            mAssociations = new SparseArray<>();
981    boolean mTrackingAssociations;
982
983    /**
984     * Backup/restore process management
985     */
986    String mBackupAppName = null;
987    BackupRecord mBackupTarget = null;
988
989    final ProviderMap mProviderMap;
990
991    /**
992     * List of content providers who have clients waiting for them.  The
993     * application is currently being launched and the provider will be
994     * removed from this list once it is published.
995     */
996    final ArrayList<ContentProviderRecord> mLaunchingProviders
997            = new ArrayList<ContentProviderRecord>();
998
999    /**
1000     * File storing persisted {@link #mGrantedUriPermissions}.
1001     */
1002    private final AtomicFile mGrantFile;
1003
1004    /** XML constants used in {@link #mGrantFile} */
1005    private static final String TAG_URI_GRANTS = "uri-grants";
1006    private static final String TAG_URI_GRANT = "uri-grant";
1007    private static final String ATTR_USER_HANDLE = "userHandle";
1008    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1009    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1010    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1011    private static final String ATTR_TARGET_PKG = "targetPkg";
1012    private static final String ATTR_URI = "uri";
1013    private static final String ATTR_MODE_FLAGS = "modeFlags";
1014    private static final String ATTR_CREATED_TIME = "createdTime";
1015    private static final String ATTR_PREFIX = "prefix";
1016
1017    /**
1018     * Global set of specific {@link Uri} permissions that have been granted.
1019     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1020     * to {@link UriPermission#uri} to {@link UriPermission}.
1021     */
1022    @GuardedBy("this")
1023    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1024            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1025
1026    public static class GrantUri {
1027        public final int sourceUserId;
1028        public final Uri uri;
1029        public boolean prefix;
1030
1031        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1032            this.sourceUserId = sourceUserId;
1033            this.uri = uri;
1034            this.prefix = prefix;
1035        }
1036
1037        @Override
1038        public int hashCode() {
1039            int hashCode = 1;
1040            hashCode = 31 * hashCode + sourceUserId;
1041            hashCode = 31 * hashCode + uri.hashCode();
1042            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1043            return hashCode;
1044        }
1045
1046        @Override
1047        public boolean equals(Object o) {
1048            if (o instanceof GrantUri) {
1049                GrantUri other = (GrantUri) o;
1050                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1051                        && prefix == other.prefix;
1052            }
1053            return false;
1054        }
1055
1056        @Override
1057        public String toString() {
1058            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1059            if (prefix) result += " [prefix]";
1060            return result;
1061        }
1062
1063        public String toSafeString() {
1064            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1065            if (prefix) result += " [prefix]";
1066            return result;
1067        }
1068
1069        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1070            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1071                    ContentProvider.getUriWithoutUserId(uri), false);
1072        }
1073    }
1074
1075    CoreSettingsObserver mCoreSettingsObserver;
1076
1077    FontScaleSettingObserver mFontScaleSettingObserver;
1078
1079    private final class FontScaleSettingObserver extends ContentObserver {
1080        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1081
1082        public FontScaleSettingObserver() {
1083            super(mHandler);
1084            ContentResolver resolver = mContext.getContentResolver();
1085            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1086        }
1087
1088        @Override
1089        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1090            if (mFontScaleUri.equals(uri)) {
1091                updateFontScaleIfNeeded(userId);
1092            }
1093        }
1094    }
1095
1096    /**
1097     * Thread-local storage used to carry caller permissions over through
1098     * indirect content-provider access.
1099     */
1100    private class Identity {
1101        public final IBinder token;
1102        public final int pid;
1103        public final int uid;
1104
1105        Identity(IBinder _token, int _pid, int _uid) {
1106            token = _token;
1107            pid = _pid;
1108            uid = _uid;
1109        }
1110    }
1111
1112    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1113
1114    /**
1115     * All information we have collected about the runtime performance of
1116     * any user id that can impact battery performance.
1117     */
1118    final BatteryStatsService mBatteryStatsService;
1119
1120    /**
1121     * Information about component usage
1122     */
1123    UsageStatsManagerInternal mUsageStatsService;
1124
1125    /**
1126     * Access to DeviceIdleController service.
1127     */
1128    DeviceIdleController.LocalService mLocalDeviceIdleController;
1129
1130    /**
1131     * Information about and control over application operations
1132     */
1133    final AppOpsService mAppOpsService;
1134
1135    /**
1136     * Current configuration information.  HistoryRecord objects are given
1137     * a reference to this object to indicate which configuration they are
1138     * currently running in, so this object must be kept immutable.
1139     */
1140    Configuration mConfiguration = new Configuration();
1141
1142    /**
1143     * Current sequencing integer of the configuration, for skipping old
1144     * configurations.
1145     */
1146    int mConfigurationSeq = 0;
1147
1148    boolean mSuppressResizeConfigChanges = false;
1149
1150    /**
1151     * Hardware-reported OpenGLES version.
1152     */
1153    final int GL_ES_VERSION;
1154
1155    /**
1156     * List of initialization arguments to pass to all processes when binding applications to them.
1157     * For example, references to the commonly used services.
1158     */
1159    HashMap<String, IBinder> mAppBindArgs;
1160
1161    /**
1162     * Temporary to avoid allocations.  Protected by main lock.
1163     */
1164    final StringBuilder mStringBuilder = new StringBuilder(256);
1165
1166    /**
1167     * Used to control how we initialize the service.
1168     */
1169    ComponentName mTopComponent;
1170    String mTopAction = Intent.ACTION_MAIN;
1171    String mTopData;
1172
1173    volatile boolean mProcessesReady = false;
1174    volatile boolean mSystemReady = false;
1175    volatile boolean mOnBattery = false;
1176    volatile int mFactoryTest;
1177
1178    @GuardedBy("this") boolean mBooting = false;
1179    @GuardedBy("this") boolean mCallFinishBooting = false;
1180    @GuardedBy("this") boolean mBootAnimationComplete = false;
1181    @GuardedBy("this") boolean mLaunchWarningShown = false;
1182    @GuardedBy("this") boolean mCheckedForSetup = false;
1183
1184    Context mContext;
1185
1186    /**
1187     * The time at which we will allow normal application switches again,
1188     * after a call to {@link #stopAppSwitches()}.
1189     */
1190    long mAppSwitchesAllowedTime;
1191
1192    /**
1193     * This is set to true after the first switch after mAppSwitchesAllowedTime
1194     * is set; any switches after that will clear the time.
1195     */
1196    boolean mDidAppSwitch;
1197
1198    /**
1199     * Last time (in realtime) at which we checked for power usage.
1200     */
1201    long mLastPowerCheckRealtime;
1202
1203    /**
1204     * Last time (in uptime) at which we checked for power usage.
1205     */
1206    long mLastPowerCheckUptime;
1207
1208    /**
1209     * Set while we are wanting to sleep, to prevent any
1210     * activities from being started/resumed.
1211     */
1212    private boolean mSleeping = false;
1213
1214    /**
1215     * The process state used for processes that are running the top activities.
1216     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1217     */
1218    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1219
1220    /**
1221     * Set while we are running a voice interaction.  This overrides
1222     * sleeping while it is active.
1223     */
1224    private IVoiceInteractionSession mRunningVoice;
1225
1226    /**
1227     * For some direct access we need to power manager.
1228     */
1229    PowerManagerInternal mLocalPowerManager;
1230
1231    /**
1232     * We want to hold a wake lock while running a voice interaction session, since
1233     * this may happen with the screen off and we need to keep the CPU running to
1234     * be able to continue to interact with the user.
1235     */
1236    PowerManager.WakeLock mVoiceWakeLock;
1237
1238    /**
1239     * State of external calls telling us if the device is awake or asleep.
1240     */
1241    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1242
1243    /**
1244     * A list of tokens that cause the top activity to be put to sleep.
1245     * They are used by components that may hide and block interaction with underlying
1246     * activities.
1247     */
1248    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1249
1250    static final int LOCK_SCREEN_HIDDEN = 0;
1251    static final int LOCK_SCREEN_LEAVING = 1;
1252    static final int LOCK_SCREEN_SHOWN = 2;
1253    /**
1254     * State of external call telling us if the lock screen is shown.
1255     */
1256    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1257
1258    /**
1259     * Set if we are shutting down the system, similar to sleeping.
1260     */
1261    boolean mShuttingDown = false;
1262
1263    /**
1264     * Current sequence id for oom_adj computation traversal.
1265     */
1266    int mAdjSeq = 0;
1267
1268    /**
1269     * Current sequence id for process LRU updating.
1270     */
1271    int mLruSeq = 0;
1272
1273    /**
1274     * Keep track of the non-cached/empty process we last found, to help
1275     * determine how to distribute cached/empty processes next time.
1276     */
1277    int mNumNonCachedProcs = 0;
1278
1279    /**
1280     * Keep track of the number of cached hidden procs, to balance oom adj
1281     * distribution between those and empty procs.
1282     */
1283    int mNumCachedHiddenProcs = 0;
1284
1285    /**
1286     * Keep track of the number of service processes we last found, to
1287     * determine on the next iteration which should be B services.
1288     */
1289    int mNumServiceProcs = 0;
1290    int mNewNumAServiceProcs = 0;
1291    int mNewNumServiceProcs = 0;
1292
1293    /**
1294     * Allow the current computed overall memory level of the system to go down?
1295     * This is set to false when we are killing processes for reasons other than
1296     * memory management, so that the now smaller process list will not be taken as
1297     * an indication that memory is tighter.
1298     */
1299    boolean mAllowLowerMemLevel = false;
1300
1301    /**
1302     * The last computed memory level, for holding when we are in a state that
1303     * processes are going away for other reasons.
1304     */
1305    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1306
1307    /**
1308     * The last total number of process we have, to determine if changes actually look
1309     * like a shrinking number of process due to lower RAM.
1310     */
1311    int mLastNumProcesses;
1312
1313    /**
1314     * The uptime of the last time we performed idle maintenance.
1315     */
1316    long mLastIdleTime = SystemClock.uptimeMillis();
1317
1318    /**
1319     * Total time spent with RAM that has been added in the past since the last idle time.
1320     */
1321    long mLowRamTimeSinceLastIdle = 0;
1322
1323    /**
1324     * If RAM is currently low, when that horrible situation started.
1325     */
1326    long mLowRamStartTime = 0;
1327
1328    /**
1329     * For reporting to battery stats the current top application.
1330     */
1331    private String mCurResumedPackage = null;
1332    private int mCurResumedUid = -1;
1333
1334    /**
1335     * For reporting to battery stats the apps currently running foreground
1336     * service.  The ProcessMap is package/uid tuples; each of these contain
1337     * an array of the currently foreground processes.
1338     */
1339    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1340            = new ProcessMap<ArrayList<ProcessRecord>>();
1341
1342    /**
1343     * This is set if we had to do a delayed dexopt of an app before launching
1344     * it, to increase the ANR timeouts in that case.
1345     */
1346    boolean mDidDexOpt;
1347
1348    /**
1349     * Set if the systemServer made a call to enterSafeMode.
1350     */
1351    boolean mSafeMode;
1352
1353    /**
1354     * If true, we are running under a test environment so will sample PSS from processes
1355     * much more rapidly to try to collect better data when the tests are rapidly
1356     * running through apps.
1357     */
1358    boolean mTestPssMode = false;
1359
1360    String mDebugApp = null;
1361    boolean mWaitForDebugger = false;
1362    boolean mDebugTransient = false;
1363    String mOrigDebugApp = null;
1364    boolean mOrigWaitForDebugger = false;
1365    boolean mAlwaysFinishActivities = false;
1366    boolean mLenientBackgroundCheck = false;
1367    boolean mForceResizableActivities;
1368    boolean mSupportsMultiWindow;
1369    boolean mSupportsFreeformWindowManagement;
1370    boolean mSupportsPictureInPicture;
1371    boolean mSupportsLeanbackOnly;
1372    Rect mDefaultPinnedStackBounds;
1373    IActivityController mController = null;
1374    boolean mControllerIsAMonkey = false;
1375    String mProfileApp = null;
1376    ProcessRecord mProfileProc = null;
1377    String mProfileFile;
1378    ParcelFileDescriptor mProfileFd;
1379    int mSamplingInterval = 0;
1380    boolean mAutoStopProfiler = false;
1381    int mProfileType = 0;
1382    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1383    String mMemWatchDumpProcName;
1384    String mMemWatchDumpFile;
1385    int mMemWatchDumpPid;
1386    int mMemWatchDumpUid;
1387    String mTrackAllocationApp = null;
1388    String mNativeDebuggingApp = null;
1389
1390    final long[] mTmpLong = new long[2];
1391
1392    static final class ProcessChangeItem {
1393        static final int CHANGE_ACTIVITIES = 1<<0;
1394        static final int CHANGE_PROCESS_STATE = 1<<1;
1395        int changes;
1396        int uid;
1397        int pid;
1398        int processState;
1399        boolean foregroundActivities;
1400    }
1401
1402    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1403    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1404
1405    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1406    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1407
1408    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1409    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1410
1411    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1412    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1413
1414    /**
1415     * Runtime CPU use collection thread.  This object's lock is used to
1416     * perform synchronization with the thread (notifying it to run).
1417     */
1418    final Thread mProcessCpuThread;
1419
1420    /**
1421     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1422     * Must acquire this object's lock when accessing it.
1423     * NOTE: this lock will be held while doing long operations (trawling
1424     * through all processes in /proc), so it should never be acquired by
1425     * any critical paths such as when holding the main activity manager lock.
1426     */
1427    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1428            MONITOR_THREAD_CPU_USAGE);
1429    final AtomicLong mLastCpuTime = new AtomicLong(0);
1430    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1431
1432    long mLastWriteTime = 0;
1433
1434    /**
1435     * Used to retain an update lock when the foreground activity is in
1436     * immersive mode.
1437     */
1438    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1439
1440    /**
1441     * Set to true after the system has finished booting.
1442     */
1443    boolean mBooted = false;
1444
1445    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1446    int mProcessLimitOverride = -1;
1447
1448    WindowManagerService mWindowManager;
1449    final ActivityThread mSystemThread;
1450
1451    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1452        final ProcessRecord mApp;
1453        final int mPid;
1454        final IApplicationThread mAppThread;
1455
1456        AppDeathRecipient(ProcessRecord app, int pid,
1457                IApplicationThread thread) {
1458            if (DEBUG_ALL) Slog.v(
1459                TAG, "New death recipient " + this
1460                + " for thread " + thread.asBinder());
1461            mApp = app;
1462            mPid = pid;
1463            mAppThread = thread;
1464        }
1465
1466        @Override
1467        public void binderDied() {
1468            if (DEBUG_ALL) Slog.v(
1469                TAG, "Death received in " + this
1470                + " for thread " + mAppThread.asBinder());
1471            synchronized(ActivityManagerService.this) {
1472                appDiedLocked(mApp, mPid, mAppThread, true);
1473            }
1474        }
1475    }
1476
1477    static final int SHOW_ERROR_UI_MSG = 1;
1478    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1479    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1480    static final int UPDATE_CONFIGURATION_MSG = 4;
1481    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1482    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1483    static final int SERVICE_TIMEOUT_MSG = 12;
1484    static final int UPDATE_TIME_ZONE = 13;
1485    static final int SHOW_UID_ERROR_UI_MSG = 14;
1486    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1487    static final int PROC_START_TIMEOUT_MSG = 20;
1488    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1489    static final int KILL_APPLICATION_MSG = 22;
1490    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1491    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1492    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1493    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1494    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1495    static final int CLEAR_DNS_CACHE_MSG = 28;
1496    static final int UPDATE_HTTP_PROXY_MSG = 29;
1497    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1498    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1499    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1500    static final int REPORT_MEM_USAGE_MSG = 33;
1501    static final int REPORT_USER_SWITCH_MSG = 34;
1502    static final int CONTINUE_USER_SWITCH_MSG = 35;
1503    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1504    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1505    static final int PERSIST_URI_GRANTS_MSG = 38;
1506    static final int REQUEST_ALL_PSS_MSG = 39;
1507    static final int START_PROFILES_MSG = 40;
1508    static final int UPDATE_TIME = 41;
1509    static final int SYSTEM_USER_START_MSG = 42;
1510    static final int SYSTEM_USER_CURRENT_MSG = 43;
1511    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1512    static final int FINISH_BOOTING_MSG = 45;
1513    static final int START_USER_SWITCH_UI_MSG = 46;
1514    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1515    static final int DISMISS_DIALOG_UI_MSG = 48;
1516    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1517    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1518    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1519    static final int DELETE_DUMPHEAP_MSG = 52;
1520    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1521    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1522    static final int REPORT_TIME_TRACKER_MSG = 55;
1523    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1524    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1525    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1526    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1527    static final int IDLE_UIDS_MSG = 60;
1528    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1529    static final int LOG_STACK_STATE = 62;
1530    static final int VR_MODE_CHANGE_MSG = 63;
1531    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1532    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1533    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1534    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1535    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1536    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1537    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1538
1539    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1540    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1541    static final int FIRST_COMPAT_MODE_MSG = 300;
1542    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1543
1544    static ServiceThread sKillThread = null;
1545    static KillHandler sKillHandler = null;
1546
1547    CompatModeDialog mCompatModeDialog;
1548    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1549    long mLastMemUsageReportTime = 0;
1550
1551    /**
1552     * Flag whether the current user is a "monkey", i.e. whether
1553     * the UI is driven by a UI automation tool.
1554     */
1555    private boolean mUserIsMonkey;
1556
1557    /** Flag whether the device has a Recents UI */
1558    boolean mHasRecents;
1559
1560    /** The dimensions of the thumbnails in the Recents UI. */
1561    int mThumbnailWidth;
1562    int mThumbnailHeight;
1563    float mFullscreenThumbnailScale;
1564
1565    final ServiceThread mHandlerThread;
1566    final MainHandler mHandler;
1567    final UiHandler mUiHandler;
1568
1569    PackageManagerInternal mPackageManagerInt;
1570
1571    // VoiceInteraction session ID that changes for each new request except when
1572    // being called for multiwindow assist in a single session.
1573    private int mViSessionId = 1000;
1574
1575    final class KillHandler extends Handler {
1576        static final int KILL_PROCESS_GROUP_MSG = 4000;
1577
1578        public KillHandler(Looper looper) {
1579            super(looper, null, true);
1580        }
1581
1582        @Override
1583        public void handleMessage(Message msg) {
1584            switch (msg.what) {
1585                case KILL_PROCESS_GROUP_MSG:
1586                {
1587                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1588                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1589                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1590                }
1591                break;
1592
1593                default:
1594                    super.handleMessage(msg);
1595            }
1596        }
1597    }
1598
1599    final class UiHandler extends Handler {
1600        public UiHandler() {
1601            super(com.android.server.UiThread.get().getLooper(), null, true);
1602        }
1603
1604        @Override
1605        public void handleMessage(Message msg) {
1606            switch (msg.what) {
1607            case SHOW_ERROR_UI_MSG: {
1608                mAppErrors.handleShowAppErrorUi(msg);
1609                ensureBootCompleted();
1610            } break;
1611            case SHOW_NOT_RESPONDING_UI_MSG: {
1612                mAppErrors.handleShowAnrUi(msg);
1613                ensureBootCompleted();
1614            } break;
1615            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1616                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1617                synchronized (ActivityManagerService.this) {
1618                    ProcessRecord proc = (ProcessRecord) data.get("app");
1619                    if (proc == null) {
1620                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1621                        break;
1622                    }
1623                    if (proc.crashDialog != null) {
1624                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1625                        return;
1626                    }
1627                    AppErrorResult res = (AppErrorResult) data.get("result");
1628                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1629                        Dialog d = new StrictModeViolationDialog(mContext,
1630                                ActivityManagerService.this, res, proc);
1631                        d.show();
1632                        proc.crashDialog = d;
1633                    } else {
1634                        // The device is asleep, so just pretend that the user
1635                        // saw a crash dialog and hit "force quit".
1636                        res.set(0);
1637                    }
1638                }
1639                ensureBootCompleted();
1640            } break;
1641            case SHOW_FACTORY_ERROR_UI_MSG: {
1642                Dialog d = new FactoryErrorDialog(
1643                    mContext, msg.getData().getCharSequence("msg"));
1644                d.show();
1645                ensureBootCompleted();
1646            } break;
1647            case WAIT_FOR_DEBUGGER_UI_MSG: {
1648                synchronized (ActivityManagerService.this) {
1649                    ProcessRecord app = (ProcessRecord)msg.obj;
1650                    if (msg.arg1 != 0) {
1651                        if (!app.waitedForDebugger) {
1652                            Dialog d = new AppWaitingForDebuggerDialog(
1653                                    ActivityManagerService.this,
1654                                    mContext, app);
1655                            app.waitDialog = d;
1656                            app.waitedForDebugger = true;
1657                            d.show();
1658                        }
1659                    } else {
1660                        if (app.waitDialog != null) {
1661                            app.waitDialog.dismiss();
1662                            app.waitDialog = null;
1663                        }
1664                    }
1665                }
1666            } break;
1667            case SHOW_UID_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_wipe_data));
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_FINGERPRINT_ERROR_UI_MSG: {
1680                if (mShowDialogs) {
1681                    AlertDialog d = new BaseErrorDialog(mContext);
1682                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1683                    d.setCancelable(false);
1684                    d.setTitle(mContext.getText(R.string.android_system_label));
1685                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1686                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1687                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1688                    d.show();
1689                }
1690            } break;
1691            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    ActivityRecord ar = (ActivityRecord) msg.obj;
1694                    if (mCompatModeDialog != null) {
1695                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1696                                ar.info.applicationInfo.packageName)) {
1697                            return;
1698                        }
1699                        mCompatModeDialog.dismiss();
1700                        mCompatModeDialog = null;
1701                    }
1702                    if (ar != null && false) {
1703                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1704                                ar.packageName)) {
1705                            int mode = mCompatModePackages.computeCompatModeLocked(
1706                                    ar.info.applicationInfo);
1707                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1708                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1709                                mCompatModeDialog = new CompatModeDialog(
1710                                        ActivityManagerService.this, mContext,
1711                                        ar.info.applicationInfo);
1712                                mCompatModeDialog.show();
1713                            }
1714                        }
1715                    }
1716                }
1717                break;
1718            }
1719            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1722                    if (mUnsupportedDisplaySizeDialog != null) {
1723                        mUnsupportedDisplaySizeDialog.dismiss();
1724                        mUnsupportedDisplaySizeDialog = null;
1725                    }
1726                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1727                            ar.packageName)) {
1728                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1729                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1730                        mUnsupportedDisplaySizeDialog.show();
1731                    }
1732                }
1733                break;
1734            }
1735            case START_USER_SWITCH_UI_MSG: {
1736                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1737                break;
1738            }
1739            case DISMISS_DIALOG_UI_MSG: {
1740                final Dialog d = (Dialog) msg.obj;
1741                d.dismiss();
1742                break;
1743            }
1744            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1745                dispatchProcessesChanged();
1746                break;
1747            }
1748            case DISPATCH_PROCESS_DIED_UI_MSG: {
1749                final int pid = msg.arg1;
1750                final int uid = msg.arg2;
1751                dispatchProcessDied(pid, uid);
1752                break;
1753            }
1754            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1755                dispatchUidsChanged();
1756            } break;
1757            }
1758        }
1759    }
1760
1761    final class MainHandler extends Handler {
1762        public MainHandler(Looper looper) {
1763            super(looper, null, true);
1764        }
1765
1766        @Override
1767        public void handleMessage(Message msg) {
1768            switch (msg.what) {
1769            case UPDATE_CONFIGURATION_MSG: {
1770                final ContentResolver resolver = mContext.getContentResolver();
1771                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1772                        msg.arg1);
1773            } break;
1774            case GC_BACKGROUND_PROCESSES_MSG: {
1775                synchronized (ActivityManagerService.this) {
1776                    performAppGcsIfAppropriateLocked();
1777                }
1778            } break;
1779            case SERVICE_TIMEOUT_MSG: {
1780                if (mDidDexOpt) {
1781                    mDidDexOpt = false;
1782                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1783                    nmsg.obj = msg.obj;
1784                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1785                    return;
1786                }
1787                mServices.serviceTimeout((ProcessRecord)msg.obj);
1788            } break;
1789            case UPDATE_TIME_ZONE: {
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.updateTimeZone();
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1798                            }
1799                        }
1800                    }
1801                }
1802            } break;
1803            case CLEAR_DNS_CACHE_MSG: {
1804                synchronized (ActivityManagerService.this) {
1805                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1806                        ProcessRecord r = mLruProcesses.get(i);
1807                        if (r.thread != null) {
1808                            try {
1809                                r.thread.clearDnsCache();
1810                            } catch (RemoteException ex) {
1811                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1812                            }
1813                        }
1814                    }
1815                }
1816            } break;
1817            case UPDATE_HTTP_PROXY_MSG: {
1818                ProxyInfo proxy = (ProxyInfo)msg.obj;
1819                String host = "";
1820                String port = "";
1821                String exclList = "";
1822                Uri pacFileUrl = Uri.EMPTY;
1823                if (proxy != null) {
1824                    host = proxy.getHost();
1825                    port = Integer.toString(proxy.getPort());
1826                    exclList = proxy.getExclusionListAsString();
1827                    pacFileUrl = proxy.getPacFileUrl();
1828                }
1829                synchronized (ActivityManagerService.this) {
1830                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1831                        ProcessRecord r = mLruProcesses.get(i);
1832                        if (r.thread != null) {
1833                            try {
1834                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1835                            } catch (RemoteException ex) {
1836                                Slog.w(TAG, "Failed to update http proxy for: " +
1837                                        r.info.processName);
1838                            }
1839                        }
1840                    }
1841                }
1842            } break;
1843            case PROC_START_TIMEOUT_MSG: {
1844                if (mDidDexOpt) {
1845                    mDidDexOpt = false;
1846                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1847                    nmsg.obj = msg.obj;
1848                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1849                    return;
1850                }
1851                ProcessRecord app = (ProcessRecord)msg.obj;
1852                synchronized (ActivityManagerService.this) {
1853                    processStartTimedOutLocked(app);
1854                }
1855            } break;
1856            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1857                ProcessRecord app = (ProcessRecord)msg.obj;
1858                synchronized (ActivityManagerService.this) {
1859                    processContentProviderPublishTimedOutLocked(app);
1860                }
1861            } break;
1862            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1863                synchronized (ActivityManagerService.this) {
1864                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1865                }
1866            } break;
1867            case KILL_APPLICATION_MSG: {
1868                synchronized (ActivityManagerService.this) {
1869                    final int appId = msg.arg1;
1870                    final int userId = msg.arg2;
1871                    Bundle bundle = (Bundle)msg.obj;
1872                    String pkg = bundle.getString("pkg");
1873                    String reason = bundle.getString("reason");
1874                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1875                            false, userId, reason);
1876                }
1877            } break;
1878            case FINALIZE_PENDING_INTENT_MSG: {
1879                ((PendingIntentRecord)msg.obj).completeFinalize();
1880            } break;
1881            case POST_HEAVY_NOTIFICATION_MSG: {
1882                INotificationManager inm = NotificationManager.getService();
1883                if (inm == null) {
1884                    return;
1885                }
1886
1887                ActivityRecord root = (ActivityRecord)msg.obj;
1888                ProcessRecord process = root.app;
1889                if (process == null) {
1890                    return;
1891                }
1892
1893                try {
1894                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1895                    String text = mContext.getString(R.string.heavy_weight_notification,
1896                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1897                    Notification notification = new Notification.Builder(context)
1898                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1899                            .setWhen(0)
1900                            .setOngoing(true)
1901                            .setTicker(text)
1902                            .setColor(mContext.getColor(
1903                                    com.android.internal.R.color.system_notification_accent_color))
1904                            .setContentTitle(text)
1905                            .setContentText(
1906                                    mContext.getText(R.string.heavy_weight_notification_detail))
1907                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1908                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1909                                    new UserHandle(root.userId)))
1910                            .build();
1911                    try {
1912                        int[] outId = new int[1];
1913                        inm.enqueueNotificationWithTag("android", "android", null,
1914                                R.string.heavy_weight_notification,
1915                                notification, outId, root.userId);
1916                    } catch (RuntimeException e) {
1917                        Slog.w(ActivityManagerService.TAG,
1918                                "Error showing notification for heavy-weight app", e);
1919                    } catch (RemoteException e) {
1920                    }
1921                } catch (NameNotFoundException e) {
1922                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1923                }
1924            } break;
1925            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1926                INotificationManager inm = NotificationManager.getService();
1927                if (inm == null) {
1928                    return;
1929                }
1930                try {
1931                    inm.cancelNotificationWithTag("android", null,
1932                            R.string.heavy_weight_notification,  msg.arg1);
1933                } catch (RuntimeException e) {
1934                    Slog.w(ActivityManagerService.TAG,
1935                            "Error canceling notification for service", e);
1936                } catch (RemoteException e) {
1937                }
1938            } break;
1939            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1940                synchronized (ActivityManagerService.this) {
1941                    checkExcessivePowerUsageLocked(true);
1942                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1943                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1944                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1945                }
1946            } break;
1947            case REPORT_MEM_USAGE_MSG: {
1948                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1949                Thread thread = new Thread() {
1950                    @Override public void run() {
1951                        reportMemUsage(memInfos);
1952                    }
1953                };
1954                thread.start();
1955                break;
1956            }
1957            case REPORT_USER_SWITCH_MSG: {
1958                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1959                break;
1960            }
1961            case CONTINUE_USER_SWITCH_MSG: {
1962                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1963                break;
1964            }
1965            case USER_SWITCH_TIMEOUT_MSG: {
1966                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1967                break;
1968            }
1969            case IMMERSIVE_MODE_LOCK_MSG: {
1970                final boolean nextState = (msg.arg1 != 0);
1971                if (mUpdateLock.isHeld() != nextState) {
1972                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1973                            "Applying new update lock state '" + nextState
1974                            + "' for " + (ActivityRecord)msg.obj);
1975                    if (nextState) {
1976                        mUpdateLock.acquire();
1977                    } else {
1978                        mUpdateLock.release();
1979                    }
1980                }
1981                break;
1982            }
1983            case PERSIST_URI_GRANTS_MSG: {
1984                writeGrantedUriPermissions();
1985                break;
1986            }
1987            case REQUEST_ALL_PSS_MSG: {
1988                synchronized (ActivityManagerService.this) {
1989                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1990                }
1991                break;
1992            }
1993            case START_PROFILES_MSG: {
1994                synchronized (ActivityManagerService.this) {
1995                    mUserController.startProfilesLocked();
1996                }
1997                break;
1998            }
1999            case UPDATE_TIME: {
2000                synchronized (ActivityManagerService.this) {
2001                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2002                        ProcessRecord r = mLruProcesses.get(i);
2003                        if (r.thread != null) {
2004                            try {
2005                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2006                            } catch (RemoteException ex) {
2007                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2008                            }
2009                        }
2010                    }
2011                }
2012                break;
2013            }
2014            case SYSTEM_USER_START_MSG: {
2015                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2016                        Integer.toString(msg.arg1), msg.arg1);
2017                mSystemServiceManager.startUser(msg.arg1);
2018                break;
2019            }
2020            case SYSTEM_USER_UNLOCK_MSG: {
2021                final int userId = msg.arg1;
2022                mSystemServiceManager.unlockUser(userId);
2023                synchronized (ActivityManagerService.this) {
2024                    mRecentTasks.loadUserRecentsLocked(userId);
2025                }
2026                if (userId == UserHandle.USER_SYSTEM) {
2027                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2028                }
2029                installEncryptionUnawareProviders(userId);
2030                mUserController.finishUserUnlocked((UserState) msg.obj);
2031                break;
2032            }
2033            case SYSTEM_USER_CURRENT_MSG: {
2034                mBatteryStatsService.noteEvent(
2035                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2036                        Integer.toString(msg.arg2), msg.arg2);
2037                mBatteryStatsService.noteEvent(
2038                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2039                        Integer.toString(msg.arg1), msg.arg1);
2040                mSystemServiceManager.switchUser(msg.arg1);
2041                break;
2042            }
2043            case ENTER_ANIMATION_COMPLETE_MSG: {
2044                synchronized (ActivityManagerService.this) {
2045                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2046                    if (r != null && r.app != null && r.app.thread != null) {
2047                        try {
2048                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2049                        } catch (RemoteException e) {
2050                        }
2051                    }
2052                }
2053                break;
2054            }
2055            case FINISH_BOOTING_MSG: {
2056                if (msg.arg1 != 0) {
2057                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2058                    finishBooting();
2059                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2060                }
2061                if (msg.arg2 != 0) {
2062                    enableScreenAfterBoot();
2063                }
2064                break;
2065            }
2066            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2067                try {
2068                    Locale l = (Locale) msg.obj;
2069                    IBinder service = ServiceManager.getService("mount");
2070                    IMountService mountService = IMountService.Stub.asInterface(service);
2071                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2072                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2073                } catch (RemoteException e) {
2074                    Log.e(TAG, "Error storing locale for decryption UI", e);
2075                }
2076                break;
2077            }
2078            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2107                synchronized (ActivityManagerService.this) {
2108                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                        try {
2110                            // Make a one-way callback to the listener
2111                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2112                        } catch (RemoteException e){
2113                            // Handled by the RemoteCallbackList
2114                        }
2115                    }
2116                    mTaskStackListeners.finishBroadcast();
2117                }
2118                break;
2119            }
2120            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2123                        try {
2124                            // Make a one-way callback to the listener
2125                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2126                        } catch (RemoteException e){
2127                            // Handled by the RemoteCallbackList
2128                        }
2129                    }
2130                    mTaskStackListeners.finishBroadcast();
2131                }
2132                break;
2133            }
2134            case NOTIFY_FORCED_RESIZABLE_MSG: {
2135                synchronized (ActivityManagerService.this) {
2136                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2137                        try {
2138                            // Make a one-way callback to the listener
2139                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2140                                    (String) msg.obj, msg.arg1);
2141                        } catch (RemoteException e){
2142                            // Handled by the RemoteCallbackList
2143                        }
2144                    }
2145                    mTaskStackListeners.finishBroadcast();
2146                }
2147                break;
2148            }
2149                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2150                    synchronized (ActivityManagerService.this) {
2151                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2152                            try {
2153                                // Make a one-way callback to the listener
2154                                mTaskStackListeners.getBroadcastItem(i)
2155                                        .onActivityDismissingDockedStack();
2156                            } catch (RemoteException e){
2157                                // Handled by the RemoteCallbackList
2158                            }
2159                        }
2160                        mTaskStackListeners.finishBroadcast();
2161                    }
2162                    break;
2163                }
2164            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2165                final int uid = msg.arg1;
2166                final byte[] firstPacket = (byte[]) msg.obj;
2167
2168                synchronized (mPidsSelfLocked) {
2169                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2170                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2171                        if (p.uid == uid) {
2172                            try {
2173                                p.thread.notifyCleartextNetwork(firstPacket);
2174                            } catch (RemoteException ignored) {
2175                            }
2176                        }
2177                    }
2178                }
2179                break;
2180            }
2181            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2182                final String procName;
2183                final int uid;
2184                final long memLimit;
2185                final String reportPackage;
2186                synchronized (ActivityManagerService.this) {
2187                    procName = mMemWatchDumpProcName;
2188                    uid = mMemWatchDumpUid;
2189                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2190                    if (val == null) {
2191                        val = mMemWatchProcesses.get(procName, 0);
2192                    }
2193                    if (val != null) {
2194                        memLimit = val.first;
2195                        reportPackage = val.second;
2196                    } else {
2197                        memLimit = 0;
2198                        reportPackage = null;
2199                    }
2200                }
2201                if (procName == null) {
2202                    return;
2203                }
2204
2205                if (DEBUG_PSS) Slog.d(TAG_PSS,
2206                        "Showing dump heap notification from " + procName + "/" + uid);
2207
2208                INotificationManager inm = NotificationManager.getService();
2209                if (inm == null) {
2210                    return;
2211                }
2212
2213                String text = mContext.getString(R.string.dump_heap_notification, procName);
2214
2215
2216                Intent deleteIntent = new Intent();
2217                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2218                Intent intent = new Intent();
2219                intent.setClassName("android", DumpHeapActivity.class.getName());
2220                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2221                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2222                if (reportPackage != null) {
2223                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2224                }
2225                int userId = UserHandle.getUserId(uid);
2226                Notification notification = new Notification.Builder(mContext)
2227                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2228                        .setWhen(0)
2229                        .setOngoing(true)
2230                        .setAutoCancel(true)
2231                        .setTicker(text)
2232                        .setColor(mContext.getColor(
2233                                com.android.internal.R.color.system_notification_accent_color))
2234                        .setContentTitle(text)
2235                        .setContentText(
2236                                mContext.getText(R.string.dump_heap_notification_detail))
2237                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2238                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2239                                new UserHandle(userId)))
2240                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2241                                deleteIntent, 0, UserHandle.SYSTEM))
2242                        .build();
2243
2244                try {
2245                    int[] outId = new int[1];
2246                    inm.enqueueNotificationWithTag("android", "android", null,
2247                            R.string.dump_heap_notification,
2248                            notification, outId, userId);
2249                } catch (RuntimeException e) {
2250                    Slog.w(ActivityManagerService.TAG,
2251                            "Error showing notification for dump heap", e);
2252                } catch (RemoteException e) {
2253                }
2254            } break;
2255            case DELETE_DUMPHEAP_MSG: {
2256                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2257                        DumpHeapActivity.JAVA_URI,
2258                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2259                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2260                        UserHandle.myUserId());
2261                synchronized (ActivityManagerService.this) {
2262                    mMemWatchDumpFile = null;
2263                    mMemWatchDumpProcName = null;
2264                    mMemWatchDumpPid = -1;
2265                    mMemWatchDumpUid = -1;
2266                }
2267            } break;
2268            case FOREGROUND_PROFILE_CHANGED_MSG: {
2269                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2270            } break;
2271            case REPORT_TIME_TRACKER_MSG: {
2272                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2273                tracker.deliverResult(mContext);
2274            } break;
2275            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2276                mUserController.dispatchUserSwitchComplete(msg.arg1);
2277            } break;
2278            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2279                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2280                try {
2281                    connection.shutdown();
2282                } catch (RemoteException e) {
2283                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2284                }
2285                // Only a UiAutomation can set this flag and now that
2286                // it is finished we make sure it is reset to its default.
2287                mUserIsMonkey = false;
2288            } break;
2289            case APP_BOOST_DEACTIVATE_MSG: {
2290                synchronized(ActivityManagerService.this) {
2291                    if (mIsBoosted) {
2292                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2293                            nativeMigrateFromBoost();
2294                            mIsBoosted = false;
2295                            mBoostStartTime = 0;
2296                        } else {
2297                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2298                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2299                        }
2300                    }
2301                }
2302            } break;
2303            case IDLE_UIDS_MSG: {
2304                idleUids();
2305            } break;
2306            case LOG_STACK_STATE: {
2307                synchronized (ActivityManagerService.this) {
2308                    mStackSupervisor.logStackState();
2309                }
2310            } break;
2311            case VR_MODE_CHANGE_MSG: {
2312                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2313                final ActivityRecord r = (ActivityRecord) msg.obj;
2314                boolean vrMode;
2315                ComponentName requestedPackage;
2316                ComponentName callingPackage;
2317                int userId;
2318                synchronized (ActivityManagerService.this) {
2319                    vrMode = r.requestedVrComponent != null;
2320                    requestedPackage = r.requestedVrComponent;
2321                    userId = r.userId;
2322                    callingPackage = r.info.getComponentName();
2323                    if (mInVrMode != vrMode) {
2324                        mInVrMode = vrMode;
2325                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2326                        if (r.app != null) {
2327                            ProcessRecord proc = r.app;
2328                            if (proc.vrThreadTid > 0) {
2329                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2330                                    if (mInVrMode == true) {
2331                                        Process.setThreadScheduler(proc.vrThreadTid,
2332                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2333                                    } else {
2334                                        Process.setThreadScheduler(proc.vrThreadTid,
2335                                            Process.SCHED_OTHER, 0);
2336                                    }
2337                                }
2338                            }
2339                        }
2340                    }
2341                }
2342                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2343            } break;
2344            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2345                final ActivityRecord r = (ActivityRecord) msg.obj;
2346                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2347                if (needsVrMode) {
2348                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2349                            r.info.getComponentName(), false);
2350                }
2351            } break;
2352            }
2353        }
2354    };
2355
2356    static final int COLLECT_PSS_BG_MSG = 1;
2357
2358    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2359        @Override
2360        public void handleMessage(Message msg) {
2361            switch (msg.what) {
2362            case COLLECT_PSS_BG_MSG: {
2363                long start = SystemClock.uptimeMillis();
2364                MemInfoReader memInfo = null;
2365                synchronized (ActivityManagerService.this) {
2366                    if (mFullPssPending) {
2367                        mFullPssPending = false;
2368                        memInfo = new MemInfoReader();
2369                    }
2370                }
2371                if (memInfo != null) {
2372                    updateCpuStatsNow();
2373                    long nativeTotalPss = 0;
2374                    synchronized (mProcessCpuTracker) {
2375                        final int N = mProcessCpuTracker.countStats();
2376                        for (int j=0; j<N; j++) {
2377                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2378                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2379                                // This is definitely an application process; skip it.
2380                                continue;
2381                            }
2382                            synchronized (mPidsSelfLocked) {
2383                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2384                                    // This is one of our own processes; skip it.
2385                                    continue;
2386                                }
2387                            }
2388                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2389                        }
2390                    }
2391                    memInfo.readMemInfo();
2392                    synchronized (ActivityManagerService.this) {
2393                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2394                                + (SystemClock.uptimeMillis()-start) + "ms");
2395                        final long cachedKb = memInfo.getCachedSizeKb();
2396                        final long freeKb = memInfo.getFreeSizeKb();
2397                        final long zramKb = memInfo.getZramTotalSizeKb();
2398                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2399                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2400                                kernelKb*1024, nativeTotalPss*1024);
2401                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2402                                nativeTotalPss);
2403                    }
2404                }
2405
2406                int num = 0;
2407                long[] tmp = new long[2];
2408                do {
2409                    ProcessRecord proc;
2410                    int procState;
2411                    int pid;
2412                    long lastPssTime;
2413                    synchronized (ActivityManagerService.this) {
2414                        if (mPendingPssProcesses.size() <= 0) {
2415                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2416                                    "Collected PSS of " + num + " processes in "
2417                                    + (SystemClock.uptimeMillis() - start) + "ms");
2418                            mPendingPssProcesses.clear();
2419                            return;
2420                        }
2421                        proc = mPendingPssProcesses.remove(0);
2422                        procState = proc.pssProcState;
2423                        lastPssTime = proc.lastPssTime;
2424                        if (proc.thread != null && procState == proc.setProcState
2425                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2426                                        < SystemClock.uptimeMillis()) {
2427                            pid = proc.pid;
2428                        } else {
2429                            proc = null;
2430                            pid = 0;
2431                        }
2432                    }
2433                    if (proc != null) {
2434                        long pss = Debug.getPss(pid, tmp, null);
2435                        synchronized (ActivityManagerService.this) {
2436                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2437                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2438                                num++;
2439                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2440                                        SystemClock.uptimeMillis());
2441                            }
2442                        }
2443                    }
2444                } while (true);
2445            }
2446            }
2447        }
2448    };
2449
2450    public void setSystemProcess() {
2451        try {
2452            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2453            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2454            ServiceManager.addService("meminfo", new MemBinder(this));
2455            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2456            ServiceManager.addService("dbinfo", new DbBinder(this));
2457            if (MONITOR_CPU_USAGE) {
2458                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2459            }
2460            ServiceManager.addService("permission", new PermissionController(this));
2461            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2462
2463            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2464                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2465            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2466
2467            synchronized (this) {
2468                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2469                app.persistent = true;
2470                app.pid = MY_PID;
2471                app.maxAdj = ProcessList.SYSTEM_ADJ;
2472                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2473                synchronized (mPidsSelfLocked) {
2474                    mPidsSelfLocked.put(app.pid, app);
2475                }
2476                updateLruProcessLocked(app, false, null);
2477                updateOomAdjLocked();
2478            }
2479        } catch (PackageManager.NameNotFoundException e) {
2480            throw new RuntimeException(
2481                    "Unable to find android system package", e);
2482        }
2483    }
2484
2485    public void setWindowManager(WindowManagerService wm) {
2486        mWindowManager = wm;
2487        mStackSupervisor.setWindowManager(wm);
2488        mActivityStarter.setWindowManager(wm);
2489    }
2490
2491    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2492        mUsageStatsService = usageStatsManager;
2493    }
2494
2495    public void startObservingNativeCrashes() {
2496        final NativeCrashListener ncl = new NativeCrashListener(this);
2497        ncl.start();
2498    }
2499
2500    public IAppOpsService getAppOpsService() {
2501        return mAppOpsService;
2502    }
2503
2504    static class MemBinder extends Binder {
2505        ActivityManagerService mActivityManagerService;
2506        MemBinder(ActivityManagerService activityManagerService) {
2507            mActivityManagerService = activityManagerService;
2508        }
2509
2510        @Override
2511        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2512            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2513                    != PackageManager.PERMISSION_GRANTED) {
2514                pw.println("Permission Denial: can't dump meminfo from from pid="
2515                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2516                        + " without permission " + android.Manifest.permission.DUMP);
2517                return;
2518            }
2519
2520            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2521        }
2522    }
2523
2524    static class GraphicsBinder extends Binder {
2525        ActivityManagerService mActivityManagerService;
2526        GraphicsBinder(ActivityManagerService activityManagerService) {
2527            mActivityManagerService = activityManagerService;
2528        }
2529
2530        @Override
2531        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2532            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2533                    != PackageManager.PERMISSION_GRANTED) {
2534                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2535                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2536                        + " without permission " + android.Manifest.permission.DUMP);
2537                return;
2538            }
2539
2540            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2541        }
2542    }
2543
2544    static class DbBinder extends Binder {
2545        ActivityManagerService mActivityManagerService;
2546        DbBinder(ActivityManagerService activityManagerService) {
2547            mActivityManagerService = activityManagerService;
2548        }
2549
2550        @Override
2551        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2552            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2553                    != PackageManager.PERMISSION_GRANTED) {
2554                pw.println("Permission Denial: can't dump dbinfo from from pid="
2555                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2556                        + " without permission " + android.Manifest.permission.DUMP);
2557                return;
2558            }
2559
2560            mActivityManagerService.dumpDbInfo(fd, pw, args);
2561        }
2562    }
2563
2564    static class CpuBinder extends Binder {
2565        ActivityManagerService mActivityManagerService;
2566        CpuBinder(ActivityManagerService activityManagerService) {
2567            mActivityManagerService = activityManagerService;
2568        }
2569
2570        @Override
2571        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2572            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2573                    != PackageManager.PERMISSION_GRANTED) {
2574                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2575                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2576                        + " without permission " + android.Manifest.permission.DUMP);
2577                return;
2578            }
2579
2580            synchronized (mActivityManagerService.mProcessCpuTracker) {
2581                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2582                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2583                        SystemClock.uptimeMillis()));
2584            }
2585        }
2586    }
2587
2588    public static final class Lifecycle extends SystemService {
2589        private final ActivityManagerService mService;
2590
2591        public Lifecycle(Context context) {
2592            super(context);
2593            mService = new ActivityManagerService(context);
2594        }
2595
2596        @Override
2597        public void onStart() {
2598            mService.start();
2599        }
2600
2601        public ActivityManagerService getService() {
2602            return mService;
2603        }
2604    }
2605
2606    // Note: This method is invoked on the main thread but may need to attach various
2607    // handlers to other threads.  So take care to be explicit about the looper.
2608    public ActivityManagerService(Context systemContext) {
2609        mContext = systemContext;
2610        mFactoryTest = FactoryTest.getMode();
2611        mSystemThread = ActivityThread.currentActivityThread();
2612
2613        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2614
2615        mHandlerThread = new ServiceThread(TAG,
2616                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2617        mHandlerThread.start();
2618        mHandler = new MainHandler(mHandlerThread.getLooper());
2619        mUiHandler = new UiHandler();
2620
2621        /* static; one-time init here */
2622        if (sKillHandler == null) {
2623            sKillThread = new ServiceThread(TAG + ":kill",
2624                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2625            sKillThread.start();
2626            sKillHandler = new KillHandler(sKillThread.getLooper());
2627        }
2628
2629        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2630                "foreground", BROADCAST_FG_TIMEOUT, false);
2631        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2632                "background", BROADCAST_BG_TIMEOUT, true);
2633        mBroadcastQueues[0] = mFgBroadcastQueue;
2634        mBroadcastQueues[1] = mBgBroadcastQueue;
2635
2636        mServices = new ActiveServices(this);
2637        mProviderMap = new ProviderMap(this);
2638        mAppErrors = new AppErrors(mContext, this);
2639
2640        // TODO: Move creation of battery stats service outside of activity manager service.
2641        File dataDir = Environment.getDataDirectory();
2642        File systemDir = new File(dataDir, "system");
2643        systemDir.mkdirs();
2644        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2645        mBatteryStatsService.getActiveStatistics().readLocked();
2646        mBatteryStatsService.scheduleWriteToDisk();
2647        mOnBattery = DEBUG_POWER ? true
2648                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2649        mBatteryStatsService.getActiveStatistics().setCallback(this);
2650
2651        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2652
2653        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2654        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2655                new IAppOpsCallback.Stub() {
2656                    @Override public void opChanged(int op, int uid, String packageName) {
2657                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2658                            if (mAppOpsService.checkOperation(op, uid, packageName)
2659                                    != AppOpsManager.MODE_ALLOWED) {
2660                                runInBackgroundDisabled(uid);
2661                            }
2662                        }
2663                    }
2664                });
2665
2666        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2667
2668        mUserController = new UserController(this);
2669
2670        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2671            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2672
2673        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2674            mUseFifoUiScheduling = true;
2675        }
2676
2677        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2678
2679        mConfiguration.setToDefaults();
2680        mConfiguration.setLocales(LocaleList.getDefault());
2681
2682        mConfigurationSeq = mConfiguration.seq = 1;
2683        mProcessCpuTracker.init();
2684
2685        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2686        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2687        mStackSupervisor = new ActivityStackSupervisor(this);
2688        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2689        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2690
2691        mProcessCpuThread = new Thread("CpuTracker") {
2692            @Override
2693            public void run() {
2694                while (true) {
2695                    try {
2696                        try {
2697                            synchronized(this) {
2698                                final long now = SystemClock.uptimeMillis();
2699                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2700                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2701                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2702                                //        + ", write delay=" + nextWriteDelay);
2703                                if (nextWriteDelay < nextCpuDelay) {
2704                                    nextCpuDelay = nextWriteDelay;
2705                                }
2706                                if (nextCpuDelay > 0) {
2707                                    mProcessCpuMutexFree.set(true);
2708                                    this.wait(nextCpuDelay);
2709                                }
2710                            }
2711                        } catch (InterruptedException e) {
2712                        }
2713                        updateCpuStatsNow();
2714                    } catch (Exception e) {
2715                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2716                    }
2717                }
2718            }
2719        };
2720
2721        Watchdog.getInstance().addMonitor(this);
2722        Watchdog.getInstance().addThread(mHandler);
2723    }
2724
2725    public void setSystemServiceManager(SystemServiceManager mgr) {
2726        mSystemServiceManager = mgr;
2727    }
2728
2729    public void setInstaller(Installer installer) {
2730        mInstaller = installer;
2731    }
2732
2733    private void start() {
2734        Process.removeAllProcessGroups();
2735        mProcessCpuThread.start();
2736
2737        mBatteryStatsService.publish(mContext);
2738        mAppOpsService.publish(mContext);
2739        Slog.d("AppOps", "AppOpsService published");
2740        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2741    }
2742
2743    void onUserStoppedLocked(int userId) {
2744        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2745    }
2746
2747    public void initPowerManagement() {
2748        mStackSupervisor.initPowerManagement();
2749        mBatteryStatsService.initPowerManagement();
2750        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2751        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2752        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2753        mVoiceWakeLock.setReferenceCounted(false);
2754    }
2755
2756    @Override
2757    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2758            throws RemoteException {
2759        if (code == SYSPROPS_TRANSACTION) {
2760            // We need to tell all apps about the system property change.
2761            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2762            synchronized(this) {
2763                final int NP = mProcessNames.getMap().size();
2764                for (int ip=0; ip<NP; ip++) {
2765                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2766                    final int NA = apps.size();
2767                    for (int ia=0; ia<NA; ia++) {
2768                        ProcessRecord app = apps.valueAt(ia);
2769                        if (app.thread != null) {
2770                            procs.add(app.thread.asBinder());
2771                        }
2772                    }
2773                }
2774            }
2775
2776            int N = procs.size();
2777            for (int i=0; i<N; i++) {
2778                Parcel data2 = Parcel.obtain();
2779                try {
2780                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2781                } catch (RemoteException e) {
2782                }
2783                data2.recycle();
2784            }
2785        }
2786        try {
2787            return super.onTransact(code, data, reply, flags);
2788        } catch (RuntimeException e) {
2789            // The activity manager only throws security exceptions, so let's
2790            // log all others.
2791            if (!(e instanceof SecurityException)) {
2792                Slog.wtf(TAG, "Activity Manager Crash", e);
2793            }
2794            throw e;
2795        }
2796    }
2797
2798    void updateCpuStats() {
2799        final long now = SystemClock.uptimeMillis();
2800        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2801            return;
2802        }
2803        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2804            synchronized (mProcessCpuThread) {
2805                mProcessCpuThread.notify();
2806            }
2807        }
2808    }
2809
2810    void updateCpuStatsNow() {
2811        synchronized (mProcessCpuTracker) {
2812            mProcessCpuMutexFree.set(false);
2813            final long now = SystemClock.uptimeMillis();
2814            boolean haveNewCpuStats = false;
2815
2816            if (MONITOR_CPU_USAGE &&
2817                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2818                mLastCpuTime.set(now);
2819                mProcessCpuTracker.update();
2820                if (mProcessCpuTracker.hasGoodLastStats()) {
2821                    haveNewCpuStats = true;
2822                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2823                    //Slog.i(TAG, "Total CPU usage: "
2824                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2825
2826                    // Slog the cpu usage if the property is set.
2827                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2828                        int user = mProcessCpuTracker.getLastUserTime();
2829                        int system = mProcessCpuTracker.getLastSystemTime();
2830                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2831                        int irq = mProcessCpuTracker.getLastIrqTime();
2832                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2833                        int idle = mProcessCpuTracker.getLastIdleTime();
2834
2835                        int total = user + system + iowait + irq + softIrq + idle;
2836                        if (total == 0) total = 1;
2837
2838                        EventLog.writeEvent(EventLogTags.CPU,
2839                                ((user+system+iowait+irq+softIrq) * 100) / total,
2840                                (user * 100) / total,
2841                                (system * 100) / total,
2842                                (iowait * 100) / total,
2843                                (irq * 100) / total,
2844                                (softIrq * 100) / total);
2845                    }
2846                }
2847            }
2848
2849            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2850            synchronized(bstats) {
2851                synchronized(mPidsSelfLocked) {
2852                    if (haveNewCpuStats) {
2853                        if (bstats.startAddingCpuLocked()) {
2854                            int totalUTime = 0;
2855                            int totalSTime = 0;
2856                            final int N = mProcessCpuTracker.countStats();
2857                            for (int i=0; i<N; i++) {
2858                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2859                                if (!st.working) {
2860                                    continue;
2861                                }
2862                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2863                                totalUTime += st.rel_utime;
2864                                totalSTime += st.rel_stime;
2865                                if (pr != null) {
2866                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2867                                    if (ps == null || !ps.isActive()) {
2868                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2869                                                pr.info.uid, pr.processName);
2870                                    }
2871                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2872                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2873                                } else {
2874                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2875                                    if (ps == null || !ps.isActive()) {
2876                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2877                                                bstats.mapUid(st.uid), st.name);
2878                                    }
2879                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2880                                }
2881                            }
2882                            final int userTime = mProcessCpuTracker.getLastUserTime();
2883                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2884                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2885                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2886                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2887                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2888                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2889                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2890                        }
2891                    }
2892                }
2893
2894                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2895                    mLastWriteTime = now;
2896                    mBatteryStatsService.scheduleWriteToDisk();
2897                }
2898            }
2899        }
2900    }
2901
2902    @Override
2903    public void batteryNeedsCpuUpdate() {
2904        updateCpuStatsNow();
2905    }
2906
2907    @Override
2908    public void batteryPowerChanged(boolean onBattery) {
2909        // When plugging in, update the CPU stats first before changing
2910        // the plug state.
2911        updateCpuStatsNow();
2912        synchronized (this) {
2913            synchronized(mPidsSelfLocked) {
2914                mOnBattery = DEBUG_POWER ? true : onBattery;
2915            }
2916        }
2917    }
2918
2919    @Override
2920    public void batterySendBroadcast(Intent intent) {
2921        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2922                AppOpsManager.OP_NONE, null, false, false,
2923                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2924    }
2925
2926    /**
2927     * Initialize the application bind args. These are passed to each
2928     * process when the bindApplication() IPC is sent to the process. They're
2929     * lazily setup to make sure the services are running when they're asked for.
2930     */
2931    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2932        if (mAppBindArgs == null) {
2933            mAppBindArgs = new HashMap<>();
2934
2935            // Isolated processes won't get this optimization, so that we don't
2936            // violate the rules about which services they have access to.
2937            if (!isolated) {
2938                // Setup the application init args
2939                mAppBindArgs.put("package", ServiceManager.getService("package"));
2940                mAppBindArgs.put("window", ServiceManager.getService("window"));
2941                mAppBindArgs.put(Context.ALARM_SERVICE,
2942                        ServiceManager.getService(Context.ALARM_SERVICE));
2943            }
2944        }
2945        return mAppBindArgs;
2946    }
2947
2948    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2949        if (r == null || mFocusedActivity == r) {
2950            return false;
2951        }
2952
2953        if (!r.isFocusable()) {
2954            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2955            return false;
2956        }
2957
2958        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2959
2960        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2961        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2962                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2963        mDoingSetFocusedActivity = true;
2964
2965        final ActivityRecord last = mFocusedActivity;
2966        mFocusedActivity = r;
2967        if (r.task.isApplicationTask()) {
2968            if (mCurAppTimeTracker != r.appTimeTracker) {
2969                // We are switching app tracking.  Complete the current one.
2970                if (mCurAppTimeTracker != null) {
2971                    mCurAppTimeTracker.stop();
2972                    mHandler.obtainMessage(
2973                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2974                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2975                    mCurAppTimeTracker = null;
2976                }
2977                if (r.appTimeTracker != null) {
2978                    mCurAppTimeTracker = r.appTimeTracker;
2979                    startTimeTrackingFocusedActivityLocked();
2980                }
2981            } else {
2982                startTimeTrackingFocusedActivityLocked();
2983            }
2984        } else {
2985            r.appTimeTracker = null;
2986        }
2987        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2988        // TODO: Probably not, because we don't want to resume voice on switching
2989        // back to this activity
2990        if (r.task.voiceInteractor != null) {
2991            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2992        } else {
2993            finishRunningVoiceLocked();
2994            IVoiceInteractionSession session;
2995            if (last != null && ((session = last.task.voiceSession) != null
2996                    || (session = last.voiceSession) != null)) {
2997                // We had been in a voice interaction session, but now focused has
2998                // move to something different.  Just finish the session, we can't
2999                // return to it and retain the proper state and synchronization with
3000                // the voice interaction service.
3001                finishVoiceTask(session);
3002            }
3003        }
3004        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3005            mWindowManager.setFocusedApp(r.appToken, true);
3006        }
3007        applyUpdateLockStateLocked(r);
3008        applyUpdateVrModeLocked(r);
3009        if (mFocusedActivity.userId != mLastFocusedUserId) {
3010            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3011            mHandler.obtainMessage(
3012                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3013            mLastFocusedUserId = mFocusedActivity.userId;
3014        }
3015
3016        // Log a warning if the focused app is changed during the process. This could
3017        // indicate a problem of the focus setting logic!
3018        if (mFocusedActivity != r) Slog.w(TAG,
3019                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3020        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3021
3022        EventLogTags.writeAmFocusedActivity(
3023                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3024                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3025                reason);
3026        return true;
3027    }
3028
3029    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3030        if (mFocusedActivity != goingAway) {
3031            return;
3032        }
3033
3034        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3035        if (focusedStack != null) {
3036            final ActivityRecord top = focusedStack.topActivity();
3037            if (top != null && top.userId != mLastFocusedUserId) {
3038                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3039                mHandler.sendMessage(
3040                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3041                mLastFocusedUserId = top.userId;
3042            }
3043        }
3044
3045        // Try to move focus to another activity if possible.
3046        if (setFocusedActivityLocked(
3047                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3048            return;
3049        }
3050
3051        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3052                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3053        mFocusedActivity = null;
3054        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3055    }
3056
3057    @Override
3058    public void setFocusedStack(int stackId) {
3059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3060        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3061        final long callingId = Binder.clearCallingIdentity();
3062        try {
3063            synchronized (this) {
3064                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3065                if (stack == null) {
3066                    return;
3067                }
3068                final ActivityRecord r = stack.topRunningActivityLocked();
3069                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3070                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3071                }
3072            }
3073        } finally {
3074            Binder.restoreCallingIdentity(callingId);
3075        }
3076    }
3077
3078    @Override
3079    public void setFocusedTask(int taskId) {
3080        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3081        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3082        final long callingId = Binder.clearCallingIdentity();
3083        try {
3084            synchronized (this) {
3085                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3086                if (task == null) {
3087                    return;
3088                }
3089                final ActivityRecord r = task.topRunningActivityLocked();
3090                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3091                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3092                }
3093            }
3094        } finally {
3095            Binder.restoreCallingIdentity(callingId);
3096        }
3097    }
3098
3099    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3100    @Override
3101    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3102        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3103        synchronized (this) {
3104            if (listener != null) {
3105                mTaskStackListeners.register(listener);
3106            }
3107        }
3108    }
3109
3110    @Override
3111    public void notifyActivityDrawn(IBinder token) {
3112        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3113        synchronized (this) {
3114            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3115            if (r != null) {
3116                r.task.stack.notifyActivityDrawnLocked(r);
3117            }
3118        }
3119    }
3120
3121    final void applyUpdateLockStateLocked(ActivityRecord r) {
3122        // Modifications to the UpdateLock state are done on our handler, outside
3123        // the activity manager's locks.  The new state is determined based on the
3124        // state *now* of the relevant activity record.  The object is passed to
3125        // the handler solely for logging detail, not to be consulted/modified.
3126        final boolean nextState = r != null && r.immersive;
3127        mHandler.sendMessage(
3128                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3129    }
3130
3131    final void applyUpdateVrModeLocked(ActivityRecord r) {
3132        mHandler.sendMessage(
3133                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3134    }
3135
3136    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3137        mHandler.sendMessage(
3138                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3139    }
3140
3141    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3142            ComponentName callingPackage, boolean immediate) {
3143        VrManagerInternal vrService =
3144                LocalServices.getService(VrManagerInternal.class);
3145        if (immediate) {
3146            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3147        } else {
3148            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3149        }
3150    }
3151
3152    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3153        Message msg = Message.obtain();
3154        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3155        msg.obj = r.task.askedCompatMode ? null : r;
3156        mUiHandler.sendMessage(msg);
3157    }
3158
3159    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3160        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3161                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3162            final Message msg = Message.obtain();
3163            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3164            msg.obj = r;
3165            mUiHandler.sendMessage(msg);
3166        }
3167    }
3168
3169    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3170            String what, Object obj, ProcessRecord srcApp) {
3171        app.lastActivityTime = now;
3172
3173        if (app.activities.size() > 0) {
3174            // Don't want to touch dependent processes that are hosting activities.
3175            return index;
3176        }
3177
3178        int lrui = mLruProcesses.lastIndexOf(app);
3179        if (lrui < 0) {
3180            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3181                    + what + " " + obj + " from " + srcApp);
3182            return index;
3183        }
3184
3185        if (lrui >= index) {
3186            // Don't want to cause this to move dependent processes *back* in the
3187            // list as if they were less frequently used.
3188            return index;
3189        }
3190
3191        if (lrui >= mLruProcessActivityStart) {
3192            // Don't want to touch dependent processes that are hosting activities.
3193            return index;
3194        }
3195
3196        mLruProcesses.remove(lrui);
3197        if (index > 0) {
3198            index--;
3199        }
3200        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3201                + " in LRU list: " + app);
3202        mLruProcesses.add(index, app);
3203        return index;
3204    }
3205
3206    static void killProcessGroup(int uid, int pid) {
3207        if (sKillHandler != null) {
3208            sKillHandler.sendMessage(
3209                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3210        } else {
3211            Slog.w(TAG, "Asked to kill process group before system bringup!");
3212            Process.killProcessGroup(uid, pid);
3213        }
3214    }
3215
3216    final void removeLruProcessLocked(ProcessRecord app) {
3217        int lrui = mLruProcesses.lastIndexOf(app);
3218        if (lrui >= 0) {
3219            if (!app.killed) {
3220                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3221                Process.killProcessQuiet(app.pid);
3222                killProcessGroup(app.uid, app.pid);
3223            }
3224            if (lrui <= mLruProcessActivityStart) {
3225                mLruProcessActivityStart--;
3226            }
3227            if (lrui <= mLruProcessServiceStart) {
3228                mLruProcessServiceStart--;
3229            }
3230            mLruProcesses.remove(lrui);
3231        }
3232    }
3233
3234    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3235            ProcessRecord client) {
3236        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3237                || app.treatLikeActivity;
3238        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3239        if (!activityChange && hasActivity) {
3240            // The process has activities, so we are only allowing activity-based adjustments
3241            // to move it.  It should be kept in the front of the list with other
3242            // processes that have activities, and we don't want those to change their
3243            // order except due to activity operations.
3244            return;
3245        }
3246
3247        mLruSeq++;
3248        final long now = SystemClock.uptimeMillis();
3249        app.lastActivityTime = now;
3250
3251        // First a quick reject: if the app is already at the position we will
3252        // put it, then there is nothing to do.
3253        if (hasActivity) {
3254            final int N = mLruProcesses.size();
3255            if (N > 0 && mLruProcesses.get(N-1) == app) {
3256                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3257                return;
3258            }
3259        } else {
3260            if (mLruProcessServiceStart > 0
3261                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3262                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3263                return;
3264            }
3265        }
3266
3267        int lrui = mLruProcesses.lastIndexOf(app);
3268
3269        if (app.persistent && lrui >= 0) {
3270            // We don't care about the position of persistent processes, as long as
3271            // they are in the list.
3272            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3273            return;
3274        }
3275
3276        /* In progress: compute new position first, so we can avoid doing work
3277           if the process is not actually going to move.  Not yet working.
3278        int addIndex;
3279        int nextIndex;
3280        boolean inActivity = false, inService = false;
3281        if (hasActivity) {
3282            // Process has activities, put it at the very tipsy-top.
3283            addIndex = mLruProcesses.size();
3284            nextIndex = mLruProcessServiceStart;
3285            inActivity = true;
3286        } else if (hasService) {
3287            // Process has services, put it at the top of the service list.
3288            addIndex = mLruProcessActivityStart;
3289            nextIndex = mLruProcessServiceStart;
3290            inActivity = true;
3291            inService = true;
3292        } else  {
3293            // Process not otherwise of interest, it goes to the top of the non-service area.
3294            addIndex = mLruProcessServiceStart;
3295            if (client != null) {
3296                int clientIndex = mLruProcesses.lastIndexOf(client);
3297                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3298                        + app);
3299                if (clientIndex >= 0 && addIndex > clientIndex) {
3300                    addIndex = clientIndex;
3301                }
3302            }
3303            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3304        }
3305
3306        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3307                + mLruProcessActivityStart + "): " + app);
3308        */
3309
3310        if (lrui >= 0) {
3311            if (lrui < mLruProcessActivityStart) {
3312                mLruProcessActivityStart--;
3313            }
3314            if (lrui < mLruProcessServiceStart) {
3315                mLruProcessServiceStart--;
3316            }
3317            /*
3318            if (addIndex > lrui) {
3319                addIndex--;
3320            }
3321            if (nextIndex > lrui) {
3322                nextIndex--;
3323            }
3324            */
3325            mLruProcesses.remove(lrui);
3326        }
3327
3328        /*
3329        mLruProcesses.add(addIndex, app);
3330        if (inActivity) {
3331            mLruProcessActivityStart++;
3332        }
3333        if (inService) {
3334            mLruProcessActivityStart++;
3335        }
3336        */
3337
3338        int nextIndex;
3339        if (hasActivity) {
3340            final int N = mLruProcesses.size();
3341            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3342                // Process doesn't have activities, but has clients with
3343                // activities...  move it up, but one below the top (the top
3344                // should always have a real activity).
3345                if (DEBUG_LRU) Slog.d(TAG_LRU,
3346                        "Adding to second-top of LRU activity list: " + app);
3347                mLruProcesses.add(N - 1, app);
3348                // To keep it from spamming the LRU list (by making a bunch of clients),
3349                // we will push down any other entries owned by the app.
3350                final int uid = app.info.uid;
3351                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3352                    ProcessRecord subProc = mLruProcesses.get(i);
3353                    if (subProc.info.uid == uid) {
3354                        // We want to push this one down the list.  If the process after
3355                        // it is for the same uid, however, don't do so, because we don't
3356                        // want them internally to be re-ordered.
3357                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3358                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3359                                    "Pushing uid " + uid + " swapping at " + i + ": "
3360                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3361                            ProcessRecord tmp = mLruProcesses.get(i);
3362                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3363                            mLruProcesses.set(i - 1, tmp);
3364                            i--;
3365                        }
3366                    } else {
3367                        // A gap, we can stop here.
3368                        break;
3369                    }
3370                }
3371            } else {
3372                // Process has activities, put it at the very tipsy-top.
3373                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3374                mLruProcesses.add(app);
3375            }
3376            nextIndex = mLruProcessServiceStart;
3377        } else if (hasService) {
3378            // Process has services, put it at the top of the service list.
3379            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3380            mLruProcesses.add(mLruProcessActivityStart, app);
3381            nextIndex = mLruProcessServiceStart;
3382            mLruProcessActivityStart++;
3383        } else  {
3384            // Process not otherwise of interest, it goes to the top of the non-service area.
3385            int index = mLruProcessServiceStart;
3386            if (client != null) {
3387                // If there is a client, don't allow the process to be moved up higher
3388                // in the list than that client.
3389                int clientIndex = mLruProcesses.lastIndexOf(client);
3390                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3391                        + " when updating " + app);
3392                if (clientIndex <= lrui) {
3393                    // Don't allow the client index restriction to push it down farther in the
3394                    // list than it already is.
3395                    clientIndex = lrui;
3396                }
3397                if (clientIndex >= 0 && index > clientIndex) {
3398                    index = clientIndex;
3399                }
3400            }
3401            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3402            mLruProcesses.add(index, app);
3403            nextIndex = index-1;
3404            mLruProcessActivityStart++;
3405            mLruProcessServiceStart++;
3406        }
3407
3408        // If the app is currently using a content provider or service,
3409        // bump those processes as well.
3410        for (int j=app.connections.size()-1; j>=0; j--) {
3411            ConnectionRecord cr = app.connections.valueAt(j);
3412            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3413                    && cr.binding.service.app != null
3414                    && cr.binding.service.app.lruSeq != mLruSeq
3415                    && !cr.binding.service.app.persistent) {
3416                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3417                        "service connection", cr, app);
3418            }
3419        }
3420        for (int j=app.conProviders.size()-1; j>=0; j--) {
3421            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3422            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3423                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3424                        "provider reference", cpr, app);
3425            }
3426        }
3427    }
3428
3429    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3430        if (uid == Process.SYSTEM_UID) {
3431            // The system gets to run in any process.  If there are multiple
3432            // processes with the same uid, just pick the first (this
3433            // should never happen).
3434            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3435            if (procs == null) return null;
3436            final int procCount = procs.size();
3437            for (int i = 0; i < procCount; i++) {
3438                final int procUid = procs.keyAt(i);
3439                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3440                    // Don't use an app process or different user process for system component.
3441                    continue;
3442                }
3443                return procs.valueAt(i);
3444            }
3445        }
3446        ProcessRecord proc = mProcessNames.get(processName, uid);
3447        if (false && proc != null && !keepIfLarge
3448                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3449                && proc.lastCachedPss >= 4000) {
3450            // Turn this condition on to cause killing to happen regularly, for testing.
3451            if (proc.baseProcessTracker != null) {
3452                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3453            }
3454            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3455        } else if (proc != null && !keepIfLarge
3456                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3457                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3458            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3459            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3460                if (proc.baseProcessTracker != null) {
3461                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3462                }
3463                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3464            }
3465        }
3466        return proc;
3467    }
3468
3469    void notifyPackageUse(String packageName, int reason) {
3470        IPackageManager pm = AppGlobals.getPackageManager();
3471        try {
3472            pm.notifyPackageUse(packageName, reason);
3473        } catch (RemoteException e) {
3474        }
3475    }
3476
3477    boolean isNextTransitionForward() {
3478        int transit = mWindowManager.getPendingAppTransition();
3479        return transit == TRANSIT_ACTIVITY_OPEN
3480                || transit == TRANSIT_TASK_OPEN
3481                || transit == TRANSIT_TASK_TO_FRONT;
3482    }
3483
3484    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3485            String processName, String abiOverride, int uid, Runnable crashHandler) {
3486        synchronized(this) {
3487            ApplicationInfo info = new ApplicationInfo();
3488            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3489            // For isolated processes, the former contains the parent's uid and the latter the
3490            // actual uid of the isolated process.
3491            // In the special case introduced by this method (which is, starting an isolated
3492            // process directly from the SystemServer without an actual parent app process) the
3493            // closest thing to a parent's uid is SYSTEM_UID.
3494            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3495            // the |isolated| logic in the ProcessRecord constructor.
3496            info.uid = Process.SYSTEM_UID;
3497            info.processName = processName;
3498            info.className = entryPoint;
3499            info.packageName = "android";
3500            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3501                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3502                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3503                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3504                    crashHandler);
3505            return proc != null ? proc.pid : 0;
3506        }
3507    }
3508
3509    final ProcessRecord startProcessLocked(String processName,
3510            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3511            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3512            boolean isolated, boolean keepIfLarge) {
3513        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3514                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3515                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3516                null /* crashHandler */);
3517    }
3518
3519    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3520            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3521            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3522            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3523        long startTime = SystemClock.elapsedRealtime();
3524        ProcessRecord app;
3525        if (!isolated) {
3526            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3527            checkTime(startTime, "startProcess: after getProcessRecord");
3528
3529            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3530                // If we are in the background, then check to see if this process
3531                // is bad.  If so, we will just silently fail.
3532                if (mAppErrors.isBadProcessLocked(info)) {
3533                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3534                            + "/" + info.processName);
3535                    return null;
3536                }
3537            } else {
3538                // When the user is explicitly starting a process, then clear its
3539                // crash count so that we won't make it bad until they see at
3540                // least one crash dialog again, and make the process good again
3541                // if it had been bad.
3542                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3543                        + "/" + info.processName);
3544                mAppErrors.resetProcessCrashTimeLocked(info);
3545                if (mAppErrors.isBadProcessLocked(info)) {
3546                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3547                            UserHandle.getUserId(info.uid), info.uid,
3548                            info.processName);
3549                    mAppErrors.clearBadProcessLocked(info);
3550                    if (app != null) {
3551                        app.bad = false;
3552                    }
3553                }
3554            }
3555        } else {
3556            // If this is an isolated process, it can't re-use an existing process.
3557            app = null;
3558        }
3559
3560        // app launch boost for big.little configurations
3561        // use cpusets to migrate freshly launched tasks to big cores
3562        nativeMigrateToBoost();
3563        mIsBoosted = true;
3564        mBoostStartTime = SystemClock.uptimeMillis();
3565        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3566        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3567
3568        // We don't have to do anything more if:
3569        // (1) There is an existing application record; and
3570        // (2) The caller doesn't think it is dead, OR there is no thread
3571        //     object attached to it so we know it couldn't have crashed; and
3572        // (3) There is a pid assigned to it, so it is either starting or
3573        //     already running.
3574        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3575                + " app=" + app + " knownToBeDead=" + knownToBeDead
3576                + " thread=" + (app != null ? app.thread : null)
3577                + " pid=" + (app != null ? app.pid : -1));
3578        if (app != null && app.pid > 0) {
3579            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3580                // We already have the app running, or are waiting for it to
3581                // come up (we have a pid but not yet its thread), so keep it.
3582                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3583                // If this is a new package in the process, add the package to the list
3584                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3585                checkTime(startTime, "startProcess: done, added package to proc");
3586                return app;
3587            }
3588
3589            // An application record is attached to a previous process,
3590            // clean it up now.
3591            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3592            checkTime(startTime, "startProcess: bad proc running, killing");
3593            killProcessGroup(app.uid, app.pid);
3594            handleAppDiedLocked(app, true, true);
3595            checkTime(startTime, "startProcess: done killing old proc");
3596        }
3597
3598        String hostingNameStr = hostingName != null
3599                ? hostingName.flattenToShortString() : null;
3600
3601        if (app == null) {
3602            checkTime(startTime, "startProcess: creating new process record");
3603            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3604            if (app == null) {
3605                Slog.w(TAG, "Failed making new process record for "
3606                        + processName + "/" + info.uid + " isolated=" + isolated);
3607                return null;
3608            }
3609            app.crashHandler = crashHandler;
3610            checkTime(startTime, "startProcess: done creating new process record");
3611        } else {
3612            // If this is a new package in the process, add the package to the list
3613            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3614            checkTime(startTime, "startProcess: added package to existing proc");
3615        }
3616
3617        // If the system is not ready yet, then hold off on starting this
3618        // process until it is.
3619        if (!mProcessesReady
3620                && !isAllowedWhileBooting(info)
3621                && !allowWhileBooting) {
3622            if (!mProcessesOnHold.contains(app)) {
3623                mProcessesOnHold.add(app);
3624            }
3625            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3626                    "System not ready, putting on hold: " + app);
3627            checkTime(startTime, "startProcess: returning with proc on hold");
3628            return app;
3629        }
3630
3631        checkTime(startTime, "startProcess: stepping in to startProcess");
3632        startProcessLocked(
3633                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3634        checkTime(startTime, "startProcess: done starting proc!");
3635        return (app.pid != 0) ? app : null;
3636    }
3637
3638    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3639        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3640    }
3641
3642    private final void startProcessLocked(ProcessRecord app,
3643            String hostingType, String hostingNameStr) {
3644        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3645                null /* entryPoint */, null /* entryPointArgs */);
3646    }
3647
3648    private final void startProcessLocked(ProcessRecord app, String hostingType,
3649            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3650        long startTime = SystemClock.elapsedRealtime();
3651        if (app.pid > 0 && app.pid != MY_PID) {
3652            checkTime(startTime, "startProcess: removing from pids map");
3653            synchronized (mPidsSelfLocked) {
3654                mPidsSelfLocked.remove(app.pid);
3655                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3656            }
3657            checkTime(startTime, "startProcess: done removing from pids map");
3658            app.setPid(0);
3659        }
3660
3661        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3662                "startProcessLocked removing on hold: " + app);
3663        mProcessesOnHold.remove(app);
3664
3665        checkTime(startTime, "startProcess: starting to update cpu stats");
3666        updateCpuStats();
3667        checkTime(startTime, "startProcess: done updating cpu stats");
3668
3669        try {
3670            try {
3671                final int userId = UserHandle.getUserId(app.uid);
3672                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3673            } catch (RemoteException e) {
3674                throw e.rethrowAsRuntimeException();
3675            }
3676
3677            int uid = app.uid;
3678            int[] gids = null;
3679            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3680            if (!app.isolated) {
3681                int[] permGids = null;
3682                try {
3683                    checkTime(startTime, "startProcess: getting gids from package manager");
3684                    final IPackageManager pm = AppGlobals.getPackageManager();
3685                    permGids = pm.getPackageGids(app.info.packageName,
3686                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3687                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3688                            MountServiceInternal.class);
3689                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3690                            app.info.packageName);
3691                } catch (RemoteException e) {
3692                    throw e.rethrowAsRuntimeException();
3693                }
3694
3695                /*
3696                 * Add shared application and profile GIDs so applications can share some
3697                 * resources like shared libraries and access user-wide resources
3698                 */
3699                if (ArrayUtils.isEmpty(permGids)) {
3700                    gids = new int[2];
3701                } else {
3702                    gids = new int[permGids.length + 2];
3703                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3704                }
3705                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3706                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3707            }
3708            checkTime(startTime, "startProcess: building args");
3709            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3710                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3711                        && mTopComponent != null
3712                        && app.processName.equals(mTopComponent.getPackageName())) {
3713                    uid = 0;
3714                }
3715                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3716                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3717                    uid = 0;
3718                }
3719            }
3720            int debugFlags = 0;
3721            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3722                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3723                // Also turn on CheckJNI for debuggable apps. It's quite
3724                // awkward to turn on otherwise.
3725                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3726            }
3727            // Run the app in safe mode if its manifest requests so or the
3728            // system is booted in safe mode.
3729            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3730                mSafeMode == true) {
3731                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3732            }
3733            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3734                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3735            }
3736            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3737            if ("true".equals(genDebugInfoProperty)) {
3738                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3739            }
3740            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3741                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3742            }
3743            if ("1".equals(SystemProperties.get("debug.assert"))) {
3744                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3745            }
3746            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3747                // Enable all debug flags required by the native debugger.
3748                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3749                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3750                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3751                mNativeDebuggingApp = null;
3752            }
3753
3754            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3755            if (requiredAbi == null) {
3756                requiredAbi = Build.SUPPORTED_ABIS[0];
3757            }
3758
3759            String instructionSet = null;
3760            if (app.info.primaryCpuAbi != null) {
3761                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3762            }
3763
3764            app.gids = gids;
3765            app.requiredAbi = requiredAbi;
3766            app.instructionSet = instructionSet;
3767
3768            // Start the process.  It will either succeed and return a result containing
3769            // the PID of the new process, or else throw a RuntimeException.
3770            boolean isActivityProcess = (entryPoint == null);
3771            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3772            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3773                    app.processName);
3774            checkTime(startTime, "startProcess: asking zygote to start proc");
3775            Process.ProcessStartResult startResult = Process.start(entryPoint,
3776                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3777                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3778                    app.info.dataDir, entryPointArgs);
3779            checkTime(startTime, "startProcess: returned from zygote!");
3780            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3781
3782            if (app.isolated) {
3783                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3784            }
3785            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3786            checkTime(startTime, "startProcess: done updating battery stats");
3787
3788            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3789                    UserHandle.getUserId(uid), startResult.pid, uid,
3790                    app.processName, hostingType,
3791                    hostingNameStr != null ? hostingNameStr : "");
3792
3793            try {
3794                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3795                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3796            } catch (RemoteException ex) {
3797                // Ignore
3798            }
3799
3800            if (app.persistent) {
3801                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3802            }
3803
3804            checkTime(startTime, "startProcess: building log message");
3805            StringBuilder buf = mStringBuilder;
3806            buf.setLength(0);
3807            buf.append("Start proc ");
3808            buf.append(startResult.pid);
3809            buf.append(':');
3810            buf.append(app.processName);
3811            buf.append('/');
3812            UserHandle.formatUid(buf, uid);
3813            if (!isActivityProcess) {
3814                buf.append(" [");
3815                buf.append(entryPoint);
3816                buf.append("]");
3817            }
3818            buf.append(" for ");
3819            buf.append(hostingType);
3820            if (hostingNameStr != null) {
3821                buf.append(" ");
3822                buf.append(hostingNameStr);
3823            }
3824            Slog.i(TAG, buf.toString());
3825            app.setPid(startResult.pid);
3826            app.usingWrapper = startResult.usingWrapper;
3827            app.removed = false;
3828            app.killed = false;
3829            app.killedByAm = false;
3830            checkTime(startTime, "startProcess: starting to update pids map");
3831            synchronized (mPidsSelfLocked) {
3832                this.mPidsSelfLocked.put(startResult.pid, app);
3833                if (isActivityProcess) {
3834                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3835                    msg.obj = app;
3836                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3837                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3838                }
3839            }
3840            checkTime(startTime, "startProcess: done updating pids map");
3841        } catch (RuntimeException e) {
3842            Slog.e(TAG, "Failure starting process " + app.processName, e);
3843
3844            // Something went very wrong while trying to start this process; one
3845            // common case is when the package is frozen due to an active
3846            // upgrade. To recover, clean up any active bookkeeping related to
3847            // starting this process. (We already invoked this method once when
3848            // the package was initially frozen through KILL_APPLICATION_MSG, so
3849            // it doesn't hurt to use it again.)
3850            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3851                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3852        }
3853    }
3854
3855    void updateUsageStats(ActivityRecord component, boolean resumed) {
3856        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3857                "updateUsageStats: comp=" + component + "res=" + resumed);
3858        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3859        if (resumed) {
3860            if (mUsageStatsService != null) {
3861                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3862                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3863            }
3864            synchronized (stats) {
3865                stats.noteActivityResumedLocked(component.app.uid);
3866            }
3867        } else {
3868            if (mUsageStatsService != null) {
3869                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3870                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3871            }
3872            synchronized (stats) {
3873                stats.noteActivityPausedLocked(component.app.uid);
3874            }
3875        }
3876    }
3877
3878    Intent getHomeIntent() {
3879        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3880        intent.setComponent(mTopComponent);
3881        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3882        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3883            intent.addCategory(Intent.CATEGORY_HOME);
3884        }
3885        return intent;
3886    }
3887
3888    boolean startHomeActivityLocked(int userId, String reason) {
3889        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3890                && mTopAction == null) {
3891            // We are running in factory test mode, but unable to find
3892            // the factory test app, so just sit around displaying the
3893            // error message and don't try to start anything.
3894            return false;
3895        }
3896        Intent intent = getHomeIntent();
3897        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3898        if (aInfo != null) {
3899            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3900            // Don't do this if the home app is currently being
3901            // instrumented.
3902            aInfo = new ActivityInfo(aInfo);
3903            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3904            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3905                    aInfo.applicationInfo.uid, true);
3906            if (app == null || app.instrumentationClass == null) {
3907                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3908                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3909            }
3910        } else {
3911            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3912        }
3913
3914        return true;
3915    }
3916
3917    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3918        ActivityInfo ai = null;
3919        ComponentName comp = intent.getComponent();
3920        try {
3921            if (comp != null) {
3922                // Factory test.
3923                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3924            } else {
3925                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3926                        intent,
3927                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3928                        flags, userId);
3929
3930                if (info != null) {
3931                    ai = info.activityInfo;
3932                }
3933            }
3934        } catch (RemoteException e) {
3935            // ignore
3936        }
3937
3938        return ai;
3939    }
3940
3941    /**
3942     * Starts the "new version setup screen" if appropriate.
3943     */
3944    void startSetupActivityLocked() {
3945        // Only do this once per boot.
3946        if (mCheckedForSetup) {
3947            return;
3948        }
3949
3950        // We will show this screen if the current one is a different
3951        // version than the last one shown, and we are not running in
3952        // low-level factory test mode.
3953        final ContentResolver resolver = mContext.getContentResolver();
3954        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3955                Settings.Global.getInt(resolver,
3956                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3957            mCheckedForSetup = true;
3958
3959            // See if we should be showing the platform update setup UI.
3960            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3961            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3962                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3963            if (!ris.isEmpty()) {
3964                final ResolveInfo ri = ris.get(0);
3965                String vers = ri.activityInfo.metaData != null
3966                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3967                        : null;
3968                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3969                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3970                            Intent.METADATA_SETUP_VERSION);
3971                }
3972                String lastVers = Settings.Secure.getString(
3973                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3974                if (vers != null && !vers.equals(lastVers)) {
3975                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3976                    intent.setComponent(new ComponentName(
3977                            ri.activityInfo.packageName, ri.activityInfo.name));
3978                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3979                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3980                            null, 0, 0, 0, null, false, false, null, null, null);
3981                }
3982            }
3983        }
3984    }
3985
3986    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3987        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3988    }
3989
3990    void enforceNotIsolatedCaller(String caller) {
3991        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3992            throw new SecurityException("Isolated process not allowed to call " + caller);
3993        }
3994    }
3995
3996    void enforceShellRestriction(String restriction, int userHandle) {
3997        if (Binder.getCallingUid() == Process.SHELL_UID) {
3998            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3999                throw new SecurityException("Shell does not have permission to access user "
4000                        + userHandle);
4001            }
4002        }
4003    }
4004
4005    @Override
4006    public int getFrontActivityScreenCompatMode() {
4007        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4008        synchronized (this) {
4009            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4010        }
4011    }
4012
4013    @Override
4014    public void setFrontActivityScreenCompatMode(int mode) {
4015        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4016                "setFrontActivityScreenCompatMode");
4017        synchronized (this) {
4018            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4019        }
4020    }
4021
4022    @Override
4023    public int getPackageScreenCompatMode(String packageName) {
4024        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4025        synchronized (this) {
4026            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4027        }
4028    }
4029
4030    @Override
4031    public void setPackageScreenCompatMode(String packageName, int mode) {
4032        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4033                "setPackageScreenCompatMode");
4034        synchronized (this) {
4035            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4036        }
4037    }
4038
4039    @Override
4040    public boolean getPackageAskScreenCompat(String packageName) {
4041        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4042        synchronized (this) {
4043            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4044        }
4045    }
4046
4047    @Override
4048    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4049        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4050                "setPackageAskScreenCompat");
4051        synchronized (this) {
4052            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4053        }
4054    }
4055
4056    private boolean hasUsageStatsPermission(String callingPackage) {
4057        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4058                Binder.getCallingUid(), callingPackage);
4059        if (mode == AppOpsManager.MODE_DEFAULT) {
4060            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4061                    == PackageManager.PERMISSION_GRANTED;
4062        }
4063        return mode == AppOpsManager.MODE_ALLOWED;
4064    }
4065
4066    @Override
4067    public int getPackageProcessState(String packageName, String callingPackage) {
4068        if (!hasUsageStatsPermission(callingPackage)) {
4069            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4070                    "getPackageProcessState");
4071        }
4072
4073        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4074        synchronized (this) {
4075            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4076                final ProcessRecord proc = mLruProcesses.get(i);
4077                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4078                        || procState > proc.setProcState) {
4079                    boolean found = false;
4080                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4081                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4082                            procState = proc.setProcState;
4083                            found = true;
4084                        }
4085                    }
4086                    if (proc.pkgDeps != null && !found) {
4087                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4088                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4089                                procState = proc.setProcState;
4090                                break;
4091                            }
4092                        }
4093                    }
4094                }
4095            }
4096        }
4097        return procState;
4098    }
4099
4100    @Override
4101    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4102        synchronized (this) {
4103            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4104            if (app == null) {
4105                return false;
4106            }
4107            if (app.trimMemoryLevel < level && app.thread != null &&
4108                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4109                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4110                try {
4111                    app.thread.scheduleTrimMemory(level);
4112                    app.trimMemoryLevel = level;
4113                    return true;
4114                } catch (RemoteException e) {
4115                    // Fallthrough to failure case.
4116                }
4117            }
4118        }
4119        return false;
4120    }
4121
4122    private void dispatchProcessesChanged() {
4123        int N;
4124        synchronized (this) {
4125            N = mPendingProcessChanges.size();
4126            if (mActiveProcessChanges.length < N) {
4127                mActiveProcessChanges = new ProcessChangeItem[N];
4128            }
4129            mPendingProcessChanges.toArray(mActiveProcessChanges);
4130            mPendingProcessChanges.clear();
4131            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4132                    "*** Delivering " + N + " process changes");
4133        }
4134
4135        int i = mProcessObservers.beginBroadcast();
4136        while (i > 0) {
4137            i--;
4138            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4139            if (observer != null) {
4140                try {
4141                    for (int j=0; j<N; j++) {
4142                        ProcessChangeItem item = mActiveProcessChanges[j];
4143                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4144                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4145                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4146                                    + item.uid + ": " + item.foregroundActivities);
4147                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4148                                    item.foregroundActivities);
4149                        }
4150                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4151                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4152                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4153                                    + ": " + item.processState);
4154                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4155                        }
4156                    }
4157                } catch (RemoteException e) {
4158                }
4159            }
4160        }
4161        mProcessObservers.finishBroadcast();
4162
4163        synchronized (this) {
4164            for (int j=0; j<N; j++) {
4165                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4166            }
4167        }
4168    }
4169
4170    private void dispatchProcessDied(int pid, int uid) {
4171        int i = mProcessObservers.beginBroadcast();
4172        while (i > 0) {
4173            i--;
4174            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4175            if (observer != null) {
4176                try {
4177                    observer.onProcessDied(pid, uid);
4178                } catch (RemoteException e) {
4179                }
4180            }
4181        }
4182        mProcessObservers.finishBroadcast();
4183    }
4184
4185    private void dispatchUidsChanged() {
4186        int N;
4187        synchronized (this) {
4188            N = mPendingUidChanges.size();
4189            if (mActiveUidChanges.length < N) {
4190                mActiveUidChanges = new UidRecord.ChangeItem[N];
4191            }
4192            for (int i=0; i<N; i++) {
4193                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4194                mActiveUidChanges[i] = change;
4195                if (change.uidRecord != null) {
4196                    change.uidRecord.pendingChange = null;
4197                    change.uidRecord = null;
4198                }
4199            }
4200            mPendingUidChanges.clear();
4201            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4202                    "*** Delivering " + N + " uid changes");
4203        }
4204
4205        if (mLocalPowerManager != null) {
4206            for (int j=0; j<N; j++) {
4207                UidRecord.ChangeItem item = mActiveUidChanges[j];
4208                if (item.change == UidRecord.CHANGE_GONE
4209                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4210                    mLocalPowerManager.uidGone(item.uid);
4211                } else {
4212                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4213                }
4214            }
4215        }
4216
4217        int i = mUidObservers.beginBroadcast();
4218        while (i > 0) {
4219            i--;
4220            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4221            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4222            if (observer != null) {
4223                try {
4224                    for (int j=0; j<N; j++) {
4225                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4226                        final int change = item.change;
4227                        UidRecord validateUid = null;
4228                        if (VALIDATE_UID_STATES && i == 0) {
4229                            validateUid = mValidateUids.get(item.uid);
4230                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4231                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4232                                validateUid = new UidRecord(item.uid);
4233                                mValidateUids.put(item.uid, validateUid);
4234                            }
4235                        }
4236                        if (change == UidRecord.CHANGE_IDLE
4237                                || change == UidRecord.CHANGE_GONE_IDLE) {
4238                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4239                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4240                                        "UID idle uid=" + item.uid);
4241                                observer.onUidIdle(item.uid);
4242                            }
4243                            if (VALIDATE_UID_STATES && i == 0) {
4244                                if (validateUid != null) {
4245                                    validateUid.idle = true;
4246                                }
4247                            }
4248                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4249                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4250                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4251                                        "UID active uid=" + item.uid);
4252                                observer.onUidActive(item.uid);
4253                            }
4254                            if (VALIDATE_UID_STATES && i == 0) {
4255                                validateUid.idle = false;
4256                            }
4257                        }
4258                        if (change == UidRecord.CHANGE_GONE
4259                                || change == UidRecord.CHANGE_GONE_IDLE) {
4260                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4261                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4262                                        "UID gone uid=" + item.uid);
4263                                observer.onUidGone(item.uid);
4264                            }
4265                            if (VALIDATE_UID_STATES && i == 0) {
4266                                if (validateUid != null) {
4267                                    mValidateUids.remove(item.uid);
4268                                }
4269                            }
4270                        } else {
4271                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4272                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4273                                        "UID CHANGED uid=" + item.uid
4274                                                + ": " + item.processState);
4275                                observer.onUidStateChanged(item.uid, item.processState);
4276                            }
4277                            if (VALIDATE_UID_STATES && i == 0) {
4278                                validateUid.curProcState = validateUid.setProcState
4279                                        = item.processState;
4280                            }
4281                        }
4282                    }
4283                } catch (RemoteException e) {
4284                }
4285            }
4286        }
4287        mUidObservers.finishBroadcast();
4288
4289        synchronized (this) {
4290            for (int j=0; j<N; j++) {
4291                mAvailUidChanges.add(mActiveUidChanges[j]);
4292            }
4293        }
4294    }
4295
4296    @Override
4297    public final int startActivity(IApplicationThread caller, String callingPackage,
4298            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4299            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4300        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4301                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4302                UserHandle.getCallingUserId());
4303    }
4304
4305    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4306        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4307        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4308                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4309                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4310
4311        // TODO: Switch to user app stacks here.
4312        String mimeType = intent.getType();
4313        final Uri data = intent.getData();
4314        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4315            mimeType = getProviderMimeType(data, userId);
4316        }
4317        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4318
4319        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4320        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4321                null, 0, 0, null, null, null, null, false, userId, container, null);
4322    }
4323
4324    @Override
4325    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4326            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4327            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4328        enforceNotIsolatedCaller("startActivity");
4329        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4330                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4331        // TODO: Switch to user app stacks here.
4332        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4333                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4334                profilerInfo, null, null, bOptions, false, userId, null, null);
4335    }
4336
4337    @Override
4338    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4339            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4340            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4341            int userId) {
4342
4343        // This is very dangerous -- it allows you to perform a start activity (including
4344        // permission grants) as any app that may launch one of your own activities.  So
4345        // we will only allow this to be done from activities that are part of the core framework,
4346        // and then only when they are running as the system.
4347        final ActivityRecord sourceRecord;
4348        final int targetUid;
4349        final String targetPackage;
4350        synchronized (this) {
4351            if (resultTo == null) {
4352                throw new SecurityException("Must be called from an activity");
4353            }
4354            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4355            if (sourceRecord == null) {
4356                throw new SecurityException("Called with bad activity token: " + resultTo);
4357            }
4358            if (!sourceRecord.info.packageName.equals("android")) {
4359                throw new SecurityException(
4360                        "Must be called from an activity that is declared in the android package");
4361            }
4362            if (sourceRecord.app == null) {
4363                throw new SecurityException("Called without a process attached to activity");
4364            }
4365            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4366                // This is still okay, as long as this activity is running under the
4367                // uid of the original calling activity.
4368                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4369                    throw new SecurityException(
4370                            "Calling activity in uid " + sourceRecord.app.uid
4371                                    + " must be system uid or original calling uid "
4372                                    + sourceRecord.launchedFromUid);
4373                }
4374            }
4375            if (ignoreTargetSecurity) {
4376                if (intent.getComponent() == null) {
4377                    throw new SecurityException(
4378                            "Component must be specified with ignoreTargetSecurity");
4379                }
4380                if (intent.getSelector() != null) {
4381                    throw new SecurityException(
4382                            "Selector not allowed with ignoreTargetSecurity");
4383                }
4384            }
4385            targetUid = sourceRecord.launchedFromUid;
4386            targetPackage = sourceRecord.launchedFromPackage;
4387        }
4388
4389        if (userId == UserHandle.USER_NULL) {
4390            userId = UserHandle.getUserId(sourceRecord.app.uid);
4391        }
4392
4393        // TODO: Switch to user app stacks here.
4394        try {
4395            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4396                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4397                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4398            return ret;
4399        } catch (SecurityException e) {
4400            // XXX need to figure out how to propagate to original app.
4401            // A SecurityException here is generally actually a fault of the original
4402            // calling activity (such as a fairly granting permissions), so propagate it
4403            // back to them.
4404            /*
4405            StringBuilder msg = new StringBuilder();
4406            msg.append("While launching");
4407            msg.append(intent.toString());
4408            msg.append(": ");
4409            msg.append(e.getMessage());
4410            */
4411            throw e;
4412        }
4413    }
4414
4415    @Override
4416    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4417            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4418            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4419        enforceNotIsolatedCaller("startActivityAndWait");
4420        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4421                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4422        WaitResult res = new WaitResult();
4423        // TODO: Switch to user app stacks here.
4424        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4425                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4426                bOptions, false, userId, null, null);
4427        return res;
4428    }
4429
4430    @Override
4431    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4432            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4433            int startFlags, Configuration config, Bundle bOptions, int userId) {
4434        enforceNotIsolatedCaller("startActivityWithConfig");
4435        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4436                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4437        // TODO: Switch to user app stacks here.
4438        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4439                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4440                null, null, config, bOptions, false, userId, null, null);
4441        return ret;
4442    }
4443
4444    @Override
4445    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4446            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4447            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4448            throws TransactionTooLargeException {
4449        enforceNotIsolatedCaller("startActivityIntentSender");
4450        // Refuse possible leaked file descriptors
4451        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4452            throw new IllegalArgumentException("File descriptors passed in Intent");
4453        }
4454
4455        IIntentSender sender = intent.getTarget();
4456        if (!(sender instanceof PendingIntentRecord)) {
4457            throw new IllegalArgumentException("Bad PendingIntent object");
4458        }
4459
4460        PendingIntentRecord pir = (PendingIntentRecord)sender;
4461
4462        synchronized (this) {
4463            // If this is coming from the currently resumed activity, it is
4464            // effectively saying that app switches are allowed at this point.
4465            final ActivityStack stack = getFocusedStack();
4466            if (stack.mResumedActivity != null &&
4467                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4468                mAppSwitchesAllowedTime = 0;
4469            }
4470        }
4471        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4472                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4473        return ret;
4474    }
4475
4476    @Override
4477    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4478            Intent intent, String resolvedType, IVoiceInteractionSession session,
4479            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4480            Bundle bOptions, int userId) {
4481        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4482                != PackageManager.PERMISSION_GRANTED) {
4483            String msg = "Permission Denial: startVoiceActivity() from pid="
4484                    + Binder.getCallingPid()
4485                    + ", uid=" + Binder.getCallingUid()
4486                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4487            Slog.w(TAG, msg);
4488            throw new SecurityException(msg);
4489        }
4490        if (session == null || interactor == null) {
4491            throw new NullPointerException("null session or interactor");
4492        }
4493        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4494                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4495        // TODO: Switch to user app stacks here.
4496        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4497                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4498                null, bOptions, false, userId, null, null);
4499    }
4500
4501    @Override
4502    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4503            throws RemoteException {
4504        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4505        synchronized (this) {
4506            ActivityRecord activity = getFocusedStack().topActivity();
4507            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4508                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4509            }
4510            if (mRunningVoice != null || activity.task.voiceSession != null
4511                    || activity.voiceSession != null) {
4512                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4513                return;
4514            }
4515            if (activity.pendingVoiceInteractionStart) {
4516                Slog.w(TAG, "Pending start of voice interaction already.");
4517                return;
4518            }
4519            activity.pendingVoiceInteractionStart = true;
4520        }
4521        LocalServices.getService(VoiceInteractionManagerInternal.class)
4522                .startLocalVoiceInteraction(callingActivity, options);
4523    }
4524
4525    @Override
4526    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4527        LocalServices.getService(VoiceInteractionManagerInternal.class)
4528                .stopLocalVoiceInteraction(callingActivity);
4529    }
4530
4531    @Override
4532    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4533        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4534                .supportsLocalVoiceInteraction();
4535    }
4536
4537    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4538            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4539        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4540        if (activityToCallback == null) return;
4541        activityToCallback.setVoiceSessionLocked(voiceSession);
4542
4543        // Inform the activity
4544        try {
4545            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4546                    voiceInteractor);
4547            long token = Binder.clearCallingIdentity();
4548            try {
4549                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4550            } finally {
4551                Binder.restoreCallingIdentity(token);
4552            }
4553            // TODO: VI Should we cache the activity so that it's easier to find later
4554            // rather than scan through all the stacks and activities?
4555        } catch (RemoteException re) {
4556            activityToCallback.clearVoiceSessionLocked();
4557            // TODO: VI Should this terminate the voice session?
4558        }
4559    }
4560
4561    @Override
4562    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4563        synchronized (this) {
4564            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4565                if (keepAwake) {
4566                    mVoiceWakeLock.acquire();
4567                } else {
4568                    mVoiceWakeLock.release();
4569                }
4570            }
4571        }
4572    }
4573
4574    @Override
4575    public boolean startNextMatchingActivity(IBinder callingActivity,
4576            Intent intent, Bundle bOptions) {
4577        // Refuse possible leaked file descriptors
4578        if (intent != null && intent.hasFileDescriptors() == true) {
4579            throw new IllegalArgumentException("File descriptors passed in Intent");
4580        }
4581        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4582
4583        synchronized (this) {
4584            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4585            if (r == null) {
4586                ActivityOptions.abort(options);
4587                return false;
4588            }
4589            if (r.app == null || r.app.thread == null) {
4590                // The caller is not running...  d'oh!
4591                ActivityOptions.abort(options);
4592                return false;
4593            }
4594            intent = new Intent(intent);
4595            // The caller is not allowed to change the data.
4596            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4597            // And we are resetting to find the next component...
4598            intent.setComponent(null);
4599
4600            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4601
4602            ActivityInfo aInfo = null;
4603            try {
4604                List<ResolveInfo> resolves =
4605                    AppGlobals.getPackageManager().queryIntentActivities(
4606                            intent, r.resolvedType,
4607                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4608                            UserHandle.getCallingUserId()).getList();
4609
4610                // Look for the original activity in the list...
4611                final int N = resolves != null ? resolves.size() : 0;
4612                for (int i=0; i<N; i++) {
4613                    ResolveInfo rInfo = resolves.get(i);
4614                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4615                            && rInfo.activityInfo.name.equals(r.info.name)) {
4616                        // We found the current one...  the next matching is
4617                        // after it.
4618                        i++;
4619                        if (i<N) {
4620                            aInfo = resolves.get(i).activityInfo;
4621                        }
4622                        if (debug) {
4623                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4624                                    + "/" + r.info.name);
4625                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4626                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4627                        }
4628                        break;
4629                    }
4630                }
4631            } catch (RemoteException e) {
4632            }
4633
4634            if (aInfo == null) {
4635                // Nobody who is next!
4636                ActivityOptions.abort(options);
4637                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4638                return false;
4639            }
4640
4641            intent.setComponent(new ComponentName(
4642                    aInfo.applicationInfo.packageName, aInfo.name));
4643            intent.setFlags(intent.getFlags()&~(
4644                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4645                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4646                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4647                    Intent.FLAG_ACTIVITY_NEW_TASK));
4648
4649            // Okay now we need to start the new activity, replacing the
4650            // currently running activity.  This is a little tricky because
4651            // we want to start the new one as if the current one is finished,
4652            // but not finish the current one first so that there is no flicker.
4653            // And thus...
4654            final boolean wasFinishing = r.finishing;
4655            r.finishing = true;
4656
4657            // Propagate reply information over to the new activity.
4658            final ActivityRecord resultTo = r.resultTo;
4659            final String resultWho = r.resultWho;
4660            final int requestCode = r.requestCode;
4661            r.resultTo = null;
4662            if (resultTo != null) {
4663                resultTo.removeResultsLocked(r, resultWho, requestCode);
4664            }
4665
4666            final long origId = Binder.clearCallingIdentity();
4667            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4668                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4669                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4670                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4671                    false, false, null, null, null);
4672            Binder.restoreCallingIdentity(origId);
4673
4674            r.finishing = wasFinishing;
4675            if (res != ActivityManager.START_SUCCESS) {
4676                return false;
4677            }
4678            return true;
4679        }
4680    }
4681
4682    @Override
4683    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4684        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4685            String msg = "Permission Denial: startActivityFromRecents called without " +
4686                    START_TASKS_FROM_RECENTS;
4687            Slog.w(TAG, msg);
4688            throw new SecurityException(msg);
4689        }
4690        final long origId = Binder.clearCallingIdentity();
4691        try {
4692            synchronized (this) {
4693                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4694            }
4695        } finally {
4696            Binder.restoreCallingIdentity(origId);
4697        }
4698    }
4699
4700    final int startActivityInPackage(int uid, String callingPackage,
4701            Intent intent, String resolvedType, IBinder resultTo,
4702            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4703            IActivityContainer container, TaskRecord inTask) {
4704
4705        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4706                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4707
4708        // TODO: Switch to user app stacks here.
4709        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4710                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4711                null, null, null, bOptions, false, userId, container, inTask);
4712        return ret;
4713    }
4714
4715    @Override
4716    public final int startActivities(IApplicationThread caller, String callingPackage,
4717            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4718            int userId) {
4719        enforceNotIsolatedCaller("startActivities");
4720        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4721                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4722        // TODO: Switch to user app stacks here.
4723        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4724                resolvedTypes, resultTo, bOptions, userId);
4725        return ret;
4726    }
4727
4728    final int startActivitiesInPackage(int uid, String callingPackage,
4729            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4730            Bundle bOptions, int userId) {
4731
4732        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4733                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4734        // TODO: Switch to user app stacks here.
4735        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4736                resultTo, bOptions, userId);
4737        return ret;
4738    }
4739
4740    @Override
4741    public void reportActivityFullyDrawn(IBinder token) {
4742        synchronized (this) {
4743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4744            if (r == null) {
4745                return;
4746            }
4747            r.reportFullyDrawnLocked();
4748        }
4749    }
4750
4751    @Override
4752    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4753        synchronized (this) {
4754            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4755            if (r == null) {
4756                return;
4757            }
4758            TaskRecord task = r.task;
4759            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4760                // Fixed screen orientation isn't supported when activities aren't in full screen
4761                // mode.
4762                return;
4763            }
4764            final long origId = Binder.clearCallingIdentity();
4765            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4766            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4767                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4768            if (config != null) {
4769                r.frozenBeforeDestroy = true;
4770                if (!updateConfigurationLocked(config, r, false)) {
4771                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4772                }
4773            }
4774            Binder.restoreCallingIdentity(origId);
4775        }
4776    }
4777
4778    @Override
4779    public int getRequestedOrientation(IBinder token) {
4780        synchronized (this) {
4781            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4782            if (r == null) {
4783                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4784            }
4785            return mWindowManager.getAppOrientation(r.appToken);
4786        }
4787    }
4788
4789    /**
4790     * This is the internal entry point for handling Activity.finish().
4791     *
4792     * @param token The Binder token referencing the Activity we want to finish.
4793     * @param resultCode Result code, if any, from this Activity.
4794     * @param resultData Result data (Intent), if any, from this Activity.
4795     * @param finishTask Whether to finish the task associated with this Activity.
4796     *
4797     * @return Returns true if the activity successfully finished, or false if it is still running.
4798     */
4799    @Override
4800    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4801            int finishTask) {
4802        // Refuse possible leaked file descriptors
4803        if (resultData != null && resultData.hasFileDescriptors() == true) {
4804            throw new IllegalArgumentException("File descriptors passed in Intent");
4805        }
4806
4807        synchronized(this) {
4808            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4809            if (r == null) {
4810                return true;
4811            }
4812            // Keep track of the root activity of the task before we finish it
4813            TaskRecord tr = r.task;
4814            ActivityRecord rootR = tr.getRootActivity();
4815            if (rootR == null) {
4816                Slog.w(TAG, "Finishing task with all activities already finished");
4817            }
4818            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4819            // finish.
4820            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4821                    mStackSupervisor.isLastLockedTask(tr)) {
4822                Slog.i(TAG, "Not finishing task in lock task mode");
4823                mStackSupervisor.showLockTaskToast();
4824                return false;
4825            }
4826            if (mController != null) {
4827                // Find the first activity that is not finishing.
4828                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4829                if (next != null) {
4830                    // ask watcher if this is allowed
4831                    boolean resumeOK = true;
4832                    try {
4833                        resumeOK = mController.activityResuming(next.packageName);
4834                    } catch (RemoteException e) {
4835                        mController = null;
4836                        Watchdog.getInstance().setActivityController(null);
4837                    }
4838
4839                    if (!resumeOK) {
4840                        Slog.i(TAG, "Not finishing activity because controller resumed");
4841                        return false;
4842                    }
4843                }
4844            }
4845            final long origId = Binder.clearCallingIdentity();
4846            try {
4847                boolean res;
4848                final boolean finishWithRootActivity =
4849                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4850                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4851                        || (finishWithRootActivity && r == rootR)) {
4852                    // If requested, remove the task that is associated to this activity only if it
4853                    // was the root activity in the task. The result code and data is ignored
4854                    // because we don't support returning them across task boundaries. Also, to
4855                    // keep backwards compatibility we remove the task from recents when finishing
4856                    // task with root activity.
4857                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4858                    if (!res) {
4859                        Slog.i(TAG, "Removing task failed to finish activity");
4860                    }
4861                } else {
4862                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4863                            resultData, "app-request", true);
4864                    if (!res) {
4865                        Slog.i(TAG, "Failed to finish by app-request");
4866                    }
4867                }
4868                return res;
4869            } finally {
4870                Binder.restoreCallingIdentity(origId);
4871            }
4872        }
4873    }
4874
4875    @Override
4876    public final void finishHeavyWeightApp() {
4877        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4878                != PackageManager.PERMISSION_GRANTED) {
4879            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4880                    + Binder.getCallingPid()
4881                    + ", uid=" + Binder.getCallingUid()
4882                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4883            Slog.w(TAG, msg);
4884            throw new SecurityException(msg);
4885        }
4886
4887        synchronized(this) {
4888            if (mHeavyWeightProcess == null) {
4889                return;
4890            }
4891
4892            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4893            for (int i = 0; i < activities.size(); i++) {
4894                ActivityRecord r = activities.get(i);
4895                if (!r.finishing && r.isInStackLocked()) {
4896                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4897                            null, "finish-heavy", true);
4898                }
4899            }
4900
4901            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4902                    mHeavyWeightProcess.userId, 0));
4903            mHeavyWeightProcess = null;
4904        }
4905    }
4906
4907    @Override
4908    public void crashApplication(int uid, int initialPid, String packageName,
4909            String message) {
4910        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4911                != PackageManager.PERMISSION_GRANTED) {
4912            String msg = "Permission Denial: crashApplication() from pid="
4913                    + Binder.getCallingPid()
4914                    + ", uid=" + Binder.getCallingUid()
4915                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4916            Slog.w(TAG, msg);
4917            throw new SecurityException(msg);
4918        }
4919
4920        synchronized(this) {
4921            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4922        }
4923    }
4924
4925    @Override
4926    public final void finishSubActivity(IBinder token, String resultWho,
4927            int requestCode) {
4928        synchronized(this) {
4929            final long origId = Binder.clearCallingIdentity();
4930            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4931            if (r != null) {
4932                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4933            }
4934            Binder.restoreCallingIdentity(origId);
4935        }
4936    }
4937
4938    @Override
4939    public boolean finishActivityAffinity(IBinder token) {
4940        synchronized(this) {
4941            final long origId = Binder.clearCallingIdentity();
4942            try {
4943                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4944                if (r == null) {
4945                    return false;
4946                }
4947
4948                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4949                // can finish.
4950                final TaskRecord task = r.task;
4951                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4952                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4953                    mStackSupervisor.showLockTaskToast();
4954                    return false;
4955                }
4956                return task.stack.finishActivityAffinityLocked(r);
4957            } finally {
4958                Binder.restoreCallingIdentity(origId);
4959            }
4960        }
4961    }
4962
4963    @Override
4964    public void finishVoiceTask(IVoiceInteractionSession session) {
4965        synchronized (this) {
4966            final long origId = Binder.clearCallingIdentity();
4967            try {
4968                // TODO: VI Consider treating local voice interactions and voice tasks
4969                // differently here
4970                mStackSupervisor.finishVoiceTask(session);
4971            } finally {
4972                Binder.restoreCallingIdentity(origId);
4973            }
4974        }
4975
4976    }
4977
4978    @Override
4979    public boolean releaseActivityInstance(IBinder token) {
4980        synchronized(this) {
4981            final long origId = Binder.clearCallingIdentity();
4982            try {
4983                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984                if (r == null) {
4985                    return false;
4986                }
4987                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4988            } finally {
4989                Binder.restoreCallingIdentity(origId);
4990            }
4991        }
4992    }
4993
4994    @Override
4995    public void releaseSomeActivities(IApplicationThread appInt) {
4996        synchronized(this) {
4997            final long origId = Binder.clearCallingIdentity();
4998            try {
4999                ProcessRecord app = getRecordForAppLocked(appInt);
5000                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5001            } finally {
5002                Binder.restoreCallingIdentity(origId);
5003            }
5004        }
5005    }
5006
5007    @Override
5008    public boolean willActivityBeVisible(IBinder token) {
5009        synchronized(this) {
5010            ActivityStack stack = ActivityRecord.getStackLocked(token);
5011            if (stack != null) {
5012                return stack.willActivityBeVisibleLocked(token);
5013            }
5014            return false;
5015        }
5016    }
5017
5018    @Override
5019    public void overridePendingTransition(IBinder token, String packageName,
5020            int enterAnim, int exitAnim) {
5021        synchronized(this) {
5022            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5023            if (self == null) {
5024                return;
5025            }
5026
5027            final long origId = Binder.clearCallingIdentity();
5028
5029            if (self.state == ActivityState.RESUMED
5030                    || self.state == ActivityState.PAUSING) {
5031                mWindowManager.overridePendingAppTransition(packageName,
5032                        enterAnim, exitAnim, null);
5033            }
5034
5035            Binder.restoreCallingIdentity(origId);
5036        }
5037    }
5038
5039    /**
5040     * Main function for removing an existing process from the activity manager
5041     * as a result of that process going away.  Clears out all connections
5042     * to the process.
5043     */
5044    private final void handleAppDiedLocked(ProcessRecord app,
5045            boolean restarting, boolean allowRestart) {
5046        int pid = app.pid;
5047        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5048        if (!kept && !restarting) {
5049            removeLruProcessLocked(app);
5050            if (pid > 0) {
5051                ProcessList.remove(pid);
5052            }
5053        }
5054
5055        if (mProfileProc == app) {
5056            clearProfilerLocked();
5057        }
5058
5059        // Remove this application's activities from active lists.
5060        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5061
5062        app.activities.clear();
5063
5064        if (app.instrumentationClass != null) {
5065            Slog.w(TAG, "Crash of app " + app.processName
5066                  + " running instrumentation " + app.instrumentationClass);
5067            Bundle info = new Bundle();
5068            info.putString("shortMsg", "Process crashed.");
5069            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5070        }
5071
5072        if (!restarting && hasVisibleActivities
5073                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5074            // If there was nothing to resume, and we are not already restarting this process, but
5075            // there is a visible activity that is hosted by the process...  then make sure all
5076            // visible activities are running, taking care of restarting this process.
5077            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5078        }
5079    }
5080
5081    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5082        IBinder threadBinder = thread.asBinder();
5083        // Find the application record.
5084        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5085            ProcessRecord rec = mLruProcesses.get(i);
5086            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5087                return i;
5088            }
5089        }
5090        return -1;
5091    }
5092
5093    final ProcessRecord getRecordForAppLocked(
5094            IApplicationThread thread) {
5095        if (thread == null) {
5096            return null;
5097        }
5098
5099        int appIndex = getLRURecordIndexForAppLocked(thread);
5100        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5101    }
5102
5103    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5104        // If there are no longer any background processes running,
5105        // and the app that died was not running instrumentation,
5106        // then tell everyone we are now low on memory.
5107        boolean haveBg = false;
5108        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5109            ProcessRecord rec = mLruProcesses.get(i);
5110            if (rec.thread != null
5111                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5112                haveBg = true;
5113                break;
5114            }
5115        }
5116
5117        if (!haveBg) {
5118            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5119            if (doReport) {
5120                long now = SystemClock.uptimeMillis();
5121                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5122                    doReport = false;
5123                } else {
5124                    mLastMemUsageReportTime = now;
5125                }
5126            }
5127            final ArrayList<ProcessMemInfo> memInfos
5128                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5129            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5130            long now = SystemClock.uptimeMillis();
5131            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5132                ProcessRecord rec = mLruProcesses.get(i);
5133                if (rec == dyingProc || rec.thread == null) {
5134                    continue;
5135                }
5136                if (doReport) {
5137                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5138                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5139                }
5140                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5141                    // The low memory report is overriding any current
5142                    // state for a GC request.  Make sure to do
5143                    // heavy/important/visible/foreground processes first.
5144                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5145                        rec.lastRequestedGc = 0;
5146                    } else {
5147                        rec.lastRequestedGc = rec.lastLowMemory;
5148                    }
5149                    rec.reportLowMemory = true;
5150                    rec.lastLowMemory = now;
5151                    mProcessesToGc.remove(rec);
5152                    addProcessToGcListLocked(rec);
5153                }
5154            }
5155            if (doReport) {
5156                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5157                mHandler.sendMessage(msg);
5158            }
5159            scheduleAppGcsLocked();
5160        }
5161    }
5162
5163    final void appDiedLocked(ProcessRecord app) {
5164       appDiedLocked(app, app.pid, app.thread, false);
5165    }
5166
5167    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5168            boolean fromBinderDied) {
5169        // First check if this ProcessRecord is actually active for the pid.
5170        synchronized (mPidsSelfLocked) {
5171            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5172            if (curProc != app) {
5173                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5174                return;
5175            }
5176        }
5177
5178        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5179        synchronized (stats) {
5180            stats.noteProcessDiedLocked(app.info.uid, pid);
5181        }
5182
5183        if (!app.killed) {
5184            if (!fromBinderDied) {
5185                Process.killProcessQuiet(pid);
5186            }
5187            killProcessGroup(app.uid, pid);
5188            app.killed = true;
5189        }
5190
5191        // Clean up already done if the process has been re-started.
5192        if (app.pid == pid && app.thread != null &&
5193                app.thread.asBinder() == thread.asBinder()) {
5194            boolean doLowMem = app.instrumentationClass == null;
5195            boolean doOomAdj = doLowMem;
5196            if (!app.killedByAm) {
5197                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5198                        + ") has died");
5199                mAllowLowerMemLevel = true;
5200            } else {
5201                // Note that we always want to do oom adj to update our state with the
5202                // new number of procs.
5203                mAllowLowerMemLevel = false;
5204                doLowMem = false;
5205            }
5206            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5207            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5208                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5209            handleAppDiedLocked(app, false, true);
5210
5211            if (doOomAdj) {
5212                updateOomAdjLocked();
5213            }
5214            if (doLowMem) {
5215                doLowMemReportIfNeededLocked(app);
5216            }
5217        } else if (app.pid != pid) {
5218            // A new process has already been started.
5219            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5220                    + ") has died and restarted (pid " + app.pid + ").");
5221            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5222        } else if (DEBUG_PROCESSES) {
5223            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5224                    + thread.asBinder());
5225        }
5226    }
5227
5228    /**
5229     * If a stack trace dump file is configured, dump process stack traces.
5230     * @param clearTraces causes the dump file to be erased prior to the new
5231     *    traces being written, if true; when false, the new traces will be
5232     *    appended to any existing file content.
5233     * @param firstPids of dalvik VM processes to dump stack traces for first
5234     * @param lastPids of dalvik VM processes to dump stack traces for last
5235     * @param nativeProcs optional list of native process names to dump stack crawls
5236     * @return file containing stack traces, or null if no dump file is configured
5237     */
5238    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5239            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5240        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5241        if (tracesPath == null || tracesPath.length() == 0) {
5242            return null;
5243        }
5244
5245        File tracesFile = new File(tracesPath);
5246        try {
5247            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5248            tracesFile.createNewFile();
5249            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5250        } catch (IOException e) {
5251            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5252            return null;
5253        }
5254
5255        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5256        return tracesFile;
5257    }
5258
5259    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5260            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5261        // Use a FileObserver to detect when traces finish writing.
5262        // The order of traces is considered important to maintain for legibility.
5263        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5264            @Override
5265            public synchronized void onEvent(int event, String path) { notify(); }
5266        };
5267
5268        try {
5269            observer.startWatching();
5270
5271            // First collect all of the stacks of the most important pids.
5272            if (firstPids != null) {
5273                try {
5274                    int num = firstPids.size();
5275                    for (int i = 0; i < num; i++) {
5276                        synchronized (observer) {
5277                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5278                                    + firstPids.get(i));
5279                            final long sime = SystemClock.elapsedRealtime();
5280                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5281                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5282                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5283                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5284                        }
5285                    }
5286                } catch (InterruptedException e) {
5287                    Slog.wtf(TAG, e);
5288                }
5289            }
5290
5291            // Next collect the stacks of the native pids
5292            if (nativeProcs != null) {
5293                int[] pids = Process.getPidsForCommands(nativeProcs);
5294                if (pids != null) {
5295                    for (int pid : pids) {
5296                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5297                        final long sime = SystemClock.elapsedRealtime();
5298                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5299                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5300                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5301                    }
5302                }
5303            }
5304
5305            // Lastly, measure CPU usage.
5306            if (processCpuTracker != null) {
5307                processCpuTracker.init();
5308                System.gc();
5309                processCpuTracker.update();
5310                try {
5311                    synchronized (processCpuTracker) {
5312                        processCpuTracker.wait(500); // measure over 1/2 second.
5313                    }
5314                } catch (InterruptedException e) {
5315                }
5316                processCpuTracker.update();
5317
5318                // We'll take the stack crawls of just the top apps using CPU.
5319                final int N = processCpuTracker.countWorkingStats();
5320                int numProcs = 0;
5321                for (int i=0; i<N && numProcs<5; i++) {
5322                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5323                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5324                        numProcs++;
5325                        try {
5326                            synchronized (observer) {
5327                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5328                                        + stats.pid);
5329                                final long stime = SystemClock.elapsedRealtime();
5330                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5331                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5332                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5333                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5334                            }
5335                        } catch (InterruptedException e) {
5336                            Slog.wtf(TAG, e);
5337                        }
5338                    } else if (DEBUG_ANR) {
5339                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5340                                + stats.pid);
5341                    }
5342                }
5343            }
5344        } finally {
5345            observer.stopWatching();
5346        }
5347    }
5348
5349    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5350        if (true || IS_USER_BUILD) {
5351            return;
5352        }
5353        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5354        if (tracesPath == null || tracesPath.length() == 0) {
5355            return;
5356        }
5357
5358        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5359        StrictMode.allowThreadDiskWrites();
5360        try {
5361            final File tracesFile = new File(tracesPath);
5362            final File tracesDir = tracesFile.getParentFile();
5363            final File tracesTmp = new File(tracesDir, "__tmp__");
5364            try {
5365                if (tracesFile.exists()) {
5366                    tracesTmp.delete();
5367                    tracesFile.renameTo(tracesTmp);
5368                }
5369                StringBuilder sb = new StringBuilder();
5370                Time tobj = new Time();
5371                tobj.set(System.currentTimeMillis());
5372                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5373                sb.append(": ");
5374                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5375                sb.append(" since ");
5376                sb.append(msg);
5377                FileOutputStream fos = new FileOutputStream(tracesFile);
5378                fos.write(sb.toString().getBytes());
5379                if (app == null) {
5380                    fos.write("\n*** No application process!".getBytes());
5381                }
5382                fos.close();
5383                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5384            } catch (IOException e) {
5385                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5386                return;
5387            }
5388
5389            if (app != null) {
5390                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5391                firstPids.add(app.pid);
5392                dumpStackTraces(tracesPath, firstPids, null, null, null);
5393            }
5394
5395            File lastTracesFile = null;
5396            File curTracesFile = null;
5397            for (int i=9; i>=0; i--) {
5398                String name = String.format(Locale.US, "slow%02d.txt", i);
5399                curTracesFile = new File(tracesDir, name);
5400                if (curTracesFile.exists()) {
5401                    if (lastTracesFile != null) {
5402                        curTracesFile.renameTo(lastTracesFile);
5403                    } else {
5404                        curTracesFile.delete();
5405                    }
5406                }
5407                lastTracesFile = curTracesFile;
5408            }
5409            tracesFile.renameTo(curTracesFile);
5410            if (tracesTmp.exists()) {
5411                tracesTmp.renameTo(tracesFile);
5412            }
5413        } finally {
5414            StrictMode.setThreadPolicy(oldPolicy);
5415        }
5416    }
5417
5418    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5419        if (!mLaunchWarningShown) {
5420            mLaunchWarningShown = true;
5421            mUiHandler.post(new Runnable() {
5422                @Override
5423                public void run() {
5424                    synchronized (ActivityManagerService.this) {
5425                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5426                        d.show();
5427                        mUiHandler.postDelayed(new Runnable() {
5428                            @Override
5429                            public void run() {
5430                                synchronized (ActivityManagerService.this) {
5431                                    d.dismiss();
5432                                    mLaunchWarningShown = false;
5433                                }
5434                            }
5435                        }, 4000);
5436                    }
5437                }
5438            });
5439        }
5440    }
5441
5442    @Override
5443    public boolean clearApplicationUserData(final String packageName,
5444            final IPackageDataObserver observer, int userId) {
5445        enforceNotIsolatedCaller("clearApplicationUserData");
5446        int uid = Binder.getCallingUid();
5447        int pid = Binder.getCallingPid();
5448        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5449                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5450
5451
5452        long callingId = Binder.clearCallingIdentity();
5453        try {
5454            IPackageManager pm = AppGlobals.getPackageManager();
5455            int pkgUid = -1;
5456            synchronized(this) {
5457                if (getPackageManagerInternalLocked().isPackageDataProtected(
5458                        userId, packageName)) {
5459                    throw new SecurityException(
5460                            "Cannot clear data for a protected package: " + packageName);
5461                }
5462
5463                try {
5464                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5465                } catch (RemoteException e) {
5466                }
5467                if (pkgUid == -1) {
5468                    Slog.w(TAG, "Invalid packageName: " + packageName);
5469                    if (observer != null) {
5470                        try {
5471                            observer.onRemoveCompleted(packageName, false);
5472                        } catch (RemoteException e) {
5473                            Slog.i(TAG, "Observer no longer exists.");
5474                        }
5475                    }
5476                    return false;
5477                }
5478                if (uid == pkgUid || checkComponentPermission(
5479                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5480                        pid, uid, -1, true)
5481                        == PackageManager.PERMISSION_GRANTED) {
5482                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5483                } else {
5484                    throw new SecurityException("PID " + pid + " does not have permission "
5485                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5486                                    + " of package " + packageName);
5487                }
5488
5489                // Remove all tasks match the cleared application package and user
5490                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5491                    final TaskRecord tr = mRecentTasks.get(i);
5492                    final String taskPackageName =
5493                            tr.getBaseIntent().getComponent().getPackageName();
5494                    if (tr.userId != userId) continue;
5495                    if (!taskPackageName.equals(packageName)) continue;
5496                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5497                }
5498            }
5499
5500            final int pkgUidF = pkgUid;
5501            final int userIdF = userId;
5502            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5503                @Override
5504                public void onRemoveCompleted(String packageName, boolean succeeded)
5505                        throws RemoteException {
5506                    synchronized (ActivityManagerService.this) {
5507                        finishForceStopPackageLocked(packageName, pkgUidF);
5508                    }
5509
5510                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5511                            Uri.fromParts("package", packageName, null));
5512                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5513                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5514                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5515                            null, null, 0, null, null, null, null, false, false, userIdF);
5516
5517                    if (observer != null) {
5518                        observer.onRemoveCompleted(packageName, succeeded);
5519                    }
5520                }
5521            };
5522
5523            try {
5524                // Clear application user data
5525                pm.clearApplicationUserData(packageName, localObserver, userId);
5526
5527                synchronized(this) {
5528                    // Remove all permissions granted from/to this package
5529                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5530                }
5531
5532                // Remove all zen rules created by this package; revoke it's zen access.
5533                INotificationManager inm = NotificationManager.getService();
5534                inm.removeAutomaticZenRules(packageName);
5535                inm.setNotificationPolicyAccessGranted(packageName, false);
5536
5537            } catch (RemoteException e) {
5538            }
5539        } finally {
5540            Binder.restoreCallingIdentity(callingId);
5541        }
5542        return true;
5543    }
5544
5545    @Override
5546    public void killBackgroundProcesses(final String packageName, int userId) {
5547        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5548                != PackageManager.PERMISSION_GRANTED &&
5549                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5550                        != PackageManager.PERMISSION_GRANTED) {
5551            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5552                    + Binder.getCallingPid()
5553                    + ", uid=" + Binder.getCallingUid()
5554                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5555            Slog.w(TAG, msg);
5556            throw new SecurityException(msg);
5557        }
5558
5559        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5560                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5561        long callingId = Binder.clearCallingIdentity();
5562        try {
5563            IPackageManager pm = AppGlobals.getPackageManager();
5564            synchronized(this) {
5565                int appId = -1;
5566                try {
5567                    appId = UserHandle.getAppId(
5568                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5569                } catch (RemoteException e) {
5570                }
5571                if (appId == -1) {
5572                    Slog.w(TAG, "Invalid packageName: " + packageName);
5573                    return;
5574                }
5575                killPackageProcessesLocked(packageName, appId, userId,
5576                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5577            }
5578        } finally {
5579            Binder.restoreCallingIdentity(callingId);
5580        }
5581    }
5582
5583    @Override
5584    public void killAllBackgroundProcesses() {
5585        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5586                != PackageManager.PERMISSION_GRANTED) {
5587            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5588                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5589                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5590            Slog.w(TAG, msg);
5591            throw new SecurityException(msg);
5592        }
5593
5594        final long callingId = Binder.clearCallingIdentity();
5595        try {
5596            synchronized (this) {
5597                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5598                final int NP = mProcessNames.getMap().size();
5599                for (int ip = 0; ip < NP; ip++) {
5600                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5601                    final int NA = apps.size();
5602                    for (int ia = 0; ia < NA; ia++) {
5603                        final ProcessRecord app = apps.valueAt(ia);
5604                        if (app.persistent) {
5605                            // We don't kill persistent processes.
5606                            continue;
5607                        }
5608                        if (app.removed) {
5609                            procs.add(app);
5610                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5611                            app.removed = true;
5612                            procs.add(app);
5613                        }
5614                    }
5615                }
5616
5617                final int N = procs.size();
5618                for (int i = 0; i < N; i++) {
5619                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5620                }
5621
5622                mAllowLowerMemLevel = true;
5623
5624                updateOomAdjLocked();
5625                doLowMemReportIfNeededLocked(null);
5626            }
5627        } finally {
5628            Binder.restoreCallingIdentity(callingId);
5629        }
5630    }
5631
5632    /**
5633     * Kills all background processes, except those matching any of the
5634     * specified properties.
5635     *
5636     * @param minTargetSdk the target SDK version at or above which to preserve
5637     *                     processes, or {@code -1} to ignore the target SDK
5638     * @param maxProcState the process state at or below which to preserve
5639     *                     processes, or {@code -1} to ignore the process state
5640     */
5641    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5642        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5643                != PackageManager.PERMISSION_GRANTED) {
5644            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5645                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5646                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5647            Slog.w(TAG, msg);
5648            throw new SecurityException(msg);
5649        }
5650
5651        final long callingId = Binder.clearCallingIdentity();
5652        try {
5653            synchronized (this) {
5654                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5655                final int NP = mProcessNames.getMap().size();
5656                for (int ip = 0; ip < NP; ip++) {
5657                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5658                    final int NA = apps.size();
5659                    for (int ia = 0; ia < NA; ia++) {
5660                        final ProcessRecord app = apps.valueAt(ia);
5661                        if (app.removed) {
5662                            procs.add(app);
5663                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5664                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5665                            app.removed = true;
5666                            procs.add(app);
5667                        }
5668                    }
5669                }
5670
5671                final int N = procs.size();
5672                for (int i = 0; i < N; i++) {
5673                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5674                }
5675            }
5676        } finally {
5677            Binder.restoreCallingIdentity(callingId);
5678        }
5679    }
5680
5681    @Override
5682    public void forceStopPackage(final String packageName, int userId) {
5683        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5684                != PackageManager.PERMISSION_GRANTED) {
5685            String msg = "Permission Denial: forceStopPackage() from pid="
5686                    + Binder.getCallingPid()
5687                    + ", uid=" + Binder.getCallingUid()
5688                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5689            Slog.w(TAG, msg);
5690            throw new SecurityException(msg);
5691        }
5692        final int callingPid = Binder.getCallingPid();
5693        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5694                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5695        long callingId = Binder.clearCallingIdentity();
5696        try {
5697            IPackageManager pm = AppGlobals.getPackageManager();
5698            synchronized(this) {
5699                int[] users = userId == UserHandle.USER_ALL
5700                        ? mUserController.getUsers() : new int[] { userId };
5701                for (int user : users) {
5702                    int pkgUid = -1;
5703                    try {
5704                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5705                                user);
5706                    } catch (RemoteException e) {
5707                    }
5708                    if (pkgUid == -1) {
5709                        Slog.w(TAG, "Invalid packageName: " + packageName);
5710                        continue;
5711                    }
5712                    try {
5713                        pm.setPackageStoppedState(packageName, true, user);
5714                    } catch (RemoteException e) {
5715                    } catch (IllegalArgumentException e) {
5716                        Slog.w(TAG, "Failed trying to unstop package "
5717                                + packageName + ": " + e);
5718                    }
5719                    if (mUserController.isUserRunningLocked(user, 0)) {
5720                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5721                        finishForceStopPackageLocked(packageName, pkgUid);
5722                    }
5723                }
5724            }
5725        } finally {
5726            Binder.restoreCallingIdentity(callingId);
5727        }
5728    }
5729
5730    @Override
5731    public void addPackageDependency(String packageName) {
5732        synchronized (this) {
5733            int callingPid = Binder.getCallingPid();
5734            if (callingPid == Process.myPid()) {
5735                //  Yeah, um, no.
5736                return;
5737            }
5738            ProcessRecord proc;
5739            synchronized (mPidsSelfLocked) {
5740                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5741            }
5742            if (proc != null) {
5743                if (proc.pkgDeps == null) {
5744                    proc.pkgDeps = new ArraySet<String>(1);
5745                }
5746                proc.pkgDeps.add(packageName);
5747            }
5748        }
5749    }
5750
5751    /*
5752     * The pkg name and app id have to be specified.
5753     */
5754    @Override
5755    public void killApplication(String pkg, int appId, int userId, String reason) {
5756        if (pkg == null) {
5757            return;
5758        }
5759        // Make sure the uid is valid.
5760        if (appId < 0) {
5761            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5762            return;
5763        }
5764        int callerUid = Binder.getCallingUid();
5765        // Only the system server can kill an application
5766        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5767            // Post an aysnc message to kill the application
5768            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5769            msg.arg1 = appId;
5770            msg.arg2 = userId;
5771            Bundle bundle = new Bundle();
5772            bundle.putString("pkg", pkg);
5773            bundle.putString("reason", reason);
5774            msg.obj = bundle;
5775            mHandler.sendMessage(msg);
5776        } else {
5777            throw new SecurityException(callerUid + " cannot kill pkg: " +
5778                    pkg);
5779        }
5780    }
5781
5782    @Override
5783    public void closeSystemDialogs(String reason) {
5784        enforceNotIsolatedCaller("closeSystemDialogs");
5785
5786        final int pid = Binder.getCallingPid();
5787        final int uid = Binder.getCallingUid();
5788        final long origId = Binder.clearCallingIdentity();
5789        try {
5790            synchronized (this) {
5791                // Only allow this from foreground processes, so that background
5792                // applications can't abuse it to prevent system UI from being shown.
5793                if (uid >= Process.FIRST_APPLICATION_UID) {
5794                    ProcessRecord proc;
5795                    synchronized (mPidsSelfLocked) {
5796                        proc = mPidsSelfLocked.get(pid);
5797                    }
5798                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5799                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5800                                + " from background process " + proc);
5801                        return;
5802                    }
5803                }
5804                closeSystemDialogsLocked(reason);
5805            }
5806        } finally {
5807            Binder.restoreCallingIdentity(origId);
5808        }
5809    }
5810
5811    void closeSystemDialogsLocked(String reason) {
5812        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5813        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5814                | Intent.FLAG_RECEIVER_FOREGROUND);
5815        if (reason != null) {
5816            intent.putExtra("reason", reason);
5817        }
5818        mWindowManager.closeSystemDialogs(reason);
5819
5820        mStackSupervisor.closeSystemDialogsLocked();
5821
5822        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5823                AppOpsManager.OP_NONE, null, false, false,
5824                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5825    }
5826
5827    @Override
5828    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5829        enforceNotIsolatedCaller("getProcessMemoryInfo");
5830        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5831        for (int i=pids.length-1; i>=0; i--) {
5832            ProcessRecord proc;
5833            int oomAdj;
5834            synchronized (this) {
5835                synchronized (mPidsSelfLocked) {
5836                    proc = mPidsSelfLocked.get(pids[i]);
5837                    oomAdj = proc != null ? proc.setAdj : 0;
5838                }
5839            }
5840            infos[i] = new Debug.MemoryInfo();
5841            Debug.getMemoryInfo(pids[i], infos[i]);
5842            if (proc != null) {
5843                synchronized (this) {
5844                    if (proc.thread != null && proc.setAdj == oomAdj) {
5845                        // Record this for posterity if the process has been stable.
5846                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5847                                infos[i].getTotalUss(), false, proc.pkgList);
5848                    }
5849                }
5850            }
5851        }
5852        return infos;
5853    }
5854
5855    @Override
5856    public long[] getProcessPss(int[] pids) {
5857        enforceNotIsolatedCaller("getProcessPss");
5858        long[] pss = new long[pids.length];
5859        for (int i=pids.length-1; i>=0; i--) {
5860            ProcessRecord proc;
5861            int oomAdj;
5862            synchronized (this) {
5863                synchronized (mPidsSelfLocked) {
5864                    proc = mPidsSelfLocked.get(pids[i]);
5865                    oomAdj = proc != null ? proc.setAdj : 0;
5866                }
5867            }
5868            long[] tmpUss = new long[1];
5869            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5870            if (proc != null) {
5871                synchronized (this) {
5872                    if (proc.thread != null && proc.setAdj == oomAdj) {
5873                        // Record this for posterity if the process has been stable.
5874                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5875                    }
5876                }
5877            }
5878        }
5879        return pss;
5880    }
5881
5882    @Override
5883    public void killApplicationProcess(String processName, int uid) {
5884        if (processName == null) {
5885            return;
5886        }
5887
5888        int callerUid = Binder.getCallingUid();
5889        // Only the system server can kill an application
5890        if (callerUid == Process.SYSTEM_UID) {
5891            synchronized (this) {
5892                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5893                if (app != null && app.thread != null) {
5894                    try {
5895                        app.thread.scheduleSuicide();
5896                    } catch (RemoteException e) {
5897                        // If the other end already died, then our work here is done.
5898                    }
5899                } else {
5900                    Slog.w(TAG, "Process/uid not found attempting kill of "
5901                            + processName + " / " + uid);
5902                }
5903            }
5904        } else {
5905            throw new SecurityException(callerUid + " cannot kill app process: " +
5906                    processName);
5907        }
5908    }
5909
5910    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5911        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5912                false, true, false, false, UserHandle.getUserId(uid), reason);
5913    }
5914
5915    private void finishForceStopPackageLocked(final String packageName, int uid) {
5916        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5917                Uri.fromParts("package", packageName, null));
5918        if (!mProcessesReady) {
5919            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5920                    | Intent.FLAG_RECEIVER_FOREGROUND);
5921        }
5922        intent.putExtra(Intent.EXTRA_UID, uid);
5923        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5924        broadcastIntentLocked(null, null, intent,
5925                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5926                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5927    }
5928
5929
5930    private final boolean killPackageProcessesLocked(String packageName, int appId,
5931            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5932            boolean doit, boolean evenPersistent, String reason) {
5933        ArrayList<ProcessRecord> procs = new ArrayList<>();
5934
5935        // Remove all processes this package may have touched: all with the
5936        // same UID (except for the system or root user), and all whose name
5937        // matches the package name.
5938        final int NP = mProcessNames.getMap().size();
5939        for (int ip=0; ip<NP; ip++) {
5940            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5941            final int NA = apps.size();
5942            for (int ia=0; ia<NA; ia++) {
5943                ProcessRecord app = apps.valueAt(ia);
5944                if (app.persistent && !evenPersistent) {
5945                    // we don't kill persistent processes
5946                    continue;
5947                }
5948                if (app.removed) {
5949                    if (doit) {
5950                        procs.add(app);
5951                    }
5952                    continue;
5953                }
5954
5955                // Skip process if it doesn't meet our oom adj requirement.
5956                if (app.setAdj < minOomAdj) {
5957                    continue;
5958                }
5959
5960                // If no package is specified, we call all processes under the
5961                // give user id.
5962                if (packageName == null) {
5963                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5964                        continue;
5965                    }
5966                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5967                        continue;
5968                    }
5969                // Package has been specified, we want to hit all processes
5970                // that match it.  We need to qualify this by the processes
5971                // that are running under the specified app and user ID.
5972                } else {
5973                    final boolean isDep = app.pkgDeps != null
5974                            && app.pkgDeps.contains(packageName);
5975                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5976                        continue;
5977                    }
5978                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5979                        continue;
5980                    }
5981                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5982                        continue;
5983                    }
5984                }
5985
5986                // Process has passed all conditions, kill it!
5987                if (!doit) {
5988                    return true;
5989                }
5990                app.removed = true;
5991                procs.add(app);
5992            }
5993        }
5994
5995        int N = procs.size();
5996        for (int i=0; i<N; i++) {
5997            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5998        }
5999        updateOomAdjLocked();
6000        return N > 0;
6001    }
6002
6003    private void cleanupDisabledPackageComponentsLocked(
6004            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6005
6006        Set<String> disabledClasses = null;
6007        boolean packageDisabled = false;
6008        IPackageManager pm = AppGlobals.getPackageManager();
6009
6010        if (changedClasses == null) {
6011            // Nothing changed...
6012            return;
6013        }
6014
6015        // Determine enable/disable state of the package and its components.
6016        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6017        for (int i = changedClasses.length - 1; i >= 0; i--) {
6018            final String changedClass = changedClasses[i];
6019
6020            if (changedClass.equals(packageName)) {
6021                try {
6022                    // Entire package setting changed
6023                    enabled = pm.getApplicationEnabledSetting(packageName,
6024                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6025                } catch (Exception e) {
6026                    // No such package/component; probably racing with uninstall.  In any
6027                    // event it means we have nothing further to do here.
6028                    return;
6029                }
6030                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6031                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6032                if (packageDisabled) {
6033                    // Entire package is disabled.
6034                    // No need to continue to check component states.
6035                    disabledClasses = null;
6036                    break;
6037                }
6038            } else {
6039                try {
6040                    enabled = pm.getComponentEnabledSetting(
6041                            new ComponentName(packageName, changedClass),
6042                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6043                } catch (Exception e) {
6044                    // As above, probably racing with uninstall.
6045                    return;
6046                }
6047                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6048                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6049                    if (disabledClasses == null) {
6050                        disabledClasses = new ArraySet<>(changedClasses.length);
6051                    }
6052                    disabledClasses.add(changedClass);
6053                }
6054            }
6055        }
6056
6057        if (!packageDisabled && disabledClasses == null) {
6058            // Nothing to do here...
6059            return;
6060        }
6061
6062        // Clean-up disabled activities.
6063        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6064                packageName, disabledClasses, true, false, userId) && mBooted) {
6065            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6066            mStackSupervisor.scheduleIdleLocked();
6067        }
6068
6069        // Clean-up disabled tasks
6070        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6071
6072        // Clean-up disabled services.
6073        mServices.bringDownDisabledPackageServicesLocked(
6074                packageName, disabledClasses, userId, false, killProcess, true);
6075
6076        // Clean-up disabled providers.
6077        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6078        mProviderMap.collectPackageProvidersLocked(
6079                packageName, disabledClasses, true, false, userId, providers);
6080        for (int i = providers.size() - 1; i >= 0; i--) {
6081            removeDyingProviderLocked(null, providers.get(i), true);
6082        }
6083
6084        // Clean-up disabled broadcast receivers.
6085        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6086            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6087                    packageName, disabledClasses, userId, true);
6088        }
6089
6090    }
6091
6092    final boolean clearBroadcastQueueForUserLocked(int userId) {
6093        boolean didSomething = false;
6094        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6095            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6096                    null, null, userId, true);
6097        }
6098        return didSomething;
6099    }
6100
6101    final boolean forceStopPackageLocked(String packageName, int appId,
6102            boolean callerWillRestart, boolean purgeCache, boolean doit,
6103            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6104        int i;
6105
6106        if (userId == UserHandle.USER_ALL && packageName == null) {
6107            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6108        }
6109
6110        if (appId < 0 && packageName != null) {
6111            try {
6112                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6113                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6114            } catch (RemoteException e) {
6115            }
6116        }
6117
6118        if (doit) {
6119            if (packageName != null) {
6120                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6121                        + " user=" + userId + ": " + reason);
6122            } else {
6123                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6124            }
6125
6126            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6127        }
6128
6129        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6130                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6131                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6132
6133        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6134                packageName, null, doit, evenPersistent, userId)) {
6135            if (!doit) {
6136                return true;
6137            }
6138            didSomething = true;
6139        }
6140
6141        if (mServices.bringDownDisabledPackageServicesLocked(
6142                packageName, null, userId, evenPersistent, true, doit)) {
6143            if (!doit) {
6144                return true;
6145            }
6146            didSomething = true;
6147        }
6148
6149        if (packageName == null) {
6150            // Remove all sticky broadcasts from this user.
6151            mStickyBroadcasts.remove(userId);
6152        }
6153
6154        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6155        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6156                userId, providers)) {
6157            if (!doit) {
6158                return true;
6159            }
6160            didSomething = true;
6161        }
6162        for (i = providers.size() - 1; i >= 0; i--) {
6163            removeDyingProviderLocked(null, providers.get(i), true);
6164        }
6165
6166        // Remove transient permissions granted from/to this package/user
6167        removeUriPermissionsForPackageLocked(packageName, userId, false);
6168
6169        if (doit) {
6170            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6171                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6172                        packageName, null, userId, doit);
6173            }
6174        }
6175
6176        if (packageName == null || uninstalling) {
6177            // Remove pending intents.  For now we only do this when force
6178            // stopping users, because we have some problems when doing this
6179            // for packages -- app widgets are not currently cleaned up for
6180            // such packages, so they can be left with bad pending intents.
6181            if (mIntentSenderRecords.size() > 0) {
6182                Iterator<WeakReference<PendingIntentRecord>> it
6183                        = mIntentSenderRecords.values().iterator();
6184                while (it.hasNext()) {
6185                    WeakReference<PendingIntentRecord> wpir = it.next();
6186                    if (wpir == null) {
6187                        it.remove();
6188                        continue;
6189                    }
6190                    PendingIntentRecord pir = wpir.get();
6191                    if (pir == null) {
6192                        it.remove();
6193                        continue;
6194                    }
6195                    if (packageName == null) {
6196                        // Stopping user, remove all objects for the user.
6197                        if (pir.key.userId != userId) {
6198                            // Not the same user, skip it.
6199                            continue;
6200                        }
6201                    } else {
6202                        if (UserHandle.getAppId(pir.uid) != appId) {
6203                            // Different app id, skip it.
6204                            continue;
6205                        }
6206                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6207                            // Different user, skip it.
6208                            continue;
6209                        }
6210                        if (!pir.key.packageName.equals(packageName)) {
6211                            // Different package, skip it.
6212                            continue;
6213                        }
6214                    }
6215                    if (!doit) {
6216                        return true;
6217                    }
6218                    didSomething = true;
6219                    it.remove();
6220                    pir.canceled = true;
6221                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6222                        pir.key.activity.pendingResults.remove(pir.ref);
6223                    }
6224                }
6225            }
6226        }
6227
6228        if (doit) {
6229            if (purgeCache && packageName != null) {
6230                AttributeCache ac = AttributeCache.instance();
6231                if (ac != null) {
6232                    ac.removePackage(packageName);
6233                }
6234            }
6235            if (mBooted) {
6236                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6237                mStackSupervisor.scheduleIdleLocked();
6238            }
6239        }
6240
6241        return didSomething;
6242    }
6243
6244    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6245        ProcessRecord old = mProcessNames.remove(name, uid);
6246        if (old != null) {
6247            old.uidRecord.numProcs--;
6248            if (old.uidRecord.numProcs == 0) {
6249                // No more processes using this uid, tell clients it is gone.
6250                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6251                        "No more processes in " + old.uidRecord);
6252                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6253                mActiveUids.remove(uid);
6254                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6255            }
6256            old.uidRecord = null;
6257        }
6258        mIsolatedProcesses.remove(uid);
6259        return old;
6260    }
6261
6262    private final void addProcessNameLocked(ProcessRecord proc) {
6263        // We shouldn't already have a process under this name, but just in case we
6264        // need to clean up whatever may be there now.
6265        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6266        if (old == proc && proc.persistent) {
6267            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6268            Slog.w(TAG, "Re-adding persistent process " + proc);
6269        } else if (old != null) {
6270            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6271        }
6272        UidRecord uidRec = mActiveUids.get(proc.uid);
6273        if (uidRec == null) {
6274            uidRec = new UidRecord(proc.uid);
6275            // This is the first appearance of the uid, report it now!
6276            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6277                    "Creating new process uid: " + uidRec);
6278            mActiveUids.put(proc.uid, uidRec);
6279            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6280            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6281        }
6282        proc.uidRecord = uidRec;
6283        uidRec.numProcs++;
6284        mProcessNames.put(proc.processName, proc.uid, proc);
6285        if (proc.isolated) {
6286            mIsolatedProcesses.put(proc.uid, proc);
6287        }
6288    }
6289
6290    boolean removeProcessLocked(ProcessRecord app,
6291            boolean callerWillRestart, boolean allowRestart, String reason) {
6292        final String name = app.processName;
6293        final int uid = app.uid;
6294        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6295            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6296
6297        ProcessRecord old = mProcessNames.get(name, uid);
6298        if (old != app) {
6299            // This process is no longer active, so nothing to do.
6300            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6301            return false;
6302        }
6303        removeProcessNameLocked(name, uid);
6304        if (mHeavyWeightProcess == app) {
6305            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6306                    mHeavyWeightProcess.userId, 0));
6307            mHeavyWeightProcess = null;
6308        }
6309        boolean needRestart = false;
6310        if (app.pid > 0 && app.pid != MY_PID) {
6311            int pid = app.pid;
6312            synchronized (mPidsSelfLocked) {
6313                mPidsSelfLocked.remove(pid);
6314                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6315            }
6316            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6317            if (app.isolated) {
6318                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6319            }
6320            boolean willRestart = false;
6321            if (app.persistent && !app.isolated) {
6322                if (!callerWillRestart) {
6323                    willRestart = true;
6324                } else {
6325                    needRestart = true;
6326                }
6327            }
6328            app.kill(reason, true);
6329            handleAppDiedLocked(app, willRestart, allowRestart);
6330            if (willRestart) {
6331                removeLruProcessLocked(app);
6332                addAppLocked(app.info, false, null /* ABI override */);
6333            }
6334        } else {
6335            mRemovedProcesses.add(app);
6336        }
6337
6338        return needRestart;
6339    }
6340
6341    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6342        cleanupAppInLaunchingProvidersLocked(app, true);
6343        removeProcessLocked(app, false, true, "timeout publishing content providers");
6344    }
6345
6346    private final void processStartTimedOutLocked(ProcessRecord app) {
6347        final int pid = app.pid;
6348        boolean gone = false;
6349        synchronized (mPidsSelfLocked) {
6350            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6351            if (knownApp != null && knownApp.thread == null) {
6352                mPidsSelfLocked.remove(pid);
6353                gone = true;
6354            }
6355        }
6356
6357        if (gone) {
6358            Slog.w(TAG, "Process " + app + " failed to attach");
6359            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6360                    pid, app.uid, app.processName);
6361            removeProcessNameLocked(app.processName, app.uid);
6362            if (mHeavyWeightProcess == app) {
6363                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6364                        mHeavyWeightProcess.userId, 0));
6365                mHeavyWeightProcess = null;
6366            }
6367            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6368            if (app.isolated) {
6369                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6370            }
6371            // Take care of any launching providers waiting for this process.
6372            cleanupAppInLaunchingProvidersLocked(app, true);
6373            // Take care of any services that are waiting for the process.
6374            mServices.processStartTimedOutLocked(app);
6375            app.kill("start timeout", true);
6376            removeLruProcessLocked(app);
6377            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6378                Slog.w(TAG, "Unattached app died before backup, skipping");
6379                try {
6380                    IBackupManager bm = IBackupManager.Stub.asInterface(
6381                            ServiceManager.getService(Context.BACKUP_SERVICE));
6382                    bm.agentDisconnected(app.info.packageName);
6383                } catch (RemoteException e) {
6384                    // Can't happen; the backup manager is local
6385                }
6386            }
6387            if (isPendingBroadcastProcessLocked(pid)) {
6388                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6389                skipPendingBroadcastLocked(pid);
6390            }
6391        } else {
6392            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6393        }
6394    }
6395
6396    private final boolean attachApplicationLocked(IApplicationThread thread,
6397            int pid) {
6398
6399        // Find the application record that is being attached...  either via
6400        // the pid if we are running in multiple processes, or just pull the
6401        // next app record if we are emulating process with anonymous threads.
6402        ProcessRecord app;
6403        if (pid != MY_PID && pid >= 0) {
6404            synchronized (mPidsSelfLocked) {
6405                app = mPidsSelfLocked.get(pid);
6406            }
6407        } else {
6408            app = null;
6409        }
6410
6411        if (app == null) {
6412            Slog.w(TAG, "No pending application record for pid " + pid
6413                    + " (IApplicationThread " + thread + "); dropping process");
6414            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6415            if (pid > 0 && pid != MY_PID) {
6416                Process.killProcessQuiet(pid);
6417                //TODO: killProcessGroup(app.info.uid, pid);
6418            } else {
6419                try {
6420                    thread.scheduleExit();
6421                } catch (Exception e) {
6422                    // Ignore exceptions.
6423                }
6424            }
6425            return false;
6426        }
6427
6428        // If this application record is still attached to a previous
6429        // process, clean it up now.
6430        if (app.thread != null) {
6431            handleAppDiedLocked(app, true, true);
6432        }
6433
6434        // Tell the process all about itself.
6435
6436        if (DEBUG_ALL) Slog.v(
6437                TAG, "Binding process pid " + pid + " to record " + app);
6438
6439        final String processName = app.processName;
6440        try {
6441            AppDeathRecipient adr = new AppDeathRecipient(
6442                    app, pid, thread);
6443            thread.asBinder().linkToDeath(adr, 0);
6444            app.deathRecipient = adr;
6445        } catch (RemoteException e) {
6446            app.resetPackageList(mProcessStats);
6447            startProcessLocked(app, "link fail", processName);
6448            return false;
6449        }
6450
6451        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6452
6453        app.makeActive(thread, mProcessStats);
6454        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6455        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6456        app.forcingToForeground = null;
6457        updateProcessForegroundLocked(app, false, false);
6458        app.hasShownUi = false;
6459        app.debugging = false;
6460        app.cached = false;
6461        app.killedByAm = false;
6462
6463        // We carefully use the same state that PackageManager uses for
6464        // filtering, since we use this flag to decide if we need to install
6465        // providers when user is unlocked later
6466        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6467
6468        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6469
6470        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6471        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6472
6473        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6474            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6475            msg.obj = app;
6476            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6477        }
6478
6479        if (!normalMode) {
6480            Slog.i(TAG, "Launching preboot mode app: " + app);
6481        }
6482
6483        if (DEBUG_ALL) Slog.v(
6484            TAG, "New app record " + app
6485            + " thread=" + thread.asBinder() + " pid=" + pid);
6486        try {
6487            int testMode = IApplicationThread.DEBUG_OFF;
6488            if (mDebugApp != null && mDebugApp.equals(processName)) {
6489                testMode = mWaitForDebugger
6490                    ? IApplicationThread.DEBUG_WAIT
6491                    : IApplicationThread.DEBUG_ON;
6492                app.debugging = true;
6493                if (mDebugTransient) {
6494                    mDebugApp = mOrigDebugApp;
6495                    mWaitForDebugger = mOrigWaitForDebugger;
6496                }
6497            }
6498            String profileFile = app.instrumentationProfileFile;
6499            ParcelFileDescriptor profileFd = null;
6500            int samplingInterval = 0;
6501            boolean profileAutoStop = false;
6502            if (mProfileApp != null && mProfileApp.equals(processName)) {
6503                mProfileProc = app;
6504                profileFile = mProfileFile;
6505                profileFd = mProfileFd;
6506                samplingInterval = mSamplingInterval;
6507                profileAutoStop = mAutoStopProfiler;
6508            }
6509            boolean enableTrackAllocation = false;
6510            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6511                enableTrackAllocation = true;
6512                mTrackAllocationApp = null;
6513            }
6514
6515            // If the app is being launched for restore or full backup, set it up specially
6516            boolean isRestrictedBackupMode = false;
6517            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6518                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6519                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6520                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6521                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6522            }
6523
6524            if (app.instrumentationClass != null) {
6525                notifyPackageUse(app.instrumentationClass.getPackageName(),
6526                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6527            }
6528            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6529                    + processName + " with config " + mConfiguration);
6530            ApplicationInfo appInfo = app.instrumentationInfo != null
6531                    ? app.instrumentationInfo : app.info;
6532            app.compat = compatibilityInfoForPackageLocked(appInfo);
6533            if (profileFd != null) {
6534                profileFd = profileFd.dup();
6535            }
6536            ProfilerInfo profilerInfo = profileFile == null ? null
6537                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6538            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6539                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6540                    app.instrumentationUiAutomationConnection, testMode,
6541                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6542                    isRestrictedBackupMode || !normalMode, app.persistent,
6543                    new Configuration(mConfiguration), app.compat,
6544                    getCommonServicesLocked(app.isolated),
6545                    mCoreSettingsObserver.getCoreSettingsLocked());
6546            updateLruProcessLocked(app, false, null);
6547            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6548        } catch (Exception e) {
6549            // todo: Yikes!  What should we do?  For now we will try to
6550            // start another process, but that could easily get us in
6551            // an infinite loop of restarting processes...
6552            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6553
6554            app.resetPackageList(mProcessStats);
6555            app.unlinkDeathRecipient();
6556            startProcessLocked(app, "bind fail", processName);
6557            return false;
6558        }
6559
6560        // Remove this record from the list of starting applications.
6561        mPersistentStartingProcesses.remove(app);
6562        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6563                "Attach application locked removing on hold: " + app);
6564        mProcessesOnHold.remove(app);
6565
6566        boolean badApp = false;
6567        boolean didSomething = false;
6568
6569        // See if the top visible activity is waiting to run in this process...
6570        if (normalMode) {
6571            try {
6572                if (mStackSupervisor.attachApplicationLocked(app)) {
6573                    didSomething = true;
6574                }
6575            } catch (Exception e) {
6576                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6577                badApp = true;
6578            }
6579        }
6580
6581        // Find any services that should be running in this process...
6582        if (!badApp) {
6583            try {
6584                didSomething |= mServices.attachApplicationLocked(app, processName);
6585            } catch (Exception e) {
6586                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6587                badApp = true;
6588            }
6589        }
6590
6591        // Check if a next-broadcast receiver is in this process...
6592        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6593            try {
6594                didSomething |= sendPendingBroadcastsLocked(app);
6595            } catch (Exception e) {
6596                // If the app died trying to launch the receiver we declare it 'bad'
6597                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6598                badApp = true;
6599            }
6600        }
6601
6602        // Check whether the next backup agent is in this process...
6603        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6604            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6605                    "New app is backup target, launching agent for " + app);
6606            notifyPackageUse(mBackupTarget.appInfo.packageName,
6607                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6608            try {
6609                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6610                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6611                        mBackupTarget.backupMode);
6612            } catch (Exception e) {
6613                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6614                badApp = true;
6615            }
6616        }
6617
6618        if (badApp) {
6619            app.kill("error during init", true);
6620            handleAppDiedLocked(app, false, true);
6621            return false;
6622        }
6623
6624        if (!didSomething) {
6625            updateOomAdjLocked();
6626        }
6627
6628        return true;
6629    }
6630
6631    @Override
6632    public final void attachApplication(IApplicationThread thread) {
6633        synchronized (this) {
6634            int callingPid = Binder.getCallingPid();
6635            final long origId = Binder.clearCallingIdentity();
6636            attachApplicationLocked(thread, callingPid);
6637            Binder.restoreCallingIdentity(origId);
6638        }
6639    }
6640
6641    @Override
6642    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6643        final long origId = Binder.clearCallingIdentity();
6644        synchronized (this) {
6645            ActivityStack stack = ActivityRecord.getStackLocked(token);
6646            if (stack != null) {
6647                ActivityRecord r =
6648                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6649                if (stopProfiling) {
6650                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6651                        try {
6652                            mProfileFd.close();
6653                        } catch (IOException e) {
6654                        }
6655                        clearProfilerLocked();
6656                    }
6657                }
6658            }
6659        }
6660        Binder.restoreCallingIdentity(origId);
6661    }
6662
6663    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6664        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6665                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6666    }
6667
6668    void enableScreenAfterBoot() {
6669        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6670                SystemClock.uptimeMillis());
6671        mWindowManager.enableScreenAfterBoot();
6672
6673        synchronized (this) {
6674            updateEventDispatchingLocked();
6675        }
6676    }
6677
6678    @Override
6679    public void showBootMessage(final CharSequence msg, final boolean always) {
6680        if (Binder.getCallingUid() != Process.myUid()) {
6681            throw new SecurityException();
6682        }
6683        mWindowManager.showBootMessage(msg, always);
6684    }
6685
6686    @Override
6687    public void keyguardWaitingForActivityDrawn() {
6688        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6689        final long token = Binder.clearCallingIdentity();
6690        try {
6691            synchronized (this) {
6692                if (DEBUG_LOCKSCREEN) logLockScreen("");
6693                mWindowManager.keyguardWaitingForActivityDrawn();
6694                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6695                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6696                    updateSleepIfNeededLocked();
6697                }
6698            }
6699        } finally {
6700            Binder.restoreCallingIdentity(token);
6701        }
6702    }
6703
6704    @Override
6705    public void keyguardGoingAway(int flags) {
6706        enforceNotIsolatedCaller("keyguardGoingAway");
6707        final long token = Binder.clearCallingIdentity();
6708        try {
6709            synchronized (this) {
6710                if (DEBUG_LOCKSCREEN) logLockScreen("");
6711                mWindowManager.keyguardGoingAway(flags);
6712                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6713                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6714                    updateSleepIfNeededLocked();
6715
6716                    // Some stack visibility might change (e.g. docked stack)
6717                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6718                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6719                }
6720            }
6721        } finally {
6722            Binder.restoreCallingIdentity(token);
6723        }
6724    }
6725
6726    final void finishBooting() {
6727        synchronized (this) {
6728            if (!mBootAnimationComplete) {
6729                mCallFinishBooting = true;
6730                return;
6731            }
6732            mCallFinishBooting = false;
6733        }
6734
6735        ArraySet<String> completedIsas = new ArraySet<String>();
6736        for (String abi : Build.SUPPORTED_ABIS) {
6737            Process.establishZygoteConnectionForAbi(abi);
6738            final String instructionSet = VMRuntime.getInstructionSet(abi);
6739            if (!completedIsas.contains(instructionSet)) {
6740                try {
6741                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6742                } catch (InstallerException e) {
6743                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6744                            e.getMessage() +")");
6745                }
6746                completedIsas.add(instructionSet);
6747            }
6748        }
6749
6750        IntentFilter pkgFilter = new IntentFilter();
6751        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6752        pkgFilter.addDataScheme("package");
6753        mContext.registerReceiver(new BroadcastReceiver() {
6754            @Override
6755            public void onReceive(Context context, Intent intent) {
6756                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6757                if (pkgs != null) {
6758                    for (String pkg : pkgs) {
6759                        synchronized (ActivityManagerService.this) {
6760                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6761                                    0, "query restart")) {
6762                                setResultCode(Activity.RESULT_OK);
6763                                return;
6764                            }
6765                        }
6766                    }
6767                }
6768            }
6769        }, pkgFilter);
6770
6771        IntentFilter dumpheapFilter = new IntentFilter();
6772        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6773        mContext.registerReceiver(new BroadcastReceiver() {
6774            @Override
6775            public void onReceive(Context context, Intent intent) {
6776                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6777                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6778                } else {
6779                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6780                }
6781            }
6782        }, dumpheapFilter);
6783
6784        // Let system services know.
6785        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6786
6787        synchronized (this) {
6788            // Ensure that any processes we had put on hold are now started
6789            // up.
6790            final int NP = mProcessesOnHold.size();
6791            if (NP > 0) {
6792                ArrayList<ProcessRecord> procs =
6793                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6794                for (int ip=0; ip<NP; ip++) {
6795                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6796                            + procs.get(ip));
6797                    startProcessLocked(procs.get(ip), "on-hold", null);
6798                }
6799            }
6800
6801            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6802                // Start looking for apps that are abusing wake locks.
6803                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6804                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6805                // Tell anyone interested that we are done booting!
6806                SystemProperties.set("sys.boot_completed", "1");
6807
6808                // And trigger dev.bootcomplete if we are not showing encryption progress
6809                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6810                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6811                    SystemProperties.set("dev.bootcomplete", "1");
6812                }
6813                mUserController.sendBootCompletedLocked(
6814                        new IIntentReceiver.Stub() {
6815                            @Override
6816                            public void performReceive(Intent intent, int resultCode,
6817                                    String data, Bundle extras, boolean ordered,
6818                                    boolean sticky, int sendingUser) {
6819                                synchronized (ActivityManagerService.this) {
6820                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6821                                            true, false);
6822                                }
6823                            }
6824                        });
6825                scheduleStartProfilesLocked();
6826            }
6827        }
6828    }
6829
6830    @Override
6831    public void bootAnimationComplete() {
6832        final boolean callFinishBooting;
6833        synchronized (this) {
6834            callFinishBooting = mCallFinishBooting;
6835            mBootAnimationComplete = true;
6836        }
6837        if (callFinishBooting) {
6838            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6839            finishBooting();
6840            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6841        }
6842    }
6843
6844    final void ensureBootCompleted() {
6845        boolean booting;
6846        boolean enableScreen;
6847        synchronized (this) {
6848            booting = mBooting;
6849            mBooting = false;
6850            enableScreen = !mBooted;
6851            mBooted = true;
6852        }
6853
6854        if (booting) {
6855            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6856            finishBooting();
6857            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6858        }
6859
6860        if (enableScreen) {
6861            enableScreenAfterBoot();
6862        }
6863    }
6864
6865    @Override
6866    public final void activityResumed(IBinder token) {
6867        final long origId = Binder.clearCallingIdentity();
6868        synchronized(this) {
6869            ActivityStack stack = ActivityRecord.getStackLocked(token);
6870            if (stack != null) {
6871                stack.activityResumedLocked(token);
6872            }
6873        }
6874        Binder.restoreCallingIdentity(origId);
6875    }
6876
6877    @Override
6878    public final void activityPaused(IBinder token) {
6879        final long origId = Binder.clearCallingIdentity();
6880        synchronized(this) {
6881            ActivityStack stack = ActivityRecord.getStackLocked(token);
6882            if (stack != null) {
6883                stack.activityPausedLocked(token, false);
6884            }
6885        }
6886        Binder.restoreCallingIdentity(origId);
6887    }
6888
6889    @Override
6890    public final void activityStopped(IBinder token, Bundle icicle,
6891            PersistableBundle persistentState, CharSequence description) {
6892        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6893
6894        // Refuse possible leaked file descriptors
6895        if (icicle != null && icicle.hasFileDescriptors()) {
6896            throw new IllegalArgumentException("File descriptors passed in Bundle");
6897        }
6898
6899        final long origId = Binder.clearCallingIdentity();
6900
6901        synchronized (this) {
6902            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6903            if (r != null) {
6904                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6905            }
6906        }
6907
6908        trimApplications();
6909
6910        Binder.restoreCallingIdentity(origId);
6911    }
6912
6913    @Override
6914    public final void activityDestroyed(IBinder token) {
6915        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6916        synchronized (this) {
6917            ActivityStack stack = ActivityRecord.getStackLocked(token);
6918            if (stack != null) {
6919                stack.activityDestroyedLocked(token, "activityDestroyed");
6920            }
6921        }
6922    }
6923
6924    @Override
6925    public final void activityRelaunched(IBinder token) {
6926        final long origId = Binder.clearCallingIdentity();
6927        synchronized (this) {
6928            mStackSupervisor.activityRelaunchedLocked(token);
6929        }
6930        Binder.restoreCallingIdentity(origId);
6931    }
6932
6933    @Override
6934    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6935            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6936        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6937                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6938        synchronized (this) {
6939            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6940            if (record == null) {
6941                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6942                        + "found for: " + token);
6943            }
6944            record.setSizeConfigurations(horizontalSizeConfiguration,
6945                    verticalSizeConfigurations, smallestSizeConfigurations);
6946        }
6947    }
6948
6949    @Override
6950    public final void backgroundResourcesReleased(IBinder token) {
6951        final long origId = Binder.clearCallingIdentity();
6952        try {
6953            synchronized (this) {
6954                ActivityStack stack = ActivityRecord.getStackLocked(token);
6955                if (stack != null) {
6956                    stack.backgroundResourcesReleased();
6957                }
6958            }
6959        } finally {
6960            Binder.restoreCallingIdentity(origId);
6961        }
6962    }
6963
6964    @Override
6965    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6966        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6967    }
6968
6969    @Override
6970    public final void notifyEnterAnimationComplete(IBinder token) {
6971        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6972    }
6973
6974    @Override
6975    public String getCallingPackage(IBinder token) {
6976        synchronized (this) {
6977            ActivityRecord r = getCallingRecordLocked(token);
6978            return r != null ? r.info.packageName : null;
6979        }
6980    }
6981
6982    @Override
6983    public ComponentName getCallingActivity(IBinder token) {
6984        synchronized (this) {
6985            ActivityRecord r = getCallingRecordLocked(token);
6986            return r != null ? r.intent.getComponent() : null;
6987        }
6988    }
6989
6990    private ActivityRecord getCallingRecordLocked(IBinder token) {
6991        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6992        if (r == null) {
6993            return null;
6994        }
6995        return r.resultTo;
6996    }
6997
6998    @Override
6999    public ComponentName getActivityClassForToken(IBinder token) {
7000        synchronized(this) {
7001            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7002            if (r == null) {
7003                return null;
7004            }
7005            return r.intent.getComponent();
7006        }
7007    }
7008
7009    @Override
7010    public String getPackageForToken(IBinder token) {
7011        synchronized(this) {
7012            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7013            if (r == null) {
7014                return null;
7015            }
7016            return r.packageName;
7017        }
7018    }
7019
7020    @Override
7021    public boolean isRootVoiceInteraction(IBinder token) {
7022        synchronized(this) {
7023            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7024            if (r == null) {
7025                return false;
7026            }
7027            return r.rootVoiceInteraction;
7028        }
7029    }
7030
7031    @Override
7032    public IIntentSender getIntentSender(int type,
7033            String packageName, IBinder token, String resultWho,
7034            int requestCode, Intent[] intents, String[] resolvedTypes,
7035            int flags, Bundle bOptions, int userId) {
7036        enforceNotIsolatedCaller("getIntentSender");
7037        // Refuse possible leaked file descriptors
7038        if (intents != null) {
7039            if (intents.length < 1) {
7040                throw new IllegalArgumentException("Intents array length must be >= 1");
7041            }
7042            for (int i=0; i<intents.length; i++) {
7043                Intent intent = intents[i];
7044                if (intent != null) {
7045                    if (intent.hasFileDescriptors()) {
7046                        throw new IllegalArgumentException("File descriptors passed in Intent");
7047                    }
7048                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7049                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7050                        throw new IllegalArgumentException(
7051                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7052                    }
7053                    intents[i] = new Intent(intent);
7054                }
7055            }
7056            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7057                throw new IllegalArgumentException(
7058                        "Intent array length does not match resolvedTypes length");
7059            }
7060        }
7061        if (bOptions != null) {
7062            if (bOptions.hasFileDescriptors()) {
7063                throw new IllegalArgumentException("File descriptors passed in options");
7064            }
7065        }
7066
7067        synchronized(this) {
7068            int callingUid = Binder.getCallingUid();
7069            int origUserId = userId;
7070            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7071                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7072                    ALLOW_NON_FULL, "getIntentSender", null);
7073            if (origUserId == UserHandle.USER_CURRENT) {
7074                // We don't want to evaluate this until the pending intent is
7075                // actually executed.  However, we do want to always do the
7076                // security checking for it above.
7077                userId = UserHandle.USER_CURRENT;
7078            }
7079            try {
7080                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7081                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7082                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7083                    if (!UserHandle.isSameApp(callingUid, uid)) {
7084                        String msg = "Permission Denial: getIntentSender() from pid="
7085                            + Binder.getCallingPid()
7086                            + ", uid=" + Binder.getCallingUid()
7087                            + ", (need uid=" + uid + ")"
7088                            + " is not allowed to send as package " + packageName;
7089                        Slog.w(TAG, msg);
7090                        throw new SecurityException(msg);
7091                    }
7092                }
7093
7094                return getIntentSenderLocked(type, packageName, callingUid, userId,
7095                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7096
7097            } catch (RemoteException e) {
7098                throw new SecurityException(e);
7099            }
7100        }
7101    }
7102
7103    IIntentSender getIntentSenderLocked(int type, String packageName,
7104            int callingUid, int userId, IBinder token, String resultWho,
7105            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7106            Bundle bOptions) {
7107        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7108        ActivityRecord activity = null;
7109        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7110            activity = ActivityRecord.isInStackLocked(token);
7111            if (activity == null) {
7112                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7113                return null;
7114            }
7115            if (activity.finishing) {
7116                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7117                return null;
7118            }
7119        }
7120
7121        // We're going to be splicing together extras before sending, so we're
7122        // okay poking into any contained extras.
7123        if (intents != null) {
7124            for (int i = 0; i < intents.length; i++) {
7125                intents[i].setDefusable(true);
7126            }
7127        }
7128        Bundle.setDefusable(bOptions, true);
7129
7130        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7131        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7132        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7133        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7134                |PendingIntent.FLAG_UPDATE_CURRENT);
7135
7136        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7137                type, packageName, activity, resultWho,
7138                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7139        WeakReference<PendingIntentRecord> ref;
7140        ref = mIntentSenderRecords.get(key);
7141        PendingIntentRecord rec = ref != null ? ref.get() : null;
7142        if (rec != null) {
7143            if (!cancelCurrent) {
7144                if (updateCurrent) {
7145                    if (rec.key.requestIntent != null) {
7146                        rec.key.requestIntent.replaceExtras(intents != null ?
7147                                intents[intents.length - 1] : null);
7148                    }
7149                    if (intents != null) {
7150                        intents[intents.length-1] = rec.key.requestIntent;
7151                        rec.key.allIntents = intents;
7152                        rec.key.allResolvedTypes = resolvedTypes;
7153                    } else {
7154                        rec.key.allIntents = null;
7155                        rec.key.allResolvedTypes = null;
7156                    }
7157                }
7158                return rec;
7159            }
7160            rec.canceled = true;
7161            mIntentSenderRecords.remove(key);
7162        }
7163        if (noCreate) {
7164            return rec;
7165        }
7166        rec = new PendingIntentRecord(this, key, callingUid);
7167        mIntentSenderRecords.put(key, rec.ref);
7168        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7169            if (activity.pendingResults == null) {
7170                activity.pendingResults
7171                        = new HashSet<WeakReference<PendingIntentRecord>>();
7172            }
7173            activity.pendingResults.add(rec.ref);
7174        }
7175        return rec;
7176    }
7177
7178    @Override
7179    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7180            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7181        if (target instanceof PendingIntentRecord) {
7182            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7183                    finishedReceiver, requiredPermission, options);
7184        } else {
7185            if (intent == null) {
7186                // Weird case: someone has given us their own custom IIntentSender, and now
7187                // they have someone else trying to send to it but of course this isn't
7188                // really a PendingIntent, so there is no base Intent, and the caller isn't
7189                // supplying an Intent... but we never want to dispatch a null Intent to
7190                // a receiver, so um...  let's make something up.
7191                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7192                intent = new Intent(Intent.ACTION_MAIN);
7193            }
7194            try {
7195                target.send(code, intent, resolvedType, null, requiredPermission, options);
7196            } catch (RemoteException e) {
7197            }
7198            // Platform code can rely on getting a result back when the send is done, but if
7199            // this intent sender is from outside of the system we can't rely on it doing that.
7200            // So instead we don't give it the result receiver, and instead just directly
7201            // report the finish immediately.
7202            if (finishedReceiver != null) {
7203                try {
7204                    finishedReceiver.performReceive(intent, 0,
7205                            null, null, false, false, UserHandle.getCallingUserId());
7206                } catch (RemoteException e) {
7207                }
7208            }
7209            return 0;
7210        }
7211    }
7212
7213    /**
7214     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7215     *
7216     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7217     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7218     */
7219    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7220        if (DEBUG_WHITELISTS) {
7221            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7222                    + targetUid + ", " + duration + ")");
7223        }
7224        synchronized (mPidsSelfLocked) {
7225            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7226            if (pr == null) {
7227                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7228                return;
7229            }
7230            if (!pr.whitelistManager) {
7231                if (DEBUG_WHITELISTS) {
7232                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7233                            + callerPid + " is not allowed");
7234                }
7235                return;
7236            }
7237        }
7238
7239        final long token = Binder.clearCallingIdentity();
7240        try {
7241            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7242                    true, "pe from uid:" + callerUid);
7243        } finally {
7244            Binder.restoreCallingIdentity(token);
7245        }
7246    }
7247
7248    @Override
7249    public void cancelIntentSender(IIntentSender sender) {
7250        if (!(sender instanceof PendingIntentRecord)) {
7251            return;
7252        }
7253        synchronized(this) {
7254            PendingIntentRecord rec = (PendingIntentRecord)sender;
7255            try {
7256                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7257                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7258                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7259                    String msg = "Permission Denial: cancelIntentSender() from pid="
7260                        + Binder.getCallingPid()
7261                        + ", uid=" + Binder.getCallingUid()
7262                        + " is not allowed to cancel packges "
7263                        + rec.key.packageName;
7264                    Slog.w(TAG, msg);
7265                    throw new SecurityException(msg);
7266                }
7267            } catch (RemoteException e) {
7268                throw new SecurityException(e);
7269            }
7270            cancelIntentSenderLocked(rec, true);
7271        }
7272    }
7273
7274    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7275        rec.canceled = true;
7276        mIntentSenderRecords.remove(rec.key);
7277        if (cleanActivity && rec.key.activity != null) {
7278            rec.key.activity.pendingResults.remove(rec.ref);
7279        }
7280    }
7281
7282    @Override
7283    public String getPackageForIntentSender(IIntentSender pendingResult) {
7284        if (!(pendingResult instanceof PendingIntentRecord)) {
7285            return null;
7286        }
7287        try {
7288            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7289            return res.key.packageName;
7290        } catch (ClassCastException e) {
7291        }
7292        return null;
7293    }
7294
7295    @Override
7296    public int getUidForIntentSender(IIntentSender sender) {
7297        if (sender instanceof PendingIntentRecord) {
7298            try {
7299                PendingIntentRecord res = (PendingIntentRecord)sender;
7300                return res.uid;
7301            } catch (ClassCastException e) {
7302            }
7303        }
7304        return -1;
7305    }
7306
7307    @Override
7308    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7309        if (!(pendingResult instanceof PendingIntentRecord)) {
7310            return false;
7311        }
7312        try {
7313            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7314            if (res.key.allIntents == null) {
7315                return false;
7316            }
7317            for (int i=0; i<res.key.allIntents.length; i++) {
7318                Intent intent = res.key.allIntents[i];
7319                if (intent.getPackage() != null && intent.getComponent() != null) {
7320                    return false;
7321                }
7322            }
7323            return true;
7324        } catch (ClassCastException e) {
7325        }
7326        return false;
7327    }
7328
7329    @Override
7330    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7331        if (!(pendingResult instanceof PendingIntentRecord)) {
7332            return false;
7333        }
7334        try {
7335            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7336            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7337                return true;
7338            }
7339            return false;
7340        } catch (ClassCastException e) {
7341        }
7342        return false;
7343    }
7344
7345    @Override
7346    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7347        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7348                "getIntentForIntentSender()");
7349        if (!(pendingResult instanceof PendingIntentRecord)) {
7350            return null;
7351        }
7352        try {
7353            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7354            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7355        } catch (ClassCastException e) {
7356        }
7357        return null;
7358    }
7359
7360    @Override
7361    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7362        if (!(pendingResult instanceof PendingIntentRecord)) {
7363            return null;
7364        }
7365        try {
7366            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7367            synchronized (this) {
7368                return getTagForIntentSenderLocked(res, prefix);
7369            }
7370        } catch (ClassCastException e) {
7371        }
7372        return null;
7373    }
7374
7375    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7376        final Intent intent = res.key.requestIntent;
7377        if (intent != null) {
7378            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7379                    || res.lastTagPrefix.equals(prefix))) {
7380                return res.lastTag;
7381            }
7382            res.lastTagPrefix = prefix;
7383            final StringBuilder sb = new StringBuilder(128);
7384            if (prefix != null) {
7385                sb.append(prefix);
7386            }
7387            if (intent.getAction() != null) {
7388                sb.append(intent.getAction());
7389            } else if (intent.getComponent() != null) {
7390                intent.getComponent().appendShortString(sb);
7391            } else {
7392                sb.append("?");
7393            }
7394            return res.lastTag = sb.toString();
7395        }
7396        return null;
7397    }
7398
7399    @Override
7400    public void setProcessLimit(int max) {
7401        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7402                "setProcessLimit()");
7403        synchronized (this) {
7404            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7405            mProcessLimitOverride = max;
7406        }
7407        trimApplications();
7408    }
7409
7410    @Override
7411    public int getProcessLimit() {
7412        synchronized (this) {
7413            return mProcessLimitOverride;
7414        }
7415    }
7416
7417    void foregroundTokenDied(ForegroundToken token) {
7418        synchronized (ActivityManagerService.this) {
7419            synchronized (mPidsSelfLocked) {
7420                ForegroundToken cur
7421                    = mForegroundProcesses.get(token.pid);
7422                if (cur != token) {
7423                    return;
7424                }
7425                mForegroundProcesses.remove(token.pid);
7426                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7427                if (pr == null) {
7428                    return;
7429                }
7430                pr.forcingToForeground = null;
7431                updateProcessForegroundLocked(pr, false, false);
7432            }
7433            updateOomAdjLocked();
7434        }
7435    }
7436
7437    @Override
7438    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7439        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7440                "setProcessForeground()");
7441        synchronized(this) {
7442            boolean changed = false;
7443
7444            synchronized (mPidsSelfLocked) {
7445                ProcessRecord pr = mPidsSelfLocked.get(pid);
7446                if (pr == null && isForeground) {
7447                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7448                    return;
7449                }
7450                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7451                if (oldToken != null) {
7452                    oldToken.token.unlinkToDeath(oldToken, 0);
7453                    mForegroundProcesses.remove(pid);
7454                    if (pr != null) {
7455                        pr.forcingToForeground = null;
7456                    }
7457                    changed = true;
7458                }
7459                if (isForeground && token != null) {
7460                    ForegroundToken newToken = new ForegroundToken() {
7461                        @Override
7462                        public void binderDied() {
7463                            foregroundTokenDied(this);
7464                        }
7465                    };
7466                    newToken.pid = pid;
7467                    newToken.token = token;
7468                    try {
7469                        token.linkToDeath(newToken, 0);
7470                        mForegroundProcesses.put(pid, newToken);
7471                        pr.forcingToForeground = token;
7472                        changed = true;
7473                    } catch (RemoteException e) {
7474                        // If the process died while doing this, we will later
7475                        // do the cleanup with the process death link.
7476                    }
7477                }
7478            }
7479
7480            if (changed) {
7481                updateOomAdjLocked();
7482            }
7483        }
7484    }
7485
7486    @Override
7487    public boolean isAppForeground(int uid) throws RemoteException {
7488        synchronized (this) {
7489            UidRecord uidRec = mActiveUids.get(uid);
7490            if (uidRec == null || uidRec.idle) {
7491                return false;
7492            }
7493            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7494        }
7495    }
7496
7497    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7498    // be guarded by permission checking.
7499    int getUidState(int uid) {
7500        synchronized (this) {
7501            UidRecord uidRec = mActiveUids.get(uid);
7502            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7503        }
7504    }
7505
7506    @Override
7507    public boolean isInMultiWindowMode(IBinder token) {
7508        final long origId = Binder.clearCallingIdentity();
7509        try {
7510            synchronized(this) {
7511                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7512                if (r == null) {
7513                    return false;
7514                }
7515                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7516                return !r.task.mFullscreen;
7517            }
7518        } finally {
7519            Binder.restoreCallingIdentity(origId);
7520        }
7521    }
7522
7523    @Override
7524    public boolean isInPictureInPictureMode(IBinder token) {
7525        final long origId = Binder.clearCallingIdentity();
7526        try {
7527            synchronized(this) {
7528                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7529                if (stack == null) {
7530                    return false;
7531                }
7532                return stack.mStackId == PINNED_STACK_ID;
7533            }
7534        } finally {
7535            Binder.restoreCallingIdentity(origId);
7536        }
7537    }
7538
7539    @Override
7540    public void enterPictureInPictureMode(IBinder token) {
7541        final long origId = Binder.clearCallingIdentity();
7542        try {
7543            synchronized(this) {
7544                if (!mSupportsPictureInPicture) {
7545                    throw new IllegalStateException("enterPictureInPictureMode: "
7546                            + "Device doesn't support picture-in-picture mode.");
7547                }
7548
7549                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7550
7551                if (r == null) {
7552                    throw new IllegalStateException("enterPictureInPictureMode: "
7553                            + "Can't find activity for token=" + token);
7554                }
7555
7556                if (!r.supportsPictureInPicture()) {
7557                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7558                            + "Picture-In-Picture not supported for r=" + r);
7559                }
7560
7561                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7562                // current bounds.
7563                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7564                final Rect bounds = (pinnedStack != null)
7565                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7566
7567                mStackSupervisor.moveActivityToPinnedStackLocked(
7568                        r, "enterPictureInPictureMode", bounds);
7569            }
7570        } finally {
7571            Binder.restoreCallingIdentity(origId);
7572        }
7573    }
7574
7575    // =========================================================
7576    // PROCESS INFO
7577    // =========================================================
7578
7579    static class ProcessInfoService extends IProcessInfoService.Stub {
7580        final ActivityManagerService mActivityManagerService;
7581        ProcessInfoService(ActivityManagerService activityManagerService) {
7582            mActivityManagerService = activityManagerService;
7583        }
7584
7585        @Override
7586        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7587            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7588                    /*in*/ pids, /*out*/ states, null);
7589        }
7590
7591        @Override
7592        public void getProcessStatesAndOomScoresFromPids(
7593                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7594            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7595                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7596        }
7597    }
7598
7599    /**
7600     * For each PID in the given input array, write the current process state
7601     * for that process into the states array, or -1 to indicate that no
7602     * process with the given PID exists. If scores array is provided, write
7603     * the oom score for the process into the scores array, with INVALID_ADJ
7604     * indicating the PID doesn't exist.
7605     */
7606    public void getProcessStatesAndOomScoresForPIDs(
7607            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7608        if (scores != null) {
7609            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7610                    "getProcessStatesAndOomScoresForPIDs()");
7611        }
7612
7613        if (pids == null) {
7614            throw new NullPointerException("pids");
7615        } else if (states == null) {
7616            throw new NullPointerException("states");
7617        } else if (pids.length != states.length) {
7618            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7619        } else if (scores != null && pids.length != scores.length) {
7620            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7621        }
7622
7623        synchronized (mPidsSelfLocked) {
7624            for (int i = 0; i < pids.length; i++) {
7625                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7626                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7627                        pr.curProcState;
7628                if (scores != null) {
7629                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7630                }
7631            }
7632        }
7633    }
7634
7635    // =========================================================
7636    // PERMISSIONS
7637    // =========================================================
7638
7639    static class PermissionController extends IPermissionController.Stub {
7640        ActivityManagerService mActivityManagerService;
7641        PermissionController(ActivityManagerService activityManagerService) {
7642            mActivityManagerService = activityManagerService;
7643        }
7644
7645        @Override
7646        public boolean checkPermission(String permission, int pid, int uid) {
7647            return mActivityManagerService.checkPermission(permission, pid,
7648                    uid) == PackageManager.PERMISSION_GRANTED;
7649        }
7650
7651        @Override
7652        public String[] getPackagesForUid(int uid) {
7653            return mActivityManagerService.mContext.getPackageManager()
7654                    .getPackagesForUid(uid);
7655        }
7656
7657        @Override
7658        public boolean isRuntimePermission(String permission) {
7659            try {
7660                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7661                        .getPermissionInfo(permission, 0);
7662                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7663            } catch (NameNotFoundException nnfe) {
7664                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7665            }
7666            return false;
7667        }
7668    }
7669
7670    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7671        @Override
7672        public int checkComponentPermission(String permission, int pid, int uid,
7673                int owningUid, boolean exported) {
7674            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7675                    owningUid, exported);
7676        }
7677
7678        @Override
7679        public Object getAMSLock() {
7680            return ActivityManagerService.this;
7681        }
7682    }
7683
7684    /**
7685     * This can be called with or without the global lock held.
7686     */
7687    int checkComponentPermission(String permission, int pid, int uid,
7688            int owningUid, boolean exported) {
7689        if (pid == MY_PID) {
7690            return PackageManager.PERMISSION_GRANTED;
7691        }
7692        return ActivityManager.checkComponentPermission(permission, uid,
7693                owningUid, exported);
7694    }
7695
7696    /**
7697     * As the only public entry point for permissions checking, this method
7698     * can enforce the semantic that requesting a check on a null global
7699     * permission is automatically denied.  (Internally a null permission
7700     * string is used when calling {@link #checkComponentPermission} in cases
7701     * when only uid-based security is needed.)
7702     *
7703     * This can be called with or without the global lock held.
7704     */
7705    @Override
7706    public int checkPermission(String permission, int pid, int uid) {
7707        if (permission == null) {
7708            return PackageManager.PERMISSION_DENIED;
7709        }
7710        return checkComponentPermission(permission, pid, uid, -1, true);
7711    }
7712
7713    @Override
7714    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7715        if (permission == null) {
7716            return PackageManager.PERMISSION_DENIED;
7717        }
7718
7719        // We might be performing an operation on behalf of an indirect binder
7720        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7721        // client identity accordingly before proceeding.
7722        Identity tlsIdentity = sCallerIdentity.get();
7723        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7724            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7725                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7726            uid = tlsIdentity.uid;
7727            pid = tlsIdentity.pid;
7728        }
7729
7730        return checkComponentPermission(permission, pid, uid, -1, true);
7731    }
7732
7733    /**
7734     * Binder IPC calls go through the public entry point.
7735     * This can be called with or without the global lock held.
7736     */
7737    int checkCallingPermission(String permission) {
7738        return checkPermission(permission,
7739                Binder.getCallingPid(),
7740                UserHandle.getAppId(Binder.getCallingUid()));
7741    }
7742
7743    /**
7744     * This can be called with or without the global lock held.
7745     */
7746    void enforceCallingPermission(String permission, String func) {
7747        if (checkCallingPermission(permission)
7748                == PackageManager.PERMISSION_GRANTED) {
7749            return;
7750        }
7751
7752        String msg = "Permission Denial: " + func + " from pid="
7753                + Binder.getCallingPid()
7754                + ", uid=" + Binder.getCallingUid()
7755                + " requires " + permission;
7756        Slog.w(TAG, msg);
7757        throw new SecurityException(msg);
7758    }
7759
7760    /**
7761     * Determine if UID is holding permissions required to access {@link Uri} in
7762     * the given {@link ProviderInfo}. Final permission checking is always done
7763     * in {@link ContentProvider}.
7764     */
7765    private final boolean checkHoldingPermissionsLocked(
7766            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7767        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7769        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7770            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7771                    != PERMISSION_GRANTED) {
7772                return false;
7773            }
7774        }
7775        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7776    }
7777
7778    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7779            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7780        if (pi.applicationInfo.uid == uid) {
7781            return true;
7782        } else if (!pi.exported) {
7783            return false;
7784        }
7785
7786        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7787        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7788        try {
7789            // check if target holds top-level <provider> permissions
7790            if (!readMet && pi.readPermission != null && considerUidPermissions
7791                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7792                readMet = true;
7793            }
7794            if (!writeMet && pi.writePermission != null && considerUidPermissions
7795                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7796                writeMet = true;
7797            }
7798
7799            // track if unprotected read/write is allowed; any denied
7800            // <path-permission> below removes this ability
7801            boolean allowDefaultRead = pi.readPermission == null;
7802            boolean allowDefaultWrite = pi.writePermission == null;
7803
7804            // check if target holds any <path-permission> that match uri
7805            final PathPermission[] pps = pi.pathPermissions;
7806            if (pps != null) {
7807                final String path = grantUri.uri.getPath();
7808                int i = pps.length;
7809                while (i > 0 && (!readMet || !writeMet)) {
7810                    i--;
7811                    PathPermission pp = pps[i];
7812                    if (pp.match(path)) {
7813                        if (!readMet) {
7814                            final String pprperm = pp.getReadPermission();
7815                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7816                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7817                                    + ": match=" + pp.match(path)
7818                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7819                            if (pprperm != null) {
7820                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7821                                        == PERMISSION_GRANTED) {
7822                                    readMet = true;
7823                                } else {
7824                                    allowDefaultRead = false;
7825                                }
7826                            }
7827                        }
7828                        if (!writeMet) {
7829                            final String ppwperm = pp.getWritePermission();
7830                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7831                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7832                                    + ": match=" + pp.match(path)
7833                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7834                            if (ppwperm != null) {
7835                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7836                                        == PERMISSION_GRANTED) {
7837                                    writeMet = true;
7838                                } else {
7839                                    allowDefaultWrite = false;
7840                                }
7841                            }
7842                        }
7843                    }
7844                }
7845            }
7846
7847            // grant unprotected <provider> read/write, if not blocked by
7848            // <path-permission> above
7849            if (allowDefaultRead) readMet = true;
7850            if (allowDefaultWrite) writeMet = true;
7851
7852        } catch (RemoteException e) {
7853            return false;
7854        }
7855
7856        return readMet && writeMet;
7857    }
7858
7859    public int getAppStartMode(int uid, String packageName) {
7860        synchronized (this) {
7861            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7862        }
7863    }
7864
7865    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7866            boolean allowWhenForeground) {
7867        UidRecord uidRec = mActiveUids.get(uid);
7868        if (!mLenientBackgroundCheck) {
7869            if (!allowWhenForeground || uidRec == null
7870                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7871                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7872                        packageName) != AppOpsManager.MODE_ALLOWED) {
7873                    return ActivityManager.APP_START_MODE_DELAYED;
7874                }
7875            }
7876
7877        } else if (uidRec == null || uidRec.idle) {
7878            if (callingPid >= 0) {
7879                ProcessRecord proc;
7880                synchronized (mPidsSelfLocked) {
7881                    proc = mPidsSelfLocked.get(callingPid);
7882                }
7883                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7884                    // Whoever is instigating this is in the foreground, so we will allow it
7885                    // to go through.
7886                    return ActivityManager.APP_START_MODE_NORMAL;
7887                }
7888            }
7889            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7890                    != AppOpsManager.MODE_ALLOWED) {
7891                return ActivityManager.APP_START_MODE_DELAYED;
7892            }
7893        }
7894        return ActivityManager.APP_START_MODE_NORMAL;
7895    }
7896
7897    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7898        ProviderInfo pi = null;
7899        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7900        if (cpr != null) {
7901            pi = cpr.info;
7902        } else {
7903            try {
7904                pi = AppGlobals.getPackageManager().resolveContentProvider(
7905                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7906                        userHandle);
7907            } catch (RemoteException ex) {
7908            }
7909        }
7910        return pi;
7911    }
7912
7913    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7914        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7915        if (targetUris != null) {
7916            return targetUris.get(grantUri);
7917        }
7918        return null;
7919    }
7920
7921    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7922            String targetPkg, int targetUid, GrantUri grantUri) {
7923        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7924        if (targetUris == null) {
7925            targetUris = Maps.newArrayMap();
7926            mGrantedUriPermissions.put(targetUid, targetUris);
7927        }
7928
7929        UriPermission perm = targetUris.get(grantUri);
7930        if (perm == null) {
7931            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7932            targetUris.put(grantUri, perm);
7933        }
7934
7935        return perm;
7936    }
7937
7938    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7939            final int modeFlags) {
7940        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7941        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7942                : UriPermission.STRENGTH_OWNED;
7943
7944        // Root gets to do everything.
7945        if (uid == 0) {
7946            return true;
7947        }
7948
7949        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7950        if (perms == null) return false;
7951
7952        // First look for exact match
7953        final UriPermission exactPerm = perms.get(grantUri);
7954        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7955            return true;
7956        }
7957
7958        // No exact match, look for prefixes
7959        final int N = perms.size();
7960        for (int i = 0; i < N; i++) {
7961            final UriPermission perm = perms.valueAt(i);
7962            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7963                    && perm.getStrength(modeFlags) >= minStrength) {
7964                return true;
7965            }
7966        }
7967
7968        return false;
7969    }
7970
7971    /**
7972     * @param uri This uri must NOT contain an embedded userId.
7973     * @param userId The userId in which the uri is to be resolved.
7974     */
7975    @Override
7976    public int checkUriPermission(Uri uri, int pid, int uid,
7977            final int modeFlags, int userId, IBinder callerToken) {
7978        enforceNotIsolatedCaller("checkUriPermission");
7979
7980        // Another redirected-binder-call permissions check as in
7981        // {@link checkPermissionWithToken}.
7982        Identity tlsIdentity = sCallerIdentity.get();
7983        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7984            uid = tlsIdentity.uid;
7985            pid = tlsIdentity.pid;
7986        }
7987
7988        // Our own process gets to do everything.
7989        if (pid == MY_PID) {
7990            return PackageManager.PERMISSION_GRANTED;
7991        }
7992        synchronized (this) {
7993            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7994                    ? PackageManager.PERMISSION_GRANTED
7995                    : PackageManager.PERMISSION_DENIED;
7996        }
7997    }
7998
7999    /**
8000     * Check if the targetPkg can be granted permission to access uri by
8001     * the callingUid using the given modeFlags.  Throws a security exception
8002     * if callingUid is not allowed to do this.  Returns the uid of the target
8003     * if the URI permission grant should be performed; returns -1 if it is not
8004     * needed (for example targetPkg already has permission to access the URI).
8005     * If you already know the uid of the target, you can supply it in
8006     * lastTargetUid else set that to -1.
8007     */
8008    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8009            final int modeFlags, int lastTargetUid) {
8010        if (!Intent.isAccessUriMode(modeFlags)) {
8011            return -1;
8012        }
8013
8014        if (targetPkg != null) {
8015            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8016                    "Checking grant " + targetPkg + " permission to " + grantUri);
8017        }
8018
8019        final IPackageManager pm = AppGlobals.getPackageManager();
8020
8021        // If this is not a content: uri, we can't do anything with it.
8022        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8023            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8024                    "Can't grant URI permission for non-content URI: " + grantUri);
8025            return -1;
8026        }
8027
8028        final String authority = grantUri.uri.getAuthority();
8029        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8030                MATCH_DEBUG_TRIAGED_MISSING);
8031        if (pi == null) {
8032            Slog.w(TAG, "No content provider found for permission check: " +
8033                    grantUri.uri.toSafeString());
8034            return -1;
8035        }
8036
8037        int targetUid = lastTargetUid;
8038        if (targetUid < 0 && targetPkg != null) {
8039            try {
8040                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8041                        UserHandle.getUserId(callingUid));
8042                if (targetUid < 0) {
8043                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8044                            "Can't grant URI permission no uid for: " + targetPkg);
8045                    return -1;
8046                }
8047            } catch (RemoteException ex) {
8048                return -1;
8049            }
8050        }
8051
8052        if (targetUid >= 0) {
8053            // First...  does the target actually need this permission?
8054            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8055                // No need to grant the target this permission.
8056                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8057                        "Target " + targetPkg + " already has full permission to " + grantUri);
8058                return -1;
8059            }
8060        } else {
8061            // First...  there is no target package, so can anyone access it?
8062            boolean allowed = pi.exported;
8063            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8064                if (pi.readPermission != null) {
8065                    allowed = false;
8066                }
8067            }
8068            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8069                if (pi.writePermission != null) {
8070                    allowed = false;
8071                }
8072            }
8073            if (allowed) {
8074                return -1;
8075            }
8076        }
8077
8078        /* There is a special cross user grant if:
8079         * - The target is on another user.
8080         * - Apps on the current user can access the uri without any uid permissions.
8081         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8082         * grant uri permissions.
8083         */
8084        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8085                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8086                modeFlags, false /*without considering the uid permissions*/);
8087
8088        // Second...  is the provider allowing granting of URI permissions?
8089        if (!specialCrossUserGrant) {
8090            if (!pi.grantUriPermissions) {
8091                throw new SecurityException("Provider " + pi.packageName
8092                        + "/" + pi.name
8093                        + " does not allow granting of Uri permissions (uri "
8094                        + grantUri + ")");
8095            }
8096            if (pi.uriPermissionPatterns != null) {
8097                final int N = pi.uriPermissionPatterns.length;
8098                boolean allowed = false;
8099                for (int i=0; i<N; i++) {
8100                    if (pi.uriPermissionPatterns[i] != null
8101                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8102                        allowed = true;
8103                        break;
8104                    }
8105                }
8106                if (!allowed) {
8107                    throw new SecurityException("Provider " + pi.packageName
8108                            + "/" + pi.name
8109                            + " does not allow granting of permission to path of Uri "
8110                            + grantUri);
8111                }
8112            }
8113        }
8114
8115        // Third...  does the caller itself have permission to access
8116        // this uri?
8117        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8118            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8119                // Require they hold a strong enough Uri permission
8120                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8121                    throw new SecurityException("Uid " + callingUid
8122                            + " does not have permission to uri " + grantUri);
8123                }
8124            }
8125        }
8126        return targetUid;
8127    }
8128
8129    /**
8130     * @param uri This uri must NOT contain an embedded userId.
8131     * @param userId The userId in which the uri is to be resolved.
8132     */
8133    @Override
8134    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8135            final int modeFlags, int userId) {
8136        enforceNotIsolatedCaller("checkGrantUriPermission");
8137        synchronized(this) {
8138            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8139                    new GrantUri(userId, uri, false), modeFlags, -1);
8140        }
8141    }
8142
8143    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8144            final int modeFlags, UriPermissionOwner owner) {
8145        if (!Intent.isAccessUriMode(modeFlags)) {
8146            return;
8147        }
8148
8149        // So here we are: the caller has the assumed permission
8150        // to the uri, and the target doesn't.  Let's now give this to
8151        // the target.
8152
8153        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8154                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8155
8156        final String authority = grantUri.uri.getAuthority();
8157        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8158                MATCH_DEBUG_TRIAGED_MISSING);
8159        if (pi == null) {
8160            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8161            return;
8162        }
8163
8164        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8165            grantUri.prefix = true;
8166        }
8167        final UriPermission perm = findOrCreateUriPermissionLocked(
8168                pi.packageName, targetPkg, targetUid, grantUri);
8169        perm.grantModes(modeFlags, owner);
8170    }
8171
8172    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8173            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8174        if (targetPkg == null) {
8175            throw new NullPointerException("targetPkg");
8176        }
8177        int targetUid;
8178        final IPackageManager pm = AppGlobals.getPackageManager();
8179        try {
8180            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8181        } catch (RemoteException ex) {
8182            return;
8183        }
8184
8185        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8186                targetUid);
8187        if (targetUid < 0) {
8188            return;
8189        }
8190
8191        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8192                owner);
8193    }
8194
8195    static class NeededUriGrants extends ArrayList<GrantUri> {
8196        final String targetPkg;
8197        final int targetUid;
8198        final int flags;
8199
8200        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8201            this.targetPkg = targetPkg;
8202            this.targetUid = targetUid;
8203            this.flags = flags;
8204        }
8205    }
8206
8207    /**
8208     * Like checkGrantUriPermissionLocked, but takes an Intent.
8209     */
8210    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8211            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8212        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8213                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8214                + " clip=" + (intent != null ? intent.getClipData() : null)
8215                + " from " + intent + "; flags=0x"
8216                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8217
8218        if (targetPkg == null) {
8219            throw new NullPointerException("targetPkg");
8220        }
8221
8222        if (intent == null) {
8223            return null;
8224        }
8225        Uri data = intent.getData();
8226        ClipData clip = intent.getClipData();
8227        if (data == null && clip == null) {
8228            return null;
8229        }
8230        // Default userId for uris in the intent (if they don't specify it themselves)
8231        int contentUserHint = intent.getContentUserHint();
8232        if (contentUserHint == UserHandle.USER_CURRENT) {
8233            contentUserHint = UserHandle.getUserId(callingUid);
8234        }
8235        final IPackageManager pm = AppGlobals.getPackageManager();
8236        int targetUid;
8237        if (needed != null) {
8238            targetUid = needed.targetUid;
8239        } else {
8240            try {
8241                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8242                        targetUserId);
8243            } catch (RemoteException ex) {
8244                return null;
8245            }
8246            if (targetUid < 0) {
8247                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8248                        "Can't grant URI permission no uid for: " + targetPkg
8249                        + " on user " + targetUserId);
8250                return null;
8251            }
8252        }
8253        if (data != null) {
8254            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8255            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8256                    targetUid);
8257            if (targetUid > 0) {
8258                if (needed == null) {
8259                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8260                }
8261                needed.add(grantUri);
8262            }
8263        }
8264        if (clip != null) {
8265            for (int i=0; i<clip.getItemCount(); i++) {
8266                Uri uri = clip.getItemAt(i).getUri();
8267                if (uri != null) {
8268                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8269                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8270                            targetUid);
8271                    if (targetUid > 0) {
8272                        if (needed == null) {
8273                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8274                        }
8275                        needed.add(grantUri);
8276                    }
8277                } else {
8278                    Intent clipIntent = clip.getItemAt(i).getIntent();
8279                    if (clipIntent != null) {
8280                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8281                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8282                        if (newNeeded != null) {
8283                            needed = newNeeded;
8284                        }
8285                    }
8286                }
8287            }
8288        }
8289
8290        return needed;
8291    }
8292
8293    /**
8294     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8295     */
8296    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8297            UriPermissionOwner owner) {
8298        if (needed != null) {
8299            for (int i=0; i<needed.size(); i++) {
8300                GrantUri grantUri = needed.get(i);
8301                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8302                        grantUri, needed.flags, owner);
8303            }
8304        }
8305    }
8306
8307    void grantUriPermissionFromIntentLocked(int callingUid,
8308            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8309        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8310                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8311        if (needed == null) {
8312            return;
8313        }
8314
8315        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8316    }
8317
8318    /**
8319     * @param uri This uri must NOT contain an embedded userId.
8320     * @param userId The userId in which the uri is to be resolved.
8321     */
8322    @Override
8323    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8324            final int modeFlags, int userId) {
8325        enforceNotIsolatedCaller("grantUriPermission");
8326        GrantUri grantUri = new GrantUri(userId, uri, false);
8327        synchronized(this) {
8328            final ProcessRecord r = getRecordForAppLocked(caller);
8329            if (r == null) {
8330                throw new SecurityException("Unable to find app for caller "
8331                        + caller
8332                        + " when granting permission to uri " + grantUri);
8333            }
8334            if (targetPkg == null) {
8335                throw new IllegalArgumentException("null target");
8336            }
8337            if (grantUri == null) {
8338                throw new IllegalArgumentException("null uri");
8339            }
8340
8341            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8342                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8343                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8344                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8345
8346            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8347                    UserHandle.getUserId(r.uid));
8348        }
8349    }
8350
8351    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8352        if (perm.modeFlags == 0) {
8353            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8354                    perm.targetUid);
8355            if (perms != null) {
8356                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8357                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8358
8359                perms.remove(perm.uri);
8360                if (perms.isEmpty()) {
8361                    mGrantedUriPermissions.remove(perm.targetUid);
8362                }
8363            }
8364        }
8365    }
8366
8367    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8368        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8369                "Revoking all granted permissions to " + grantUri);
8370
8371        final IPackageManager pm = AppGlobals.getPackageManager();
8372        final String authority = grantUri.uri.getAuthority();
8373        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8374                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8375        if (pi == null) {
8376            Slog.w(TAG, "No content provider found for permission revoke: "
8377                    + grantUri.toSafeString());
8378            return;
8379        }
8380
8381        // Does the caller have this permission on the URI?
8382        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8383            // If they don't have direct access to the URI, then revoke any
8384            // ownerless URI permissions that have been granted to them.
8385            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8386            if (perms != null) {
8387                boolean persistChanged = false;
8388                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8389                    final UriPermission perm = it.next();
8390                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8391                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8392                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8393                                "Revoking non-owned " + perm.targetUid
8394                                + " permission to " + perm.uri);
8395                        persistChanged |= perm.revokeModes(
8396                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8397                        if (perm.modeFlags == 0) {
8398                            it.remove();
8399                        }
8400                    }
8401                }
8402                if (perms.isEmpty()) {
8403                    mGrantedUriPermissions.remove(callingUid);
8404                }
8405                if (persistChanged) {
8406                    schedulePersistUriGrants();
8407                }
8408            }
8409            return;
8410        }
8411
8412        boolean persistChanged = false;
8413
8414        // Go through all of the permissions and remove any that match.
8415        int N = mGrantedUriPermissions.size();
8416        for (int i = 0; i < N; i++) {
8417            final int targetUid = mGrantedUriPermissions.keyAt(i);
8418            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8419
8420            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8421                final UriPermission perm = it.next();
8422                if (perm.uri.sourceUserId == grantUri.sourceUserId
8423                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8424                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8425                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8426                    persistChanged |= perm.revokeModes(
8427                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8428                    if (perm.modeFlags == 0) {
8429                        it.remove();
8430                    }
8431                }
8432            }
8433
8434            if (perms.isEmpty()) {
8435                mGrantedUriPermissions.remove(targetUid);
8436                N--;
8437                i--;
8438            }
8439        }
8440
8441        if (persistChanged) {
8442            schedulePersistUriGrants();
8443        }
8444    }
8445
8446    /**
8447     * @param uri This uri must NOT contain an embedded userId.
8448     * @param userId The userId in which the uri is to be resolved.
8449     */
8450    @Override
8451    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8452            int userId) {
8453        enforceNotIsolatedCaller("revokeUriPermission");
8454        synchronized(this) {
8455            final ProcessRecord r = getRecordForAppLocked(caller);
8456            if (r == null) {
8457                throw new SecurityException("Unable to find app for caller "
8458                        + caller
8459                        + " when revoking permission to uri " + uri);
8460            }
8461            if (uri == null) {
8462                Slog.w(TAG, "revokeUriPermission: null uri");
8463                return;
8464            }
8465
8466            if (!Intent.isAccessUriMode(modeFlags)) {
8467                return;
8468            }
8469
8470            final String authority = uri.getAuthority();
8471            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8472                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8473            if (pi == null) {
8474                Slog.w(TAG, "No content provider found for permission revoke: "
8475                        + uri.toSafeString());
8476                return;
8477            }
8478
8479            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8480        }
8481    }
8482
8483    /**
8484     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8485     * given package.
8486     *
8487     * @param packageName Package name to match, or {@code null} to apply to all
8488     *            packages.
8489     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8490     *            to all users.
8491     * @param persistable If persistable grants should be removed.
8492     */
8493    private void removeUriPermissionsForPackageLocked(
8494            String packageName, int userHandle, boolean persistable) {
8495        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8496            throw new IllegalArgumentException("Must narrow by either package or user");
8497        }
8498
8499        boolean persistChanged = false;
8500
8501        int N = mGrantedUriPermissions.size();
8502        for (int i = 0; i < N; i++) {
8503            final int targetUid = mGrantedUriPermissions.keyAt(i);
8504            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8505
8506            // Only inspect grants matching user
8507            if (userHandle == UserHandle.USER_ALL
8508                    || userHandle == UserHandle.getUserId(targetUid)) {
8509                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8510                    final UriPermission perm = it.next();
8511
8512                    // Only inspect grants matching package
8513                    if (packageName == null || perm.sourcePkg.equals(packageName)
8514                            || perm.targetPkg.equals(packageName)) {
8515                        persistChanged |= perm.revokeModes(persistable
8516                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8517
8518                        // Only remove when no modes remain; any persisted grants
8519                        // will keep this alive.
8520                        if (perm.modeFlags == 0) {
8521                            it.remove();
8522                        }
8523                    }
8524                }
8525
8526                if (perms.isEmpty()) {
8527                    mGrantedUriPermissions.remove(targetUid);
8528                    N--;
8529                    i--;
8530                }
8531            }
8532        }
8533
8534        if (persistChanged) {
8535            schedulePersistUriGrants();
8536        }
8537    }
8538
8539    @Override
8540    public IBinder newUriPermissionOwner(String name) {
8541        enforceNotIsolatedCaller("newUriPermissionOwner");
8542        synchronized(this) {
8543            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8544            return owner.getExternalTokenLocked();
8545        }
8546    }
8547
8548    @Override
8549    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8550        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8551        synchronized(this) {
8552            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8553            if (r == null) {
8554                throw new IllegalArgumentException("Activity does not exist; token="
8555                        + activityToken);
8556            }
8557            return r.getUriPermissionsLocked().getExternalTokenLocked();
8558        }
8559    }
8560    /**
8561     * @param uri This uri must NOT contain an embedded userId.
8562     * @param sourceUserId The userId in which the uri is to be resolved.
8563     * @param targetUserId The userId of the app that receives the grant.
8564     */
8565    @Override
8566    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8567            final int modeFlags, int sourceUserId, int targetUserId) {
8568        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8569                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8570                "grantUriPermissionFromOwner", null);
8571        synchronized(this) {
8572            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8573            if (owner == null) {
8574                throw new IllegalArgumentException("Unknown owner: " + token);
8575            }
8576            if (fromUid != Binder.getCallingUid()) {
8577                if (Binder.getCallingUid() != Process.myUid()) {
8578                    // Only system code can grant URI permissions on behalf
8579                    // of other users.
8580                    throw new SecurityException("nice try");
8581                }
8582            }
8583            if (targetPkg == null) {
8584                throw new IllegalArgumentException("null target");
8585            }
8586            if (uri == null) {
8587                throw new IllegalArgumentException("null uri");
8588            }
8589
8590            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8591                    modeFlags, owner, targetUserId);
8592        }
8593    }
8594
8595    /**
8596     * @param uri This uri must NOT contain an embedded userId.
8597     * @param userId The userId in which the uri is to be resolved.
8598     */
8599    @Override
8600    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8601        synchronized(this) {
8602            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8603            if (owner == null) {
8604                throw new IllegalArgumentException("Unknown owner: " + token);
8605            }
8606
8607            if (uri == null) {
8608                owner.removeUriPermissionsLocked(mode);
8609            } else {
8610                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8611            }
8612        }
8613    }
8614
8615    private void schedulePersistUriGrants() {
8616        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8617            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8618                    10 * DateUtils.SECOND_IN_MILLIS);
8619        }
8620    }
8621
8622    private void writeGrantedUriPermissions() {
8623        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8624
8625        // Snapshot permissions so we can persist without lock
8626        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8627        synchronized (this) {
8628            final int size = mGrantedUriPermissions.size();
8629            for (int i = 0; i < size; i++) {
8630                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8631                for (UriPermission perm : perms.values()) {
8632                    if (perm.persistedModeFlags != 0) {
8633                        persist.add(perm.snapshot());
8634                    }
8635                }
8636            }
8637        }
8638
8639        FileOutputStream fos = null;
8640        try {
8641            fos = mGrantFile.startWrite();
8642
8643            XmlSerializer out = new FastXmlSerializer();
8644            out.setOutput(fos, StandardCharsets.UTF_8.name());
8645            out.startDocument(null, true);
8646            out.startTag(null, TAG_URI_GRANTS);
8647            for (UriPermission.Snapshot perm : persist) {
8648                out.startTag(null, TAG_URI_GRANT);
8649                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8650                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8651                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8652                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8653                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8654                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8655                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8656                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8657                out.endTag(null, TAG_URI_GRANT);
8658            }
8659            out.endTag(null, TAG_URI_GRANTS);
8660            out.endDocument();
8661
8662            mGrantFile.finishWrite(fos);
8663        } catch (IOException e) {
8664            if (fos != null) {
8665                mGrantFile.failWrite(fos);
8666            }
8667        }
8668    }
8669
8670    private void readGrantedUriPermissionsLocked() {
8671        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8672
8673        final long now = System.currentTimeMillis();
8674
8675        FileInputStream fis = null;
8676        try {
8677            fis = mGrantFile.openRead();
8678            final XmlPullParser in = Xml.newPullParser();
8679            in.setInput(fis, StandardCharsets.UTF_8.name());
8680
8681            int type;
8682            while ((type = in.next()) != END_DOCUMENT) {
8683                final String tag = in.getName();
8684                if (type == START_TAG) {
8685                    if (TAG_URI_GRANT.equals(tag)) {
8686                        final int sourceUserId;
8687                        final int targetUserId;
8688                        final int userHandle = readIntAttribute(in,
8689                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8690                        if (userHandle != UserHandle.USER_NULL) {
8691                            // For backwards compatibility.
8692                            sourceUserId = userHandle;
8693                            targetUserId = userHandle;
8694                        } else {
8695                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8696                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8697                        }
8698                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8699                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8700                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8701                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8702                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8703                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8704
8705                        // Sanity check that provider still belongs to source package
8706                        // Both direct boot aware and unaware packages are fine as we
8707                        // will do filtering at query time to avoid multiple parsing.
8708                        final ProviderInfo pi = getProviderInfoLocked(
8709                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8710                                        | MATCH_DIRECT_BOOT_UNAWARE);
8711                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8712                            int targetUid = -1;
8713                            try {
8714                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8715                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8716                            } catch (RemoteException e) {
8717                            }
8718                            if (targetUid != -1) {
8719                                final UriPermission perm = findOrCreateUriPermissionLocked(
8720                                        sourcePkg, targetPkg, targetUid,
8721                                        new GrantUri(sourceUserId, uri, prefix));
8722                                perm.initPersistedModes(modeFlags, createdTime);
8723                            }
8724                        } else {
8725                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8726                                    + " but instead found " + pi);
8727                        }
8728                    }
8729                }
8730            }
8731        } catch (FileNotFoundException e) {
8732            // Missing grants is okay
8733        } catch (IOException e) {
8734            Slog.wtf(TAG, "Failed reading Uri grants", e);
8735        } catch (XmlPullParserException e) {
8736            Slog.wtf(TAG, "Failed reading Uri grants", e);
8737        } finally {
8738            IoUtils.closeQuietly(fis);
8739        }
8740    }
8741
8742    /**
8743     * @param uri This uri must NOT contain an embedded userId.
8744     * @param userId The userId in which the uri is to be resolved.
8745     */
8746    @Override
8747    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8748        enforceNotIsolatedCaller("takePersistableUriPermission");
8749
8750        Preconditions.checkFlagsArgument(modeFlags,
8751                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8752
8753        synchronized (this) {
8754            final int callingUid = Binder.getCallingUid();
8755            boolean persistChanged = false;
8756            GrantUri grantUri = new GrantUri(userId, uri, false);
8757
8758            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8759                    new GrantUri(userId, uri, false));
8760            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8761                    new GrantUri(userId, uri, true));
8762
8763            final boolean exactValid = (exactPerm != null)
8764                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8765            final boolean prefixValid = (prefixPerm != null)
8766                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8767
8768            if (!(exactValid || prefixValid)) {
8769                throw new SecurityException("No persistable permission grants found for UID "
8770                        + callingUid + " and Uri " + grantUri.toSafeString());
8771            }
8772
8773            if (exactValid) {
8774                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8775            }
8776            if (prefixValid) {
8777                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8778            }
8779
8780            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8781
8782            if (persistChanged) {
8783                schedulePersistUriGrants();
8784            }
8785        }
8786    }
8787
8788    /**
8789     * @param uri This uri must NOT contain an embedded userId.
8790     * @param userId The userId in which the uri is to be resolved.
8791     */
8792    @Override
8793    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8794        enforceNotIsolatedCaller("releasePersistableUriPermission");
8795
8796        Preconditions.checkFlagsArgument(modeFlags,
8797                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8798
8799        synchronized (this) {
8800            final int callingUid = Binder.getCallingUid();
8801            boolean persistChanged = false;
8802
8803            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8804                    new GrantUri(userId, uri, false));
8805            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8806                    new GrantUri(userId, uri, true));
8807            if (exactPerm == null && prefixPerm == null) {
8808                throw new SecurityException("No permission grants found for UID " + callingUid
8809                        + " and Uri " + uri.toSafeString());
8810            }
8811
8812            if (exactPerm != null) {
8813                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8814                removeUriPermissionIfNeededLocked(exactPerm);
8815            }
8816            if (prefixPerm != null) {
8817                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8818                removeUriPermissionIfNeededLocked(prefixPerm);
8819            }
8820
8821            if (persistChanged) {
8822                schedulePersistUriGrants();
8823            }
8824        }
8825    }
8826
8827    /**
8828     * Prune any older {@link UriPermission} for the given UID until outstanding
8829     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8830     *
8831     * @return if any mutations occured that require persisting.
8832     */
8833    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8834        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8835        if (perms == null) return false;
8836        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8837
8838        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8839        for (UriPermission perm : perms.values()) {
8840            if (perm.persistedModeFlags != 0) {
8841                persisted.add(perm);
8842            }
8843        }
8844
8845        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8846        if (trimCount <= 0) return false;
8847
8848        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8849        for (int i = 0; i < trimCount; i++) {
8850            final UriPermission perm = persisted.get(i);
8851
8852            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8853                    "Trimming grant created at " + perm.persistedCreateTime);
8854
8855            perm.releasePersistableModes(~0);
8856            removeUriPermissionIfNeededLocked(perm);
8857        }
8858
8859        return true;
8860    }
8861
8862    @Override
8863    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8864            String packageName, boolean incoming) {
8865        enforceNotIsolatedCaller("getPersistedUriPermissions");
8866        Preconditions.checkNotNull(packageName, "packageName");
8867
8868        final int callingUid = Binder.getCallingUid();
8869        final int callingUserId = UserHandle.getUserId(callingUid);
8870        final IPackageManager pm = AppGlobals.getPackageManager();
8871        try {
8872            final int packageUid = pm.getPackageUid(packageName,
8873                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8874            if (packageUid != callingUid) {
8875                throw new SecurityException(
8876                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8877            }
8878        } catch (RemoteException e) {
8879            throw new SecurityException("Failed to verify package name ownership");
8880        }
8881
8882        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8883        synchronized (this) {
8884            if (incoming) {
8885                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8886                        callingUid);
8887                if (perms == null) {
8888                    Slog.w(TAG, "No permission grants found for " + packageName);
8889                } else {
8890                    for (UriPermission perm : perms.values()) {
8891                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8892                            result.add(perm.buildPersistedPublicApiObject());
8893                        }
8894                    }
8895                }
8896            } else {
8897                final int size = mGrantedUriPermissions.size();
8898                for (int i = 0; i < size; i++) {
8899                    final ArrayMap<GrantUri, UriPermission> perms =
8900                            mGrantedUriPermissions.valueAt(i);
8901                    for (UriPermission perm : perms.values()) {
8902                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8903                            result.add(perm.buildPersistedPublicApiObject());
8904                        }
8905                    }
8906                }
8907            }
8908        }
8909        return new ParceledListSlice<android.content.UriPermission>(result);
8910    }
8911
8912    @Override
8913    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8914            String packageName, int userId) {
8915        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8916                "getGrantedUriPermissions");
8917
8918        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8919        synchronized (this) {
8920            final int size = mGrantedUriPermissions.size();
8921            for (int i = 0; i < size; i++) {
8922                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8923                for (UriPermission perm : perms.values()) {
8924                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8925                            && perm.persistedModeFlags != 0) {
8926                        result.add(perm.buildPersistedPublicApiObject());
8927                    }
8928                }
8929            }
8930        }
8931        return new ParceledListSlice<android.content.UriPermission>(result);
8932    }
8933
8934    @Override
8935    public void clearGrantedUriPermissions(String packageName, int userId) {
8936        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8937                "clearGrantedUriPermissions");
8938        removeUriPermissionsForPackageLocked(packageName, userId, true);
8939    }
8940
8941    @Override
8942    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8943        synchronized (this) {
8944            ProcessRecord app =
8945                who != null ? getRecordForAppLocked(who) : null;
8946            if (app == null) return;
8947
8948            Message msg = Message.obtain();
8949            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8950            msg.obj = app;
8951            msg.arg1 = waiting ? 1 : 0;
8952            mUiHandler.sendMessage(msg);
8953        }
8954    }
8955
8956    @Override
8957    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8958        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8959        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8960        outInfo.availMem = Process.getFreeMemory();
8961        outInfo.totalMem = Process.getTotalMemory();
8962        outInfo.threshold = homeAppMem;
8963        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8964        outInfo.hiddenAppThreshold = cachedAppMem;
8965        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8966                ProcessList.SERVICE_ADJ);
8967        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8968                ProcessList.VISIBLE_APP_ADJ);
8969        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8970                ProcessList.FOREGROUND_APP_ADJ);
8971    }
8972
8973    // =========================================================
8974    // TASK MANAGEMENT
8975    // =========================================================
8976
8977    @Override
8978    public List<IAppTask> getAppTasks(String callingPackage) {
8979        int callingUid = Binder.getCallingUid();
8980        long ident = Binder.clearCallingIdentity();
8981
8982        synchronized(this) {
8983            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8984            try {
8985                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8986
8987                final int N = mRecentTasks.size();
8988                for (int i = 0; i < N; i++) {
8989                    TaskRecord tr = mRecentTasks.get(i);
8990                    // Skip tasks that do not match the caller.  We don't need to verify
8991                    // callingPackage, because we are also limiting to callingUid and know
8992                    // that will limit to the correct security sandbox.
8993                    if (tr.effectiveUid != callingUid) {
8994                        continue;
8995                    }
8996                    Intent intent = tr.getBaseIntent();
8997                    if (intent == null ||
8998                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8999                        continue;
9000                    }
9001                    ActivityManager.RecentTaskInfo taskInfo =
9002                            createRecentTaskInfoFromTaskRecord(tr);
9003                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9004                    list.add(taskImpl);
9005                }
9006            } finally {
9007                Binder.restoreCallingIdentity(ident);
9008            }
9009            return list;
9010        }
9011    }
9012
9013    @Override
9014    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9015        final int callingUid = Binder.getCallingUid();
9016        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9017
9018        synchronized(this) {
9019            if (DEBUG_ALL) Slog.v(
9020                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9021
9022            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9023                    callingUid);
9024
9025            // TODO: Improve with MRU list from all ActivityStacks.
9026            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9027        }
9028
9029        return list;
9030    }
9031
9032    /**
9033     * Creates a new RecentTaskInfo from a TaskRecord.
9034     */
9035    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9036        // Update the task description to reflect any changes in the task stack
9037        tr.updateTaskDescription();
9038
9039        // Compose the recent task info
9040        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9041        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9042        rti.persistentId = tr.taskId;
9043        rti.baseIntent = new Intent(tr.getBaseIntent());
9044        rti.origActivity = tr.origActivity;
9045        rti.realActivity = tr.realActivity;
9046        rti.description = tr.lastDescription;
9047        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9048        rti.userId = tr.userId;
9049        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9050        rti.firstActiveTime = tr.firstActiveTime;
9051        rti.lastActiveTime = tr.lastActiveTime;
9052        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9053        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9054        rti.numActivities = 0;
9055        if (tr.mBounds != null) {
9056            rti.bounds = new Rect(tr.mBounds);
9057        }
9058        rti.isDockable = tr.canGoInDockedStack();
9059        rti.resizeMode = tr.mResizeMode;
9060
9061        ActivityRecord base = null;
9062        ActivityRecord top = null;
9063        ActivityRecord tmp;
9064
9065        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9066            tmp = tr.mActivities.get(i);
9067            if (tmp.finishing) {
9068                continue;
9069            }
9070            base = tmp;
9071            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9072                top = base;
9073            }
9074            rti.numActivities++;
9075        }
9076
9077        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9078        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9079
9080        return rti;
9081    }
9082
9083    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9084        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9085                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9086        if (!allowed) {
9087            if (checkPermission(android.Manifest.permission.GET_TASKS,
9088                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9089                // Temporary compatibility: some existing apps on the system image may
9090                // still be requesting the old permission and not switched to the new
9091                // one; if so, we'll still allow them full access.  This means we need
9092                // to see if they are holding the old permission and are a system app.
9093                try {
9094                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9095                        allowed = true;
9096                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9097                                + " is using old GET_TASKS but privileged; allowing");
9098                    }
9099                } catch (RemoteException e) {
9100                }
9101            }
9102        }
9103        if (!allowed) {
9104            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9105                    + " does not hold REAL_GET_TASKS; limiting output");
9106        }
9107        return allowed;
9108    }
9109
9110    @Override
9111    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9112            int userId) {
9113        final int callingUid = Binder.getCallingUid();
9114        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9115                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9116
9117        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9118        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9119        synchronized (this) {
9120            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9121                    callingUid);
9122            final boolean detailed = checkCallingPermission(
9123                    android.Manifest.permission.GET_DETAILED_TASKS)
9124                    == PackageManager.PERMISSION_GRANTED;
9125
9126            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9127                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9128                return ParceledListSlice.emptyList();
9129            }
9130            mRecentTasks.loadUserRecentsLocked(userId);
9131
9132            final int recentsCount = mRecentTasks.size();
9133            ArrayList<ActivityManager.RecentTaskInfo> res =
9134                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9135
9136            final Set<Integer> includedUsers;
9137            if (includeProfiles) {
9138                includedUsers = mUserController.getProfileIds(userId);
9139            } else {
9140                includedUsers = new HashSet<>();
9141            }
9142            includedUsers.add(Integer.valueOf(userId));
9143
9144            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9145                TaskRecord tr = mRecentTasks.get(i);
9146                // Only add calling user or related users recent tasks
9147                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9148                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9149                    continue;
9150                }
9151
9152                if (tr.realActivitySuspended) {
9153                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9154                    continue;
9155                }
9156
9157                // Return the entry if desired by the caller.  We always return
9158                // the first entry, because callers always expect this to be the
9159                // foreground app.  We may filter others if the caller has
9160                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9161                // we should exclude the entry.
9162
9163                if (i == 0
9164                        || withExcluded
9165                        || (tr.intent == null)
9166                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9167                                == 0)) {
9168                    if (!allowed) {
9169                        // If the caller doesn't have the GET_TASKS permission, then only
9170                        // allow them to see a small subset of tasks -- their own and home.
9171                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9172                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9173                            continue;
9174                        }
9175                    }
9176                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9177                        if (tr.stack != null && tr.stack.isHomeStack()) {
9178                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9179                                    "Skipping, home stack task: " + tr);
9180                            continue;
9181                        }
9182                    }
9183                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9184                        final ActivityStack stack = tr.stack;
9185                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9186                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9187                                    "Skipping, top task in docked stack: " + tr);
9188                            continue;
9189                        }
9190                    }
9191                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9192                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9193                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9194                                    "Skipping, pinned stack task: " + tr);
9195                            continue;
9196                        }
9197                    }
9198                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9199                        // Don't include auto remove tasks that are finished or finishing.
9200                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9201                                "Skipping, auto-remove without activity: " + tr);
9202                        continue;
9203                    }
9204                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9205                            && !tr.isAvailable) {
9206                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9207                                "Skipping, unavail real act: " + tr);
9208                        continue;
9209                    }
9210
9211                    if (!tr.mUserSetupComplete) {
9212                        // Don't include task launched while user is not done setting-up.
9213                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9214                                "Skipping, user setup not complete: " + tr);
9215                        continue;
9216                    }
9217
9218                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9219                    if (!detailed) {
9220                        rti.baseIntent.replaceExtras((Bundle)null);
9221                    }
9222
9223                    res.add(rti);
9224                    maxNum--;
9225                }
9226            }
9227            return new ParceledListSlice<>(res);
9228        }
9229    }
9230
9231    @Override
9232    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9233        synchronized (this) {
9234            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9235                    "getTaskThumbnail()");
9236            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9237                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9238            if (tr != null) {
9239                return tr.getTaskThumbnailLocked();
9240            }
9241        }
9242        return null;
9243    }
9244
9245    @Override
9246    public int addAppTask(IBinder activityToken, Intent intent,
9247            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9248        final int callingUid = Binder.getCallingUid();
9249        final long callingIdent = Binder.clearCallingIdentity();
9250
9251        try {
9252            synchronized (this) {
9253                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9254                if (r == null) {
9255                    throw new IllegalArgumentException("Activity does not exist; token="
9256                            + activityToken);
9257                }
9258                ComponentName comp = intent.getComponent();
9259                if (comp == null) {
9260                    throw new IllegalArgumentException("Intent " + intent
9261                            + " must specify explicit component");
9262                }
9263                if (thumbnail.getWidth() != mThumbnailWidth
9264                        || thumbnail.getHeight() != mThumbnailHeight) {
9265                    throw new IllegalArgumentException("Bad thumbnail size: got "
9266                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9267                            + mThumbnailWidth + "x" + mThumbnailHeight);
9268                }
9269                if (intent.getSelector() != null) {
9270                    intent.setSelector(null);
9271                }
9272                if (intent.getSourceBounds() != null) {
9273                    intent.setSourceBounds(null);
9274                }
9275                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9276                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9277                        // The caller has added this as an auto-remove task...  that makes no
9278                        // sense, so turn off auto-remove.
9279                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9280                    }
9281                }
9282                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9283                    mLastAddedTaskActivity = null;
9284                }
9285                ActivityInfo ainfo = mLastAddedTaskActivity;
9286                if (ainfo == null) {
9287                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9288                            comp, 0, UserHandle.getUserId(callingUid));
9289                    if (ainfo.applicationInfo.uid != callingUid) {
9290                        throw new SecurityException(
9291                                "Can't add task for another application: target uid="
9292                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9293                    }
9294                }
9295
9296                // Use the full screen as the context for the task thumbnail
9297                final Point displaySize = new Point();
9298                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9299                r.task.stack.getDisplaySize(displaySize);
9300                thumbnailInfo.taskWidth = displaySize.x;
9301                thumbnailInfo.taskHeight = displaySize.y;
9302                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9303
9304                TaskRecord task = new TaskRecord(this,
9305                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9306                        ainfo, intent, description, thumbnailInfo);
9307
9308                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9309                if (trimIdx >= 0) {
9310                    // If this would have caused a trim, then we'll abort because that
9311                    // means it would be added at the end of the list but then just removed.
9312                    return INVALID_TASK_ID;
9313                }
9314
9315                final int N = mRecentTasks.size();
9316                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9317                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9318                    tr.removedFromRecents();
9319                }
9320
9321                task.inRecents = true;
9322                mRecentTasks.add(task);
9323                r.task.stack.addTask(task, false, "addAppTask");
9324
9325                task.setLastThumbnailLocked(thumbnail);
9326                task.freeLastThumbnail();
9327
9328                return task.taskId;
9329            }
9330        } finally {
9331            Binder.restoreCallingIdentity(callingIdent);
9332        }
9333    }
9334
9335    @Override
9336    public Point getAppTaskThumbnailSize() {
9337        synchronized (this) {
9338            return new Point(mThumbnailWidth,  mThumbnailHeight);
9339        }
9340    }
9341
9342    @Override
9343    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9344        synchronized (this) {
9345            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9346            if (r != null) {
9347                r.setTaskDescription(td);
9348                r.task.updateTaskDescription();
9349            }
9350        }
9351    }
9352
9353    @Override
9354    public void setTaskResizeable(int taskId, int resizeableMode) {
9355        synchronized (this) {
9356            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9357                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9358            if (task == null) {
9359                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9360                return;
9361            }
9362            if (task.mResizeMode != resizeableMode) {
9363                task.mResizeMode = resizeableMode;
9364                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9365                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9366                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9367            }
9368        }
9369    }
9370
9371    @Override
9372    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9373        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9374        long ident = Binder.clearCallingIdentity();
9375        try {
9376            synchronized (this) {
9377                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9378                if (task == null) {
9379                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9380                    return;
9381                }
9382                int stackId = task.stack.mStackId;
9383                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9384                // in crop windows resize mode or if the task size is affected by the docked stack
9385                // changing size. No need to update configuration.
9386                if (bounds != null && task.inCropWindowsResizeMode()
9387                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9388                    mWindowManager.scrollTask(task.taskId, bounds);
9389                    return;
9390                }
9391
9392                // Place the task in the right stack if it isn't there already based on
9393                // the requested bounds.
9394                // The stack transition logic is:
9395                // - a null bounds on a freeform task moves that task to fullscreen
9396                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9397                //   that task to freeform
9398                // - otherwise the task is not moved
9399                if (!StackId.isTaskResizeAllowed(stackId)) {
9400                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9401                }
9402                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9403                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9404                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9405                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9406                }
9407                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9408                if (stackId != task.stack.mStackId) {
9409                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9410                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9411                    preserveWindow = false;
9412                }
9413
9414                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9415                        false /* deferResume */);
9416            }
9417        } finally {
9418            Binder.restoreCallingIdentity(ident);
9419        }
9420    }
9421
9422    @Override
9423    public Rect getTaskBounds(int taskId) {
9424        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9425        long ident = Binder.clearCallingIdentity();
9426        Rect rect = new Rect();
9427        try {
9428            synchronized (this) {
9429                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9430                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9431                if (task == null) {
9432                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9433                    return rect;
9434                }
9435                if (task.stack != null) {
9436                    // Return the bounds from window manager since it will be adjusted for various
9437                    // things like the presense of a docked stack for tasks that aren't resizeable.
9438                    mWindowManager.getTaskBounds(task.taskId, rect);
9439                } else {
9440                    // Task isn't in window manager yet since it isn't associated with a stack.
9441                    // Return the persist value from activity manager
9442                    if (task.mBounds != null) {
9443                        rect.set(task.mBounds);
9444                    } else if (task.mLastNonFullscreenBounds != null) {
9445                        rect.set(task.mLastNonFullscreenBounds);
9446                    }
9447                }
9448            }
9449        } finally {
9450            Binder.restoreCallingIdentity(ident);
9451        }
9452        return rect;
9453    }
9454
9455    @Override
9456    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9457        if (userId != UserHandle.getCallingUserId()) {
9458            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9459                    "getTaskDescriptionIcon");
9460        }
9461        final File passedIconFile = new File(filePath);
9462        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9463                passedIconFile.getName());
9464        if (!legitIconFile.getPath().equals(filePath)
9465                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9466            throw new IllegalArgumentException("Bad file path: " + filePath
9467                    + " passed for userId " + userId);
9468        }
9469        return mRecentTasks.getTaskDescriptionIcon(filePath);
9470    }
9471
9472    @Override
9473    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9474            throws RemoteException {
9475        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9476                opts.getCustomInPlaceResId() == 0) {
9477            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9478                    "with valid animation");
9479        }
9480        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9481        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9482                opts.getCustomInPlaceResId());
9483        mWindowManager.executeAppTransition();
9484    }
9485
9486    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9487            boolean removeFromRecents) {
9488        if (removeFromRecents) {
9489            mRecentTasks.remove(tr);
9490            tr.removedFromRecents();
9491        }
9492        ComponentName component = tr.getBaseIntent().getComponent();
9493        if (component == null) {
9494            Slog.w(TAG, "No component for base intent of task: " + tr);
9495            return;
9496        }
9497
9498        // Find any running services associated with this app and stop if needed.
9499        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9500
9501        if (!killProcess) {
9502            return;
9503        }
9504
9505        // Determine if the process(es) for this task should be killed.
9506        final String pkg = component.getPackageName();
9507        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9508        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9509        for (int i = 0; i < pmap.size(); i++) {
9510
9511            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9512            for (int j = 0; j < uids.size(); j++) {
9513                ProcessRecord proc = uids.valueAt(j);
9514                if (proc.userId != tr.userId) {
9515                    // Don't kill process for a different user.
9516                    continue;
9517                }
9518                if (proc == mHomeProcess) {
9519                    // Don't kill the home process along with tasks from the same package.
9520                    continue;
9521                }
9522                if (!proc.pkgList.containsKey(pkg)) {
9523                    // Don't kill process that is not associated with this task.
9524                    continue;
9525                }
9526
9527                for (int k = 0; k < proc.activities.size(); k++) {
9528                    TaskRecord otherTask = proc.activities.get(k).task;
9529                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9530                        // Don't kill process(es) that has an activity in a different task that is
9531                        // also in recents.
9532                        return;
9533                    }
9534                }
9535
9536                if (proc.foregroundServices) {
9537                    // Don't kill process(es) with foreground service.
9538                    return;
9539                }
9540
9541                // Add process to kill list.
9542                procsToKill.add(proc);
9543            }
9544        }
9545
9546        // Kill the running processes.
9547        for (int i = 0; i < procsToKill.size(); i++) {
9548            ProcessRecord pr = procsToKill.get(i);
9549            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9550                    && pr.curReceiver == null) {
9551                pr.kill("remove task", true);
9552            } else {
9553                // We delay killing processes that are not in the background or running a receiver.
9554                pr.waitingToKill = "remove task";
9555            }
9556        }
9557    }
9558
9559    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9560        // Remove all tasks with activities in the specified package from the list of recent tasks
9561        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9562            TaskRecord tr = mRecentTasks.get(i);
9563            if (tr.userId != userId) continue;
9564
9565            ComponentName cn = tr.intent.getComponent();
9566            if (cn != null && cn.getPackageName().equals(packageName)) {
9567                // If the package name matches, remove the task.
9568                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9569            }
9570        }
9571    }
9572
9573    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9574            int userId) {
9575
9576        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9577            TaskRecord tr = mRecentTasks.get(i);
9578            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9579                continue;
9580            }
9581
9582            ComponentName cn = tr.intent.getComponent();
9583            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9584                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9585            if (sameComponent) {
9586                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9587            }
9588        }
9589    }
9590
9591    /**
9592     * Removes the task with the specified task id.
9593     *
9594     * @param taskId Identifier of the task to be removed.
9595     * @param killProcess Kill any process associated with the task if possible.
9596     * @param removeFromRecents Whether to also remove the task from recents.
9597     * @return Returns true if the given task was found and removed.
9598     */
9599    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9600            boolean removeFromRecents) {
9601        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9602                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9603        if (tr != null) {
9604            tr.removeTaskActivitiesLocked();
9605            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9606            if (tr.isPersistable) {
9607                notifyTaskPersisterLocked(null, true);
9608            }
9609            return true;
9610        }
9611        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9612        return false;
9613    }
9614
9615    @Override
9616    public void removeStack(int stackId) {
9617        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9618        if (stackId == HOME_STACK_ID) {
9619            throw new IllegalArgumentException("Removing home stack is not allowed.");
9620        }
9621
9622        synchronized (this) {
9623            final long ident = Binder.clearCallingIdentity();
9624            try {
9625                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9626                if (stack == null) {
9627                    return;
9628                }
9629                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9630                for (int i = tasks.size() - 1; i >= 0; i--) {
9631                    removeTaskByIdLocked(
9632                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9633                }
9634            } finally {
9635                Binder.restoreCallingIdentity(ident);
9636            }
9637        }
9638    }
9639
9640    @Override
9641    public boolean removeTask(int taskId) {
9642        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9643        synchronized (this) {
9644            final long ident = Binder.clearCallingIdentity();
9645            try {
9646                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9647            } finally {
9648                Binder.restoreCallingIdentity(ident);
9649            }
9650        }
9651    }
9652
9653    /**
9654     * TODO: Add mController hook
9655     */
9656    @Override
9657    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9658        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9659
9660        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9661        synchronized(this) {
9662            moveTaskToFrontLocked(taskId, flags, bOptions);
9663        }
9664    }
9665
9666    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9667        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9668
9669        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9670                Binder.getCallingUid(), -1, -1, "Task to front")) {
9671            ActivityOptions.abort(options);
9672            return;
9673        }
9674        final long origId = Binder.clearCallingIdentity();
9675        try {
9676            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9677            if (task == null) {
9678                Slog.d(TAG, "Could not find task for id: "+ taskId);
9679                return;
9680            }
9681            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9682                mStackSupervisor.showLockTaskToast();
9683                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9684                return;
9685            }
9686            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9687            if (prev != null && prev.isRecentsActivity()) {
9688                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9689            }
9690            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9691                    false /* forceNonResizable */);
9692        } finally {
9693            Binder.restoreCallingIdentity(origId);
9694        }
9695        ActivityOptions.abort(options);
9696    }
9697
9698    /**
9699     * Moves an activity, and all of the other activities within the same task, to the bottom
9700     * of the history stack.  The activity's order within the task is unchanged.
9701     *
9702     * @param token A reference to the activity we wish to move
9703     * @param nonRoot If false then this only works if the activity is the root
9704     *                of a task; if true it will work for any activity in a task.
9705     * @return Returns true if the move completed, false if not.
9706     */
9707    @Override
9708    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9709        enforceNotIsolatedCaller("moveActivityTaskToBack");
9710        synchronized(this) {
9711            final long origId = Binder.clearCallingIdentity();
9712            try {
9713                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9714                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9715                if (task != null) {
9716                    if (mStackSupervisor.isLockedTask(task)) {
9717                        mStackSupervisor.showLockTaskToast();
9718                        return false;
9719                    }
9720                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9721                }
9722            } finally {
9723                Binder.restoreCallingIdentity(origId);
9724            }
9725        }
9726        return false;
9727    }
9728
9729    @Override
9730    public void moveTaskBackwards(int task) {
9731        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9732                "moveTaskBackwards()");
9733
9734        synchronized(this) {
9735            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9736                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9737                return;
9738            }
9739            final long origId = Binder.clearCallingIdentity();
9740            moveTaskBackwardsLocked(task);
9741            Binder.restoreCallingIdentity(origId);
9742        }
9743    }
9744
9745    private final void moveTaskBackwardsLocked(int task) {
9746        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9747    }
9748
9749    @Override
9750    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9751            IActivityContainerCallback callback) throws RemoteException {
9752        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9753        synchronized (this) {
9754            if (parentActivityToken == null) {
9755                throw new IllegalArgumentException("parent token must not be null");
9756            }
9757            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9758            if (r == null) {
9759                return null;
9760            }
9761            if (callback == null) {
9762                throw new IllegalArgumentException("callback must not be null");
9763            }
9764            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9765        }
9766    }
9767
9768    @Override
9769    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9770        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9771        synchronized (this) {
9772            mStackSupervisor.deleteActivityContainer(container);
9773        }
9774    }
9775
9776    @Override
9777    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9778        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9779        synchronized (this) {
9780            final int stackId = mStackSupervisor.getNextStackId();
9781            final ActivityStack stack =
9782                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9783            if (stack == null) {
9784                return null;
9785            }
9786            return stack.mActivityContainer;
9787        }
9788    }
9789
9790    @Override
9791    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9792        synchronized (this) {
9793            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9794            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9795                return stack.mActivityContainer.getDisplayId();
9796            }
9797            return Display.DEFAULT_DISPLAY;
9798        }
9799    }
9800
9801    @Override
9802    public int getActivityStackId(IBinder token) throws RemoteException {
9803        synchronized (this) {
9804            ActivityStack stack = ActivityRecord.getStackLocked(token);
9805            if (stack == null) {
9806                return INVALID_STACK_ID;
9807            }
9808            return stack.mStackId;
9809        }
9810    }
9811
9812    @Override
9813    public void exitFreeformMode(IBinder token) throws RemoteException {
9814        synchronized (this) {
9815            long ident = Binder.clearCallingIdentity();
9816            try {
9817                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9818                if (r == null) {
9819                    throw new IllegalArgumentException(
9820                            "exitFreeformMode: No activity record matching token=" + token);
9821                }
9822                final ActivityStack stack = r.getStackLocked(token);
9823                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9824                    throw new IllegalStateException(
9825                            "exitFreeformMode: You can only go fullscreen from freeform.");
9826                }
9827                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9828                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9829                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9830            } finally {
9831                Binder.restoreCallingIdentity(ident);
9832            }
9833        }
9834    }
9835
9836    @Override
9837    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9838        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9839        if (stackId == HOME_STACK_ID) {
9840            throw new IllegalArgumentException(
9841                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9842        }
9843        synchronized (this) {
9844            long ident = Binder.clearCallingIdentity();
9845            try {
9846                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9847                        + " to stackId=" + stackId + " toTop=" + toTop);
9848                if (stackId == DOCKED_STACK_ID) {
9849                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9850                            null /* initialBounds */);
9851                }
9852                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9853                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9854                if (result && stackId == DOCKED_STACK_ID) {
9855                    // If task moved to docked stack - show recents if needed.
9856                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9857                            "moveTaskToDockedStack");
9858                }
9859            } finally {
9860                Binder.restoreCallingIdentity(ident);
9861            }
9862        }
9863    }
9864
9865    @Override
9866    public void swapDockedAndFullscreenStack() throws RemoteException {
9867        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9868        synchronized (this) {
9869            long ident = Binder.clearCallingIdentity();
9870            try {
9871                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9872                        FULLSCREEN_WORKSPACE_STACK_ID);
9873                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9874                        : null;
9875                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9876                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9877                        : null;
9878                if (topTask == null || tasks == null || tasks.size() == 0) {
9879                    Slog.w(TAG,
9880                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9881                    return;
9882                }
9883
9884                // TODO: App transition
9885                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9886
9887                // Defer the resume so resume/pausing while moving stacks is dangerous.
9888                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9889                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9890                        ANIMATE, true /* deferResume */);
9891                final int size = tasks.size();
9892                for (int i = 0; i < size; i++) {
9893                    final int id = tasks.get(i).taskId;
9894                    if (id == topTask.taskId) {
9895                        continue;
9896                    }
9897                    mStackSupervisor.moveTaskToStackLocked(id,
9898                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9899                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9900                }
9901
9902                // Because we deferred the resume, to avoid conflicts with stack switches while
9903                // resuming, we need to do it after all the tasks are moved.
9904                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9905                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9906
9907                mWindowManager.executeAppTransition();
9908            } finally {
9909                Binder.restoreCallingIdentity(ident);
9910            }
9911        }
9912    }
9913
9914    /**
9915     * Moves the input task to the docked stack.
9916     *
9917     * @param taskId Id of task to move.
9918     * @param createMode The mode the docked stack should be created in if it doesn't exist
9919     *                   already. See
9920     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9921     *                   and
9922     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9923     * @param toTop If the task and stack should be moved to the top.
9924     * @param animate Whether we should play an animation for the moving the task
9925     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9926     *                      docked stack. Pass {@code null} to use default bounds.
9927     */
9928    @Override
9929    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9930            Rect initialBounds, boolean moveHomeStackFront) {
9931        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9932        synchronized (this) {
9933            long ident = Binder.clearCallingIdentity();
9934            try {
9935                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9936                        + " to createMode=" + createMode + " toTop=" + toTop);
9937                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9938                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9939                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9940                        animate, DEFER_RESUME);
9941                if (moved) {
9942                    if (moveHomeStackFront) {
9943                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9944                    }
9945                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9946                }
9947                return moved;
9948            } finally {
9949                Binder.restoreCallingIdentity(ident);
9950            }
9951        }
9952    }
9953
9954    /**
9955     * Moves the top activity in the input stackId to the pinned stack.
9956     *
9957     * @param stackId Id of stack to move the top activity to pinned stack.
9958     * @param bounds Bounds to use for pinned stack.
9959     *
9960     * @return True if the top activity of the input stack was successfully moved to the pinned
9961     *          stack.
9962     */
9963    @Override
9964    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9965        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9966        synchronized (this) {
9967            if (!mSupportsPictureInPicture) {
9968                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9969                        + "Device doesn't support picture-in-pciture mode");
9970            }
9971
9972            long ident = Binder.clearCallingIdentity();
9973            try {
9974                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9975            } finally {
9976                Binder.restoreCallingIdentity(ident);
9977            }
9978        }
9979    }
9980
9981    @Override
9982    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9983            boolean preserveWindows, boolean animate, int animationDuration) {
9984        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9985        long ident = Binder.clearCallingIdentity();
9986        try {
9987            synchronized (this) {
9988                if (animate) {
9989                    if (stackId == PINNED_STACK_ID) {
9990                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9991                    } else {
9992                        throw new IllegalArgumentException("Stack: " + stackId
9993                                + " doesn't support animated resize.");
9994                    }
9995                } else {
9996                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9997                            null /* tempTaskInsetBounds */, preserveWindows,
9998                            allowResizeInDockedMode, !DEFER_RESUME);
9999                }
10000            }
10001        } finally {
10002            Binder.restoreCallingIdentity(ident);
10003        }
10004    }
10005
10006    @Override
10007    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10008            Rect tempDockedTaskInsetBounds,
10009            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10010        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10011                "resizeDockedStack()");
10012        long ident = Binder.clearCallingIdentity();
10013        try {
10014            synchronized (this) {
10015                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10016                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10017                        PRESERVE_WINDOWS);
10018            }
10019        } finally {
10020            Binder.restoreCallingIdentity(ident);
10021        }
10022    }
10023
10024    @Override
10025    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10026        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10027                "resizePinnedStack()");
10028        final long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10032            }
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    @Override
10039    public void positionTaskInStack(int taskId, int stackId, int position) {
10040        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10041        if (stackId == HOME_STACK_ID) {
10042            throw new IllegalArgumentException(
10043                    "positionTaskInStack: Attempt to change the position of task "
10044                    + taskId + " in/to home stack");
10045        }
10046        synchronized (this) {
10047            long ident = Binder.clearCallingIdentity();
10048            try {
10049                if (DEBUG_STACK) Slog.d(TAG_STACK,
10050                        "positionTaskInStack: positioning task=" + taskId
10051                        + " in stackId=" + stackId + " at position=" + position);
10052                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10053            } finally {
10054                Binder.restoreCallingIdentity(ident);
10055            }
10056        }
10057    }
10058
10059    @Override
10060    public List<StackInfo> getAllStackInfos() {
10061        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10062        long ident = Binder.clearCallingIdentity();
10063        try {
10064            synchronized (this) {
10065                return mStackSupervisor.getAllStackInfosLocked();
10066            }
10067        } finally {
10068            Binder.restoreCallingIdentity(ident);
10069        }
10070    }
10071
10072    @Override
10073    public StackInfo getStackInfo(int stackId) {
10074        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10075        long ident = Binder.clearCallingIdentity();
10076        try {
10077            synchronized (this) {
10078                return mStackSupervisor.getStackInfoLocked(stackId);
10079            }
10080        } finally {
10081            Binder.restoreCallingIdentity(ident);
10082        }
10083    }
10084
10085    @Override
10086    public boolean isInHomeStack(int taskId) {
10087        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10088        long ident = Binder.clearCallingIdentity();
10089        try {
10090            synchronized (this) {
10091                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10092                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10093                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10094            }
10095        } finally {
10096            Binder.restoreCallingIdentity(ident);
10097        }
10098    }
10099
10100    @Override
10101    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10102        synchronized(this) {
10103            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10104        }
10105    }
10106
10107    @Override
10108    public void updateDeviceOwner(String packageName) {
10109        final int callingUid = Binder.getCallingUid();
10110        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10111            throw new SecurityException("updateDeviceOwner called from non-system process");
10112        }
10113        synchronized (this) {
10114            mDeviceOwnerName = packageName;
10115        }
10116    }
10117
10118    @Override
10119    public void updateLockTaskPackages(int userId, String[] packages) {
10120        final int callingUid = Binder.getCallingUid();
10121        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10122            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10123                    "updateLockTaskPackages()");
10124        }
10125        synchronized (this) {
10126            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10127                    Arrays.toString(packages));
10128            mLockTaskPackages.put(userId, packages);
10129            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10130        }
10131    }
10132
10133
10134    void startLockTaskModeLocked(TaskRecord task) {
10135        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10136        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10137            return;
10138        }
10139
10140        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10141        // is initiated by system after the pinning request was shown and locked mode is initiated
10142        // by an authorized app directly
10143        final int callingUid = Binder.getCallingUid();
10144        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10145        long ident = Binder.clearCallingIdentity();
10146        try {
10147            if (!isSystemInitiated) {
10148                task.mLockTaskUid = callingUid;
10149                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10150                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10151                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10152                    StatusBarManagerInternal statusBarManager =
10153                            LocalServices.getService(StatusBarManagerInternal.class);
10154                    if (statusBarManager != null) {
10155                        statusBarManager.showScreenPinningRequest(task.taskId);
10156                    }
10157                    return;
10158                }
10159
10160                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10161                if (stack == null || task != stack.topTask()) {
10162                    throw new IllegalArgumentException("Invalid task, not in foreground");
10163                }
10164            }
10165            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10166                    "Locking fully");
10167            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10168                    ActivityManager.LOCK_TASK_MODE_PINNED :
10169                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10170                    "startLockTask", true);
10171        } finally {
10172            Binder.restoreCallingIdentity(ident);
10173        }
10174    }
10175
10176    @Override
10177    public void startLockTaskMode(int taskId) {
10178        synchronized (this) {
10179            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10180            if (task != null) {
10181                startLockTaskModeLocked(task);
10182            }
10183        }
10184    }
10185
10186    @Override
10187    public void startLockTaskMode(IBinder token) {
10188        synchronized (this) {
10189            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10190            if (r == null) {
10191                return;
10192            }
10193            final TaskRecord task = r.task;
10194            if (task != null) {
10195                startLockTaskModeLocked(task);
10196            }
10197        }
10198    }
10199
10200    @Override
10201    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10202        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10203        // This makes inner call to look as if it was initiated by system.
10204        long ident = Binder.clearCallingIdentity();
10205        try {
10206            synchronized (this) {
10207                startLockTaskMode(taskId);
10208            }
10209        } finally {
10210            Binder.restoreCallingIdentity(ident);
10211        }
10212    }
10213
10214    @Override
10215    public void stopLockTaskMode() {
10216        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10217        if (lockTask == null) {
10218            // Our work here is done.
10219            return;
10220        }
10221
10222        final int callingUid = Binder.getCallingUid();
10223        final int lockTaskUid = lockTask.mLockTaskUid;
10224        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10225        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10226            // Done.
10227            return;
10228        } else {
10229            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10230            // It is possible lockTaskMode was started by the system process because
10231            // android:lockTaskMode is set to a locking value in the application manifest
10232            // instead of the app calling startLockTaskMode. In this case
10233            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10234            // {@link TaskRecord.effectiveUid} instead. Also caller with
10235            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10236            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10237                    && callingUid != lockTaskUid
10238                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10239                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10240                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10241            }
10242        }
10243        long ident = Binder.clearCallingIdentity();
10244        try {
10245            Log.d(TAG, "stopLockTaskMode");
10246            // Stop lock task
10247            synchronized (this) {
10248                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10249                        "stopLockTask", true);
10250            }
10251            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10252            if (tm != null) {
10253                tm.showInCallScreen(false);
10254            }
10255        } finally {
10256            Binder.restoreCallingIdentity(ident);
10257        }
10258    }
10259
10260    /**
10261     * This API should be called by SystemUI only when user perform certain action to dismiss
10262     * lock task mode. We should only dismiss pinned lock task mode in this case.
10263     */
10264    @Override
10265    public void stopSystemLockTaskMode() throws RemoteException {
10266        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10267            stopLockTaskMode();
10268        } else {
10269            mStackSupervisor.showLockTaskToast();
10270        }
10271    }
10272
10273    @Override
10274    public boolean isInLockTaskMode() {
10275        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10276    }
10277
10278    @Override
10279    public int getLockTaskModeState() {
10280        synchronized (this) {
10281            return mStackSupervisor.getLockTaskModeState();
10282        }
10283    }
10284
10285    @Override
10286    public void showLockTaskEscapeMessage(IBinder token) {
10287        synchronized (this) {
10288            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10289            if (r == null) {
10290                return;
10291            }
10292            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10293        }
10294    }
10295
10296    // =========================================================
10297    // CONTENT PROVIDERS
10298    // =========================================================
10299
10300    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10301        List<ProviderInfo> providers = null;
10302        try {
10303            providers = AppGlobals.getPackageManager()
10304                    .queryContentProviders(app.processName, app.uid,
10305                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10306                                    | MATCH_DEBUG_TRIAGED_MISSING)
10307                    .getList();
10308        } catch (RemoteException ex) {
10309        }
10310        if (DEBUG_MU) Slog.v(TAG_MU,
10311                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10312        int userId = app.userId;
10313        if (providers != null) {
10314            int N = providers.size();
10315            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10316            for (int i=0; i<N; i++) {
10317                // TODO: keep logic in sync with installEncryptionUnawareProviders
10318                ProviderInfo cpi =
10319                    (ProviderInfo)providers.get(i);
10320                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10321                        cpi.name, cpi.flags);
10322                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10323                    // This is a singleton provider, but a user besides the
10324                    // default user is asking to initialize a process it runs
10325                    // in...  well, no, it doesn't actually run in this process,
10326                    // it runs in the process of the default user.  Get rid of it.
10327                    providers.remove(i);
10328                    N--;
10329                    i--;
10330                    continue;
10331                }
10332
10333                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10334                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10335                if (cpr == null) {
10336                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10337                    mProviderMap.putProviderByClass(comp, cpr);
10338                }
10339                if (DEBUG_MU) Slog.v(TAG_MU,
10340                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10341                app.pubProviders.put(cpi.name, cpr);
10342                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10343                    // Don't add this if it is a platform component that is marked
10344                    // to run in multiple processes, because this is actually
10345                    // part of the framework so doesn't make sense to track as a
10346                    // separate apk in the process.
10347                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10348                            mProcessStats);
10349                }
10350                notifyPackageUse(cpi.applicationInfo.packageName,
10351                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10352            }
10353        }
10354        return providers;
10355    }
10356
10357    /**
10358     * Check if {@link ProcessRecord} has a possible chance at accessing the
10359     * given {@link ProviderInfo}. Final permission checking is always done
10360     * in {@link ContentProvider}.
10361     */
10362    private final String checkContentProviderPermissionLocked(
10363            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10364        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10365        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10366        boolean checkedGrants = false;
10367        if (checkUser) {
10368            // Looking for cross-user grants before enforcing the typical cross-users permissions
10369            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10370            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10371                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10372                    return null;
10373                }
10374                checkedGrants = true;
10375            }
10376            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10377                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10378            if (userId != tmpTargetUserId) {
10379                // When we actually went to determine the final targer user ID, this ended
10380                // up different than our initial check for the authority.  This is because
10381                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10382                // SELF.  So we need to re-check the grants again.
10383                checkedGrants = false;
10384            }
10385        }
10386        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10387                cpi.applicationInfo.uid, cpi.exported)
10388                == PackageManager.PERMISSION_GRANTED) {
10389            return null;
10390        }
10391        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10392                cpi.applicationInfo.uid, cpi.exported)
10393                == PackageManager.PERMISSION_GRANTED) {
10394            return null;
10395        }
10396
10397        PathPermission[] pps = cpi.pathPermissions;
10398        if (pps != null) {
10399            int i = pps.length;
10400            while (i > 0) {
10401                i--;
10402                PathPermission pp = pps[i];
10403                String pprperm = pp.getReadPermission();
10404                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10405                        cpi.applicationInfo.uid, cpi.exported)
10406                        == PackageManager.PERMISSION_GRANTED) {
10407                    return null;
10408                }
10409                String ppwperm = pp.getWritePermission();
10410                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10411                        cpi.applicationInfo.uid, cpi.exported)
10412                        == PackageManager.PERMISSION_GRANTED) {
10413                    return null;
10414                }
10415            }
10416        }
10417        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10418            return null;
10419        }
10420
10421        String msg;
10422        if (!cpi.exported) {
10423            msg = "Permission Denial: opening provider " + cpi.name
10424                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10425                    + ", uid=" + callingUid + ") that is not exported from uid "
10426                    + cpi.applicationInfo.uid;
10427        } else {
10428            msg = "Permission Denial: opening provider " + cpi.name
10429                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10430                    + ", uid=" + callingUid + ") requires "
10431                    + cpi.readPermission + " or " + cpi.writePermission;
10432        }
10433        Slog.w(TAG, msg);
10434        return msg;
10435    }
10436
10437    /**
10438     * Returns if the ContentProvider has granted a uri to callingUid
10439     */
10440    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10441        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10442        if (perms != null) {
10443            for (int i=perms.size()-1; i>=0; i--) {
10444                GrantUri grantUri = perms.keyAt(i);
10445                if (grantUri.sourceUserId == userId || !checkUser) {
10446                    if (matchesProvider(grantUri.uri, cpi)) {
10447                        return true;
10448                    }
10449                }
10450            }
10451        }
10452        return false;
10453    }
10454
10455    /**
10456     * Returns true if the uri authority is one of the authorities specified in the provider.
10457     */
10458    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10459        String uriAuth = uri.getAuthority();
10460        String cpiAuth = cpi.authority;
10461        if (cpiAuth.indexOf(';') == -1) {
10462            return cpiAuth.equals(uriAuth);
10463        }
10464        String[] cpiAuths = cpiAuth.split(";");
10465        int length = cpiAuths.length;
10466        for (int i = 0; i < length; i++) {
10467            if (cpiAuths[i].equals(uriAuth)) return true;
10468        }
10469        return false;
10470    }
10471
10472    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10473            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10474        if (r != null) {
10475            for (int i=0; i<r.conProviders.size(); i++) {
10476                ContentProviderConnection conn = r.conProviders.get(i);
10477                if (conn.provider == cpr) {
10478                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10479                            "Adding provider requested by "
10480                            + r.processName + " from process "
10481                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10482                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10483                    if (stable) {
10484                        conn.stableCount++;
10485                        conn.numStableIncs++;
10486                    } else {
10487                        conn.unstableCount++;
10488                        conn.numUnstableIncs++;
10489                    }
10490                    return conn;
10491                }
10492            }
10493            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10494            if (stable) {
10495                conn.stableCount = 1;
10496                conn.numStableIncs = 1;
10497            } else {
10498                conn.unstableCount = 1;
10499                conn.numUnstableIncs = 1;
10500            }
10501            cpr.connections.add(conn);
10502            r.conProviders.add(conn);
10503            startAssociationLocked(r.uid, r.processName, r.curProcState,
10504                    cpr.uid, cpr.name, cpr.info.processName);
10505            return conn;
10506        }
10507        cpr.addExternalProcessHandleLocked(externalProcessToken);
10508        return null;
10509    }
10510
10511    boolean decProviderCountLocked(ContentProviderConnection conn,
10512            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10513        if (conn != null) {
10514            cpr = conn.provider;
10515            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10516                    "Removing provider requested by "
10517                    + conn.client.processName + " from process "
10518                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10519                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10520            if (stable) {
10521                conn.stableCount--;
10522            } else {
10523                conn.unstableCount--;
10524            }
10525            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10526                cpr.connections.remove(conn);
10527                conn.client.conProviders.remove(conn);
10528                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10529                    // The client is more important than last activity -- note the time this
10530                    // is happening, so we keep the old provider process around a bit as last
10531                    // activity to avoid thrashing it.
10532                    if (cpr.proc != null) {
10533                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10534                    }
10535                }
10536                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10537                return true;
10538            }
10539            return false;
10540        }
10541        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10542        return false;
10543    }
10544
10545    private void checkTime(long startTime, String where) {
10546        long now = SystemClock.uptimeMillis();
10547        if ((now-startTime) > 50) {
10548            // If we are taking more than 50ms, log about it.
10549            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10550        }
10551    }
10552
10553    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10554            PROC_SPACE_TERM,
10555            PROC_SPACE_TERM|PROC_PARENS,
10556            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10557    };
10558
10559    private final long[] mProcessStateStatsLongs = new long[1];
10560
10561    boolean isProcessAliveLocked(ProcessRecord proc) {
10562        if (proc.procStatFile == null) {
10563            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10564        }
10565        mProcessStateStatsLongs[0] = 0;
10566        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10567                mProcessStateStatsLongs, null)) {
10568            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10569            return false;
10570        }
10571        final long state = mProcessStateStatsLongs[0];
10572        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10573                + (char)state);
10574        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10575    }
10576
10577    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10578            String name, IBinder token, boolean stable, int userId) {
10579        ContentProviderRecord cpr;
10580        ContentProviderConnection conn = null;
10581        ProviderInfo cpi = null;
10582
10583        synchronized(this) {
10584            long startTime = SystemClock.uptimeMillis();
10585
10586            ProcessRecord r = null;
10587            if (caller != null) {
10588                r = getRecordForAppLocked(caller);
10589                if (r == null) {
10590                    throw new SecurityException(
10591                            "Unable to find app for caller " + caller
10592                          + " (pid=" + Binder.getCallingPid()
10593                          + ") when getting content provider " + name);
10594                }
10595            }
10596
10597            boolean checkCrossUser = true;
10598
10599            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10600
10601            // First check if this content provider has been published...
10602            cpr = mProviderMap.getProviderByName(name, userId);
10603            // If that didn't work, check if it exists for user 0 and then
10604            // verify that it's a singleton provider before using it.
10605            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10606                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10607                if (cpr != null) {
10608                    cpi = cpr.info;
10609                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10610                            cpi.name, cpi.flags)
10611                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10612                        userId = UserHandle.USER_SYSTEM;
10613                        checkCrossUser = false;
10614                    } else {
10615                        cpr = null;
10616                        cpi = null;
10617                    }
10618                }
10619            }
10620
10621            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10622            if (providerRunning) {
10623                cpi = cpr.info;
10624                String msg;
10625                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10626                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10627                        != null) {
10628                    throw new SecurityException(msg);
10629                }
10630                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10631
10632                if (r != null && cpr.canRunHere(r)) {
10633                    // This provider has been published or is in the process
10634                    // of being published...  but it is also allowed to run
10635                    // in the caller's process, so don't make a connection
10636                    // and just let the caller instantiate its own instance.
10637                    ContentProviderHolder holder = cpr.newHolder(null);
10638                    // don't give caller the provider object, it needs
10639                    // to make its own.
10640                    holder.provider = null;
10641                    return holder;
10642                }
10643
10644                final long origId = Binder.clearCallingIdentity();
10645
10646                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10647
10648                // In this case the provider instance already exists, so we can
10649                // return it right away.
10650                conn = incProviderCountLocked(r, cpr, token, stable);
10651                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10652                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10653                        // If this is a perceptible app accessing the provider,
10654                        // make sure to count it as being accessed and thus
10655                        // back up on the LRU list.  This is good because
10656                        // content providers are often expensive to start.
10657                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10658                        updateLruProcessLocked(cpr.proc, false, null);
10659                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10660                    }
10661                }
10662
10663                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10664                final int verifiedAdj = cpr.proc.verifiedAdj;
10665                boolean success = updateOomAdjLocked(cpr.proc);
10666                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10667                // if the process has been successfully adjusted.  So to reduce races with
10668                // it, we will check whether the process still exists.  Note that this doesn't
10669                // completely get rid of races with LMK killing the process, but should make
10670                // them much smaller.
10671                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10672                    success = false;
10673                }
10674                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10675                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10676                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10677                // NOTE: there is still a race here where a signal could be
10678                // pending on the process even though we managed to update its
10679                // adj level.  Not sure what to do about this, but at least
10680                // the race is now smaller.
10681                if (!success) {
10682                    // Uh oh...  it looks like the provider's process
10683                    // has been killed on us.  We need to wait for a new
10684                    // process to be started, and make sure its death
10685                    // doesn't kill our process.
10686                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10687                            + " is crashing; detaching " + r);
10688                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10689                    checkTime(startTime, "getContentProviderImpl: before appDied");
10690                    appDiedLocked(cpr.proc);
10691                    checkTime(startTime, "getContentProviderImpl: after appDied");
10692                    if (!lastRef) {
10693                        // This wasn't the last ref our process had on
10694                        // the provider...  we have now been killed, bail.
10695                        return null;
10696                    }
10697                    providerRunning = false;
10698                    conn = null;
10699                } else {
10700                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10701                }
10702
10703                Binder.restoreCallingIdentity(origId);
10704            }
10705
10706            if (!providerRunning) {
10707                try {
10708                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10709                    cpi = AppGlobals.getPackageManager().
10710                        resolveContentProvider(name,
10711                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10712                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10713                } catch (RemoteException ex) {
10714                }
10715                if (cpi == null) {
10716                    return null;
10717                }
10718                // If the provider is a singleton AND
10719                // (it's a call within the same user || the provider is a
10720                // privileged app)
10721                // Then allow connecting to the singleton provider
10722                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10723                        cpi.name, cpi.flags)
10724                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10725                if (singleton) {
10726                    userId = UserHandle.USER_SYSTEM;
10727                }
10728                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10729                checkTime(startTime, "getContentProviderImpl: got app info for user");
10730
10731                String msg;
10732                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10733                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10734                        != null) {
10735                    throw new SecurityException(msg);
10736                }
10737                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10738
10739                if (!mProcessesReady
10740                        && !cpi.processName.equals("system")) {
10741                    // If this content provider does not run in the system
10742                    // process, and the system is not yet ready to run other
10743                    // processes, then fail fast instead of hanging.
10744                    throw new IllegalArgumentException(
10745                            "Attempt to launch content provider before system ready");
10746                }
10747
10748                // Make sure that the user who owns this provider is running.  If not,
10749                // we don't want to allow it to run.
10750                if (!mUserController.isUserRunningLocked(userId, 0)) {
10751                    Slog.w(TAG, "Unable to launch app "
10752                            + cpi.applicationInfo.packageName + "/"
10753                            + cpi.applicationInfo.uid + " for provider "
10754                            + name + ": user " + userId + " is stopped");
10755                    return null;
10756                }
10757
10758                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10759                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10760                cpr = mProviderMap.getProviderByClass(comp, userId);
10761                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10762                final boolean firstClass = cpr == null;
10763                if (firstClass) {
10764                    final long ident = Binder.clearCallingIdentity();
10765
10766                    // If permissions need a review before any of the app components can run,
10767                    // we return no provider and launch a review activity if the calling app
10768                    // is in the foreground.
10769                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10770                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10771                            return null;
10772                        }
10773                    }
10774
10775                    try {
10776                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10777                        ApplicationInfo ai =
10778                            AppGlobals.getPackageManager().
10779                                getApplicationInfo(
10780                                        cpi.applicationInfo.packageName,
10781                                        STOCK_PM_FLAGS, userId);
10782                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10783                        if (ai == null) {
10784                            Slog.w(TAG, "No package info for content provider "
10785                                    + cpi.name);
10786                            return null;
10787                        }
10788                        ai = getAppInfoForUser(ai, userId);
10789                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10790                    } catch (RemoteException ex) {
10791                        // pm is in same process, this will never happen.
10792                    } finally {
10793                        Binder.restoreCallingIdentity(ident);
10794                    }
10795                }
10796
10797                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10798
10799                if (r != null && cpr.canRunHere(r)) {
10800                    // If this is a multiprocess provider, then just return its
10801                    // info and allow the caller to instantiate it.  Only do
10802                    // this if the provider is the same user as the caller's
10803                    // process, or can run as root (so can be in any process).
10804                    return cpr.newHolder(null);
10805                }
10806
10807                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10808                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10809                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10810
10811                // This is single process, and our app is now connecting to it.
10812                // See if we are already in the process of launching this
10813                // provider.
10814                final int N = mLaunchingProviders.size();
10815                int i;
10816                for (i = 0; i < N; i++) {
10817                    if (mLaunchingProviders.get(i) == cpr) {
10818                        break;
10819                    }
10820                }
10821
10822                // If the provider is not already being launched, then get it
10823                // started.
10824                if (i >= N) {
10825                    final long origId = Binder.clearCallingIdentity();
10826
10827                    try {
10828                        // Content provider is now in use, its package can't be stopped.
10829                        try {
10830                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10831                            AppGlobals.getPackageManager().setPackageStoppedState(
10832                                    cpr.appInfo.packageName, false, userId);
10833                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10834                        } catch (RemoteException e) {
10835                        } catch (IllegalArgumentException e) {
10836                            Slog.w(TAG, "Failed trying to unstop package "
10837                                    + cpr.appInfo.packageName + ": " + e);
10838                        }
10839
10840                        // Use existing process if already started
10841                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10842                        ProcessRecord proc = getProcessRecordLocked(
10843                                cpi.processName, cpr.appInfo.uid, false);
10844                        if (proc != null && proc.thread != null && !proc.killed) {
10845                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10846                                    "Installing in existing process " + proc);
10847                            if (!proc.pubProviders.containsKey(cpi.name)) {
10848                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10849                                proc.pubProviders.put(cpi.name, cpr);
10850                                try {
10851                                    proc.thread.scheduleInstallProvider(cpi);
10852                                } catch (RemoteException e) {
10853                                }
10854                            }
10855                        } else {
10856                            checkTime(startTime, "getContentProviderImpl: before start process");
10857                            proc = startProcessLocked(cpi.processName,
10858                                    cpr.appInfo, false, 0, "content provider",
10859                                    new ComponentName(cpi.applicationInfo.packageName,
10860                                            cpi.name), false, false, false);
10861                            checkTime(startTime, "getContentProviderImpl: after start process");
10862                            if (proc == null) {
10863                                Slog.w(TAG, "Unable to launch app "
10864                                        + cpi.applicationInfo.packageName + "/"
10865                                        + cpi.applicationInfo.uid + " for provider "
10866                                        + name + ": process is bad");
10867                                return null;
10868                            }
10869                        }
10870                        cpr.launchingApp = proc;
10871                        mLaunchingProviders.add(cpr);
10872                    } finally {
10873                        Binder.restoreCallingIdentity(origId);
10874                    }
10875                }
10876
10877                checkTime(startTime, "getContentProviderImpl: updating data structures");
10878
10879                // Make sure the provider is published (the same provider class
10880                // may be published under multiple names).
10881                if (firstClass) {
10882                    mProviderMap.putProviderByClass(comp, cpr);
10883                }
10884
10885                mProviderMap.putProviderByName(name, cpr);
10886                conn = incProviderCountLocked(r, cpr, token, stable);
10887                if (conn != null) {
10888                    conn.waiting = true;
10889                }
10890            }
10891            checkTime(startTime, "getContentProviderImpl: done!");
10892        }
10893
10894        // Wait for the provider to be published...
10895        synchronized (cpr) {
10896            while (cpr.provider == null) {
10897                if (cpr.launchingApp == null) {
10898                    Slog.w(TAG, "Unable to launch app "
10899                            + cpi.applicationInfo.packageName + "/"
10900                            + cpi.applicationInfo.uid + " for provider "
10901                            + name + ": launching app became null");
10902                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10903                            UserHandle.getUserId(cpi.applicationInfo.uid),
10904                            cpi.applicationInfo.packageName,
10905                            cpi.applicationInfo.uid, name);
10906                    return null;
10907                }
10908                try {
10909                    if (DEBUG_MU) Slog.v(TAG_MU,
10910                            "Waiting to start provider " + cpr
10911                            + " launchingApp=" + cpr.launchingApp);
10912                    if (conn != null) {
10913                        conn.waiting = true;
10914                    }
10915                    cpr.wait();
10916                } catch (InterruptedException ex) {
10917                } finally {
10918                    if (conn != null) {
10919                        conn.waiting = false;
10920                    }
10921                }
10922            }
10923        }
10924        return cpr != null ? cpr.newHolder(conn) : null;
10925    }
10926
10927    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10928            ProcessRecord r, final int userId) {
10929        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10930                cpi.packageName, userId)) {
10931
10932            final boolean callerForeground = r == null || r.setSchedGroup
10933                    != ProcessList.SCHED_GROUP_BACKGROUND;
10934
10935            // Show a permission review UI only for starting from a foreground app
10936            if (!callerForeground) {
10937                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10938                        + cpi.packageName + " requires a permissions review");
10939                return false;
10940            }
10941
10942            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10943            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10944                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10945            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10946
10947            if (DEBUG_PERMISSIONS_REVIEW) {
10948                Slog.i(TAG, "u" + userId + " Launching permission review "
10949                        + "for package " + cpi.packageName);
10950            }
10951
10952            final UserHandle userHandle = new UserHandle(userId);
10953            mHandler.post(new Runnable() {
10954                @Override
10955                public void run() {
10956                    mContext.startActivityAsUser(intent, userHandle);
10957                }
10958            });
10959
10960            return false;
10961        }
10962
10963        return true;
10964    }
10965
10966    PackageManagerInternal getPackageManagerInternalLocked() {
10967        if (mPackageManagerInt == null) {
10968            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10969        }
10970        return mPackageManagerInt;
10971    }
10972
10973    @Override
10974    public final ContentProviderHolder getContentProvider(
10975            IApplicationThread caller, String name, int userId, boolean stable) {
10976        enforceNotIsolatedCaller("getContentProvider");
10977        if (caller == null) {
10978            String msg = "null IApplicationThread when getting content provider "
10979                    + name;
10980            Slog.w(TAG, msg);
10981            throw new SecurityException(msg);
10982        }
10983        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10984        // with cross-user grant.
10985        return getContentProviderImpl(caller, name, null, stable, userId);
10986    }
10987
10988    public ContentProviderHolder getContentProviderExternal(
10989            String name, int userId, IBinder token) {
10990        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10991            "Do not have permission in call getContentProviderExternal()");
10992        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10993                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10994        return getContentProviderExternalUnchecked(name, token, userId);
10995    }
10996
10997    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10998            IBinder token, int userId) {
10999        return getContentProviderImpl(null, name, token, true, userId);
11000    }
11001
11002    /**
11003     * Drop a content provider from a ProcessRecord's bookkeeping
11004     */
11005    public void removeContentProvider(IBinder connection, boolean stable) {
11006        enforceNotIsolatedCaller("removeContentProvider");
11007        long ident = Binder.clearCallingIdentity();
11008        try {
11009            synchronized (this) {
11010                ContentProviderConnection conn;
11011                try {
11012                    conn = (ContentProviderConnection)connection;
11013                } catch (ClassCastException e) {
11014                    String msg ="removeContentProvider: " + connection
11015                            + " not a ContentProviderConnection";
11016                    Slog.w(TAG, msg);
11017                    throw new IllegalArgumentException(msg);
11018                }
11019                if (conn == null) {
11020                    throw new NullPointerException("connection is null");
11021                }
11022                if (decProviderCountLocked(conn, null, null, stable)) {
11023                    updateOomAdjLocked();
11024                }
11025            }
11026        } finally {
11027            Binder.restoreCallingIdentity(ident);
11028        }
11029    }
11030
11031    public void removeContentProviderExternal(String name, IBinder token) {
11032        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11033            "Do not have permission in call removeContentProviderExternal()");
11034        int userId = UserHandle.getCallingUserId();
11035        long ident = Binder.clearCallingIdentity();
11036        try {
11037            removeContentProviderExternalUnchecked(name, token, userId);
11038        } finally {
11039            Binder.restoreCallingIdentity(ident);
11040        }
11041    }
11042
11043    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11044        synchronized (this) {
11045            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11046            if(cpr == null) {
11047                //remove from mProvidersByClass
11048                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11049                return;
11050            }
11051
11052            //update content provider record entry info
11053            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11054            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11055            if (localCpr.hasExternalProcessHandles()) {
11056                if (localCpr.removeExternalProcessHandleLocked(token)) {
11057                    updateOomAdjLocked();
11058                } else {
11059                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11060                            + " with no external reference for token: "
11061                            + token + ".");
11062                }
11063            } else {
11064                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11065                        + " with no external references.");
11066            }
11067        }
11068    }
11069
11070    public final void publishContentProviders(IApplicationThread caller,
11071            List<ContentProviderHolder> providers) {
11072        if (providers == null) {
11073            return;
11074        }
11075
11076        enforceNotIsolatedCaller("publishContentProviders");
11077        synchronized (this) {
11078            final ProcessRecord r = getRecordForAppLocked(caller);
11079            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11080            if (r == null) {
11081                throw new SecurityException(
11082                        "Unable to find app for caller " + caller
11083                      + " (pid=" + Binder.getCallingPid()
11084                      + ") when publishing content providers");
11085            }
11086
11087            final long origId = Binder.clearCallingIdentity();
11088
11089            final int N = providers.size();
11090            for (int i = 0; i < N; i++) {
11091                ContentProviderHolder src = providers.get(i);
11092                if (src == null || src.info == null || src.provider == null) {
11093                    continue;
11094                }
11095                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11096                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11097                if (dst != null) {
11098                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11099                    mProviderMap.putProviderByClass(comp, dst);
11100                    String names[] = dst.info.authority.split(";");
11101                    for (int j = 0; j < names.length; j++) {
11102                        mProviderMap.putProviderByName(names[j], dst);
11103                    }
11104
11105                    int launchingCount = mLaunchingProviders.size();
11106                    int j;
11107                    boolean wasInLaunchingProviders = false;
11108                    for (j = 0; j < launchingCount; j++) {
11109                        if (mLaunchingProviders.get(j) == dst) {
11110                            mLaunchingProviders.remove(j);
11111                            wasInLaunchingProviders = true;
11112                            j--;
11113                            launchingCount--;
11114                        }
11115                    }
11116                    if (wasInLaunchingProviders) {
11117                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11118                    }
11119                    synchronized (dst) {
11120                        dst.provider = src.provider;
11121                        dst.proc = r;
11122                        dst.notifyAll();
11123                    }
11124                    updateOomAdjLocked(r);
11125                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11126                            src.info.authority);
11127                }
11128            }
11129
11130            Binder.restoreCallingIdentity(origId);
11131        }
11132    }
11133
11134    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11135        ContentProviderConnection conn;
11136        try {
11137            conn = (ContentProviderConnection)connection;
11138        } catch (ClassCastException e) {
11139            String msg ="refContentProvider: " + connection
11140                    + " not a ContentProviderConnection";
11141            Slog.w(TAG, msg);
11142            throw new IllegalArgumentException(msg);
11143        }
11144        if (conn == null) {
11145            throw new NullPointerException("connection is null");
11146        }
11147
11148        synchronized (this) {
11149            if (stable > 0) {
11150                conn.numStableIncs += stable;
11151            }
11152            stable = conn.stableCount + stable;
11153            if (stable < 0) {
11154                throw new IllegalStateException("stableCount < 0: " + stable);
11155            }
11156
11157            if (unstable > 0) {
11158                conn.numUnstableIncs += unstable;
11159            }
11160            unstable = conn.unstableCount + unstable;
11161            if (unstable < 0) {
11162                throw new IllegalStateException("unstableCount < 0: " + unstable);
11163            }
11164
11165            if ((stable+unstable) <= 0) {
11166                throw new IllegalStateException("ref counts can't go to zero here: stable="
11167                        + stable + " unstable=" + unstable);
11168            }
11169            conn.stableCount = stable;
11170            conn.unstableCount = unstable;
11171            return !conn.dead;
11172        }
11173    }
11174
11175    public void unstableProviderDied(IBinder connection) {
11176        ContentProviderConnection conn;
11177        try {
11178            conn = (ContentProviderConnection)connection;
11179        } catch (ClassCastException e) {
11180            String msg ="refContentProvider: " + connection
11181                    + " not a ContentProviderConnection";
11182            Slog.w(TAG, msg);
11183            throw new IllegalArgumentException(msg);
11184        }
11185        if (conn == null) {
11186            throw new NullPointerException("connection is null");
11187        }
11188
11189        // Safely retrieve the content provider associated with the connection.
11190        IContentProvider provider;
11191        synchronized (this) {
11192            provider = conn.provider.provider;
11193        }
11194
11195        if (provider == null) {
11196            // Um, yeah, we're way ahead of you.
11197            return;
11198        }
11199
11200        // Make sure the caller is being honest with us.
11201        if (provider.asBinder().pingBinder()) {
11202            // Er, no, still looks good to us.
11203            synchronized (this) {
11204                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11205                        + " says " + conn + " died, but we don't agree");
11206                return;
11207            }
11208        }
11209
11210        // Well look at that!  It's dead!
11211        synchronized (this) {
11212            if (conn.provider.provider != provider) {
11213                // But something changed...  good enough.
11214                return;
11215            }
11216
11217            ProcessRecord proc = conn.provider.proc;
11218            if (proc == null || proc.thread == null) {
11219                // Seems like the process is already cleaned up.
11220                return;
11221            }
11222
11223            // As far as we're concerned, this is just like receiving a
11224            // death notification...  just a bit prematurely.
11225            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11226                    + ") early provider death");
11227            final long ident = Binder.clearCallingIdentity();
11228            try {
11229                appDiedLocked(proc);
11230            } finally {
11231                Binder.restoreCallingIdentity(ident);
11232            }
11233        }
11234    }
11235
11236    @Override
11237    public void appNotRespondingViaProvider(IBinder connection) {
11238        enforceCallingPermission(
11239                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11240
11241        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11242        if (conn == null) {
11243            Slog.w(TAG, "ContentProviderConnection is null");
11244            return;
11245        }
11246
11247        final ProcessRecord host = conn.provider.proc;
11248        if (host == null) {
11249            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11250            return;
11251        }
11252
11253        mHandler.post(new Runnable() {
11254            @Override
11255            public void run() {
11256                mAppErrors.appNotResponding(host, null, null, false,
11257                        "ContentProvider not responding");
11258            }
11259        });
11260    }
11261
11262    public final void installSystemProviders() {
11263        List<ProviderInfo> providers;
11264        synchronized (this) {
11265            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11266            providers = generateApplicationProvidersLocked(app);
11267            if (providers != null) {
11268                for (int i=providers.size()-1; i>=0; i--) {
11269                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11270                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11271                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11272                                + ": not system .apk");
11273                        providers.remove(i);
11274                    }
11275                }
11276            }
11277        }
11278        if (providers != null) {
11279            mSystemThread.installSystemProviders(providers);
11280        }
11281
11282        mCoreSettingsObserver = new CoreSettingsObserver(this);
11283        mFontScaleSettingObserver = new FontScaleSettingObserver();
11284
11285        //mUsageStatsService.monitorPackages();
11286    }
11287
11288    private void startPersistentApps(int matchFlags) {
11289        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11290
11291        synchronized (this) {
11292            try {
11293                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11294                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11295                for (ApplicationInfo app : apps) {
11296                    if (!"android".equals(app.packageName)) {
11297                        addAppLocked(app, false, null /* ABI override */);
11298                    }
11299                }
11300            } catch (RemoteException ex) {
11301            }
11302        }
11303    }
11304
11305    /**
11306     * When a user is unlocked, we need to install encryption-unaware providers
11307     * belonging to any running apps.
11308     */
11309    private void installEncryptionUnawareProviders(int userId) {
11310        // We're only interested in providers that are encryption unaware, and
11311        // we don't care about uninstalled apps, since there's no way they're
11312        // running at this point.
11313        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11314
11315        synchronized (this) {
11316            final int NP = mProcessNames.getMap().size();
11317            for (int ip = 0; ip < NP; ip++) {
11318                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11319                final int NA = apps.size();
11320                for (int ia = 0; ia < NA; ia++) {
11321                    final ProcessRecord app = apps.valueAt(ia);
11322                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11323
11324                    final int NG = app.pkgList.size();
11325                    for (int ig = 0; ig < NG; ig++) {
11326                        try {
11327                            final String pkgName = app.pkgList.keyAt(ig);
11328                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11329                                    .getPackageInfo(pkgName, matchFlags, userId);
11330                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11331                                for (ProviderInfo pi : pkgInfo.providers) {
11332                                    // TODO: keep in sync with generateApplicationProvidersLocked
11333                                    final boolean processMatch = Objects.equals(pi.processName,
11334                                            app.processName) || pi.multiprocess;
11335                                    final boolean userMatch = isSingleton(pi.processName,
11336                                            pi.applicationInfo, pi.name, pi.flags)
11337                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11338                                    if (processMatch && userMatch) {
11339                                        Log.v(TAG, "Installing " + pi);
11340                                        app.thread.scheduleInstallProvider(pi);
11341                                    } else {
11342                                        Log.v(TAG, "Skipping " + pi);
11343                                    }
11344                                }
11345                            }
11346                        } catch (RemoteException ignored) {
11347                        }
11348                    }
11349                }
11350            }
11351        }
11352    }
11353
11354    /**
11355     * Allows apps to retrieve the MIME type of a URI.
11356     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11357     * users, then it does not need permission to access the ContentProvider.
11358     * Either, it needs cross-user uri grants.
11359     *
11360     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11361     *
11362     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11363     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11364     */
11365    public String getProviderMimeType(Uri uri, int userId) {
11366        enforceNotIsolatedCaller("getProviderMimeType");
11367        final String name = uri.getAuthority();
11368        int callingUid = Binder.getCallingUid();
11369        int callingPid = Binder.getCallingPid();
11370        long ident = 0;
11371        boolean clearedIdentity = false;
11372        synchronized (this) {
11373            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11374        }
11375        if (canClearIdentity(callingPid, callingUid, userId)) {
11376            clearedIdentity = true;
11377            ident = Binder.clearCallingIdentity();
11378        }
11379        ContentProviderHolder holder = null;
11380        try {
11381            holder = getContentProviderExternalUnchecked(name, null, userId);
11382            if (holder != null) {
11383                return holder.provider.getType(uri);
11384            }
11385        } catch (RemoteException e) {
11386            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11387            return null;
11388        } catch (Exception e) {
11389            Log.w(TAG, "Exception while determining type of " + uri, e);
11390            return null;
11391        } finally {
11392            // We need to clear the identity to call removeContentProviderExternalUnchecked
11393            if (!clearedIdentity) {
11394                ident = Binder.clearCallingIdentity();
11395            }
11396            try {
11397                if (holder != null) {
11398                    removeContentProviderExternalUnchecked(name, null, userId);
11399                }
11400            } finally {
11401                Binder.restoreCallingIdentity(ident);
11402            }
11403        }
11404
11405        return null;
11406    }
11407
11408    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11409        if (UserHandle.getUserId(callingUid) == userId) {
11410            return true;
11411        }
11412        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11413                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11414                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11415                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11416                return true;
11417        }
11418        return false;
11419    }
11420
11421    // =========================================================
11422    // GLOBAL MANAGEMENT
11423    // =========================================================
11424
11425    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11426            boolean isolated, int isolatedUid) {
11427        String proc = customProcess != null ? customProcess : info.processName;
11428        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11429        final int userId = UserHandle.getUserId(info.uid);
11430        int uid = info.uid;
11431        if (isolated) {
11432            if (isolatedUid == 0) {
11433                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11434                while (true) {
11435                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11436                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11437                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11438                    }
11439                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11440                    mNextIsolatedProcessUid++;
11441                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11442                        // No process for this uid, use it.
11443                        break;
11444                    }
11445                    stepsLeft--;
11446                    if (stepsLeft <= 0) {
11447                        return null;
11448                    }
11449                }
11450            } else {
11451                // Special case for startIsolatedProcess (internal only), where
11452                // the uid of the isolated process is specified by the caller.
11453                uid = isolatedUid;
11454            }
11455        }
11456        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11457        if (!mBooted && !mBooting
11458                && userId == UserHandle.USER_SYSTEM
11459                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11460            r.persistent = true;
11461        }
11462        addProcessNameLocked(r);
11463        return r;
11464    }
11465
11466    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11467            String abiOverride) {
11468        ProcessRecord app;
11469        if (!isolated) {
11470            app = getProcessRecordLocked(info.processName, info.uid, true);
11471        } else {
11472            app = null;
11473        }
11474
11475        if (app == null) {
11476            app = newProcessRecordLocked(info, null, isolated, 0);
11477            updateLruProcessLocked(app, false, null);
11478            updateOomAdjLocked();
11479        }
11480
11481        // This package really, really can not be stopped.
11482        try {
11483            AppGlobals.getPackageManager().setPackageStoppedState(
11484                    info.packageName, false, UserHandle.getUserId(app.uid));
11485        } catch (RemoteException e) {
11486        } catch (IllegalArgumentException e) {
11487            Slog.w(TAG, "Failed trying to unstop package "
11488                    + info.packageName + ": " + e);
11489        }
11490
11491        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11492            app.persistent = true;
11493            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11494        }
11495        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11496            mPersistentStartingProcesses.add(app);
11497            startProcessLocked(app, "added application", app.processName, abiOverride,
11498                    null /* entryPoint */, null /* entryPointArgs */);
11499        }
11500
11501        return app;
11502    }
11503
11504    public void unhandledBack() {
11505        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11506                "unhandledBack()");
11507
11508        synchronized(this) {
11509            final long origId = Binder.clearCallingIdentity();
11510            try {
11511                getFocusedStack().unhandledBackLocked();
11512            } finally {
11513                Binder.restoreCallingIdentity(origId);
11514            }
11515        }
11516    }
11517
11518    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11519        enforceNotIsolatedCaller("openContentUri");
11520        final int userId = UserHandle.getCallingUserId();
11521        String name = uri.getAuthority();
11522        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11523        ParcelFileDescriptor pfd = null;
11524        if (cph != null) {
11525            // We record the binder invoker's uid in thread-local storage before
11526            // going to the content provider to open the file.  Later, in the code
11527            // that handles all permissions checks, we look for this uid and use
11528            // that rather than the Activity Manager's own uid.  The effect is that
11529            // we do the check against the caller's permissions even though it looks
11530            // to the content provider like the Activity Manager itself is making
11531            // the request.
11532            Binder token = new Binder();
11533            sCallerIdentity.set(new Identity(
11534                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11535            try {
11536                pfd = cph.provider.openFile(null, uri, "r", null, token);
11537            } catch (FileNotFoundException e) {
11538                // do nothing; pfd will be returned null
11539            } finally {
11540                // Ensure that whatever happens, we clean up the identity state
11541                sCallerIdentity.remove();
11542                // Ensure we're done with the provider.
11543                removeContentProviderExternalUnchecked(name, null, userId);
11544            }
11545        } else {
11546            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11547        }
11548        return pfd;
11549    }
11550
11551    // Actually is sleeping or shutting down or whatever else in the future
11552    // is an inactive state.
11553    boolean isSleepingOrShuttingDownLocked() {
11554        return isSleepingLocked() || mShuttingDown;
11555    }
11556
11557    boolean isShuttingDownLocked() {
11558        return mShuttingDown;
11559    }
11560
11561    boolean isSleepingLocked() {
11562        return mSleeping;
11563    }
11564
11565    void onWakefulnessChanged(int wakefulness) {
11566        synchronized(this) {
11567            mWakefulness = wakefulness;
11568            updateSleepIfNeededLocked();
11569        }
11570    }
11571
11572    void finishRunningVoiceLocked() {
11573        if (mRunningVoice != null) {
11574            mRunningVoice = null;
11575            mVoiceWakeLock.release();
11576            updateSleepIfNeededLocked();
11577        }
11578    }
11579
11580    void startTimeTrackingFocusedActivityLocked() {
11581        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11582            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11583        }
11584    }
11585
11586    void updateSleepIfNeededLocked() {
11587        if (mSleeping && !shouldSleepLocked()) {
11588            mSleeping = false;
11589            startTimeTrackingFocusedActivityLocked();
11590            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11591            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11592            updateOomAdjLocked();
11593        } else if (!mSleeping && shouldSleepLocked()) {
11594            mSleeping = true;
11595            if (mCurAppTimeTracker != null) {
11596                mCurAppTimeTracker.stop();
11597            }
11598            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11599            mStackSupervisor.goingToSleepLocked();
11600            updateOomAdjLocked();
11601
11602            // Initialize the wake times of all processes.
11603            checkExcessivePowerUsageLocked(false);
11604            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11605            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11606            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11607        }
11608    }
11609
11610    private boolean shouldSleepLocked() {
11611        // Resume applications while running a voice interactor.
11612        if (mRunningVoice != null) {
11613            return false;
11614        }
11615
11616        // TODO: Transform the lock screen state into a sleep token instead.
11617        switch (mWakefulness) {
11618            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11619            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11620            case PowerManagerInternal.WAKEFULNESS_DOZING:
11621                // Pause applications whenever the lock screen is shown or any sleep
11622                // tokens have been acquired.
11623                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11624            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11625            default:
11626                // If we're asleep then pause applications unconditionally.
11627                return true;
11628        }
11629    }
11630
11631    /** Pokes the task persister. */
11632    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11633        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11634    }
11635
11636    /** Notifies all listeners when the task stack has changed. */
11637    void notifyTaskStackChangedLocked() {
11638        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11639        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11640        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11641        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11642    }
11643
11644    /** Notifies all listeners when an Activity is pinned. */
11645    void notifyActivityPinnedLocked() {
11646        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11647        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11648    }
11649
11650    /**
11651     * Notifies all listeners when an attempt was made to start an an activity that is already
11652     * running in the pinned stack and the activity was not actually started, but the task is
11653     * either brought to the front or a new Intent is delivered to it.
11654     */
11655    void notifyPinnedActivityRestartAttemptLocked() {
11656        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11657        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11658    }
11659
11660    /** Notifies all listeners when the pinned stack animation ends. */
11661    @Override
11662    public void notifyPinnedStackAnimationEnded() {
11663        synchronized (this) {
11664            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11665            mHandler.obtainMessage(
11666                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11667        }
11668    }
11669
11670    @Override
11671    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11672        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11673    }
11674
11675    @Override
11676    public boolean shutdown(int timeout) {
11677        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11678                != PackageManager.PERMISSION_GRANTED) {
11679            throw new SecurityException("Requires permission "
11680                    + android.Manifest.permission.SHUTDOWN);
11681        }
11682
11683        boolean timedout = false;
11684
11685        synchronized(this) {
11686            mShuttingDown = true;
11687            updateEventDispatchingLocked();
11688            timedout = mStackSupervisor.shutdownLocked(timeout);
11689        }
11690
11691        mAppOpsService.shutdown();
11692        if (mUsageStatsService != null) {
11693            mUsageStatsService.prepareShutdown();
11694        }
11695        mBatteryStatsService.shutdown();
11696        synchronized (this) {
11697            mProcessStats.shutdownLocked();
11698            notifyTaskPersisterLocked(null, true);
11699        }
11700
11701        return timedout;
11702    }
11703
11704    public final void activitySlept(IBinder token) {
11705        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11706
11707        final long origId = Binder.clearCallingIdentity();
11708
11709        synchronized (this) {
11710            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11711            if (r != null) {
11712                mStackSupervisor.activitySleptLocked(r);
11713            }
11714        }
11715
11716        Binder.restoreCallingIdentity(origId);
11717    }
11718
11719    private String lockScreenShownToString() {
11720        switch (mLockScreenShown) {
11721            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11722            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11723            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11724            default: return "Unknown=" + mLockScreenShown;
11725        }
11726    }
11727
11728    void logLockScreen(String msg) {
11729        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11730                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11731                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11732                + " mSleeping=" + mSleeping);
11733    }
11734
11735    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11736        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11737        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11738        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11739            boolean wasRunningVoice = mRunningVoice != null;
11740            mRunningVoice = session;
11741            if (!wasRunningVoice) {
11742                mVoiceWakeLock.acquire();
11743                updateSleepIfNeededLocked();
11744            }
11745        }
11746    }
11747
11748    private void updateEventDispatchingLocked() {
11749        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11750    }
11751
11752    public void setLockScreenShown(boolean showing, boolean occluded) {
11753        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11754                != PackageManager.PERMISSION_GRANTED) {
11755            throw new SecurityException("Requires permission "
11756                    + android.Manifest.permission.DEVICE_POWER);
11757        }
11758
11759        synchronized(this) {
11760            long ident = Binder.clearCallingIdentity();
11761            try {
11762                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11763                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11764                if (showing && occluded) {
11765                    // The lock screen is currently showing, but is occluded by a window that can
11766                    // show on top of the lock screen. In this can we want to dismiss the docked
11767                    // stack since it will be complicated/risky to try to put the activity on top
11768                    // of the lock screen in the right fullscreen configuration.
11769                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11770                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11771                }
11772
11773                updateSleepIfNeededLocked();
11774            } finally {
11775                Binder.restoreCallingIdentity(ident);
11776            }
11777        }
11778    }
11779
11780    @Override
11781    public void notifyLockedProfile(@UserIdInt int userId) {
11782        try {
11783            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11784                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11785            }
11786        } catch (RemoteException ex) {
11787            throw new SecurityException("Fail to check is caller a privileged app", ex);
11788        }
11789
11790        synchronized (this) {
11791            if (mStackSupervisor.isUserLockedProfile(userId)) {
11792                final long ident = Binder.clearCallingIdentity();
11793                try {
11794                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11795                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11796                        // If there is no device lock, we will show the profile's credential page.
11797                        mActivityStarter.showConfirmDeviceCredential(userId);
11798                    } else {
11799                        // Showing launcher to avoid user entering credential twice.
11800                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11801                    }
11802                } finally {
11803                    Binder.restoreCallingIdentity(ident);
11804                }
11805            }
11806        }
11807    }
11808
11809    @Override
11810    public void startConfirmDeviceCredentialIntent(Intent intent) {
11811        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11812        synchronized (this) {
11813            final long ident = Binder.clearCallingIdentity();
11814            try {
11815                mActivityStarter.startConfirmCredentialIntent(intent);
11816            } finally {
11817                Binder.restoreCallingIdentity(ident);
11818            }
11819        }
11820    }
11821
11822    @Override
11823    public void stopAppSwitches() {
11824        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11825                != PackageManager.PERMISSION_GRANTED) {
11826            throw new SecurityException("viewquires permission "
11827                    + android.Manifest.permission.STOP_APP_SWITCHES);
11828        }
11829
11830        synchronized(this) {
11831            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11832                    + APP_SWITCH_DELAY_TIME;
11833            mDidAppSwitch = false;
11834            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11835            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11836            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11837        }
11838    }
11839
11840    public void resumeAppSwitches() {
11841        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11842                != PackageManager.PERMISSION_GRANTED) {
11843            throw new SecurityException("Requires permission "
11844                    + android.Manifest.permission.STOP_APP_SWITCHES);
11845        }
11846
11847        synchronized(this) {
11848            // Note that we don't execute any pending app switches... we will
11849            // let those wait until either the timeout, or the next start
11850            // activity request.
11851            mAppSwitchesAllowedTime = 0;
11852        }
11853    }
11854
11855    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11856            int callingPid, int callingUid, String name) {
11857        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11858            return true;
11859        }
11860
11861        int perm = checkComponentPermission(
11862                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11863                sourceUid, -1, true);
11864        if (perm == PackageManager.PERMISSION_GRANTED) {
11865            return true;
11866        }
11867
11868        // If the actual IPC caller is different from the logical source, then
11869        // also see if they are allowed to control app switches.
11870        if (callingUid != -1 && callingUid != sourceUid) {
11871            perm = checkComponentPermission(
11872                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11873                    callingUid, -1, true);
11874            if (perm == PackageManager.PERMISSION_GRANTED) {
11875                return true;
11876            }
11877        }
11878
11879        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11880        return false;
11881    }
11882
11883    public void setDebugApp(String packageName, boolean waitForDebugger,
11884            boolean persistent) {
11885        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11886                "setDebugApp()");
11887
11888        long ident = Binder.clearCallingIdentity();
11889        try {
11890            // Note that this is not really thread safe if there are multiple
11891            // callers into it at the same time, but that's not a situation we
11892            // care about.
11893            if (persistent) {
11894                final ContentResolver resolver = mContext.getContentResolver();
11895                Settings.Global.putString(
11896                    resolver, Settings.Global.DEBUG_APP,
11897                    packageName);
11898                Settings.Global.putInt(
11899                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11900                    waitForDebugger ? 1 : 0);
11901            }
11902
11903            synchronized (this) {
11904                if (!persistent) {
11905                    mOrigDebugApp = mDebugApp;
11906                    mOrigWaitForDebugger = mWaitForDebugger;
11907                }
11908                mDebugApp = packageName;
11909                mWaitForDebugger = waitForDebugger;
11910                mDebugTransient = !persistent;
11911                if (packageName != null) {
11912                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11913                            false, UserHandle.USER_ALL, "set debug app");
11914                }
11915            }
11916        } finally {
11917            Binder.restoreCallingIdentity(ident);
11918        }
11919    }
11920
11921    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11922        synchronized (this) {
11923            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11924            if (!isDebuggable) {
11925                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11926                    throw new SecurityException("Process not debuggable: " + app.packageName);
11927                }
11928            }
11929
11930            mTrackAllocationApp = processName;
11931        }
11932    }
11933
11934    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11935        synchronized (this) {
11936            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11937            if (!isDebuggable) {
11938                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11939                    throw new SecurityException("Process not debuggable: " + app.packageName);
11940                }
11941            }
11942            mProfileApp = processName;
11943            mProfileFile = profilerInfo.profileFile;
11944            if (mProfileFd != null) {
11945                try {
11946                    mProfileFd.close();
11947                } catch (IOException e) {
11948                }
11949                mProfileFd = null;
11950            }
11951            mProfileFd = profilerInfo.profileFd;
11952            mSamplingInterval = profilerInfo.samplingInterval;
11953            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11954            mProfileType = 0;
11955        }
11956    }
11957
11958    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11959        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11960        if (!isDebuggable) {
11961            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11962                throw new SecurityException("Process not debuggable: " + app.packageName);
11963            }
11964        }
11965        mNativeDebuggingApp = processName;
11966    }
11967
11968    @Override
11969    public void setAlwaysFinish(boolean enabled) {
11970        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11971                "setAlwaysFinish()");
11972
11973        long ident = Binder.clearCallingIdentity();
11974        try {
11975            Settings.Global.putInt(
11976                    mContext.getContentResolver(),
11977                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11978
11979            synchronized (this) {
11980                mAlwaysFinishActivities = enabled;
11981            }
11982        } finally {
11983            Binder.restoreCallingIdentity(ident);
11984        }
11985    }
11986
11987    @Override
11988    public void setLenientBackgroundCheck(boolean enabled) {
11989        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11990                "setLenientBackgroundCheck()");
11991
11992        long ident = Binder.clearCallingIdentity();
11993        try {
11994            Settings.Global.putInt(
11995                    mContext.getContentResolver(),
11996                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11997
11998            synchronized (this) {
11999                mLenientBackgroundCheck = enabled;
12000            }
12001        } finally {
12002            Binder.restoreCallingIdentity(ident);
12003        }
12004    }
12005
12006    @Override
12007    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12008        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12009                "setActivityController()");
12010        synchronized (this) {
12011            mController = controller;
12012            mControllerIsAMonkey = imAMonkey;
12013            Watchdog.getInstance().setActivityController(controller);
12014        }
12015    }
12016
12017    @Override
12018    public void setUserIsMonkey(boolean userIsMonkey) {
12019        synchronized (this) {
12020            synchronized (mPidsSelfLocked) {
12021                final int callingPid = Binder.getCallingPid();
12022                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12023                if (precessRecord == null) {
12024                    throw new SecurityException("Unknown process: " + callingPid);
12025                }
12026                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12027                    throw new SecurityException("Only an instrumentation process "
12028                            + "with a UiAutomation can call setUserIsMonkey");
12029                }
12030            }
12031            mUserIsMonkey = userIsMonkey;
12032        }
12033    }
12034
12035    @Override
12036    public boolean isUserAMonkey() {
12037        synchronized (this) {
12038            // If there is a controller also implies the user is a monkey.
12039            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12040        }
12041    }
12042
12043    public void requestBugReport(int bugreportType) {
12044        String service = null;
12045        switch (bugreportType) {
12046            case ActivityManager.BUGREPORT_OPTION_FULL:
12047                service = "bugreport";
12048                break;
12049            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12050                service = "bugreportplus";
12051                break;
12052            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12053                service = "bugreportremote";
12054                break;
12055            case ActivityManager.BUGREPORT_OPTION_WEAR:
12056                service = "bugreportwear";
12057                break;
12058        }
12059        if (service == null) {
12060            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12061                    + bugreportType);
12062        }
12063        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12064        SystemProperties.set("ctl.start", service);
12065    }
12066
12067    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12068        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12069    }
12070
12071    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12072        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12073            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12074        }
12075        return KEY_DISPATCHING_TIMEOUT;
12076    }
12077
12078    @Override
12079    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12080        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12081                != PackageManager.PERMISSION_GRANTED) {
12082            throw new SecurityException("Requires permission "
12083                    + android.Manifest.permission.FILTER_EVENTS);
12084        }
12085        ProcessRecord proc;
12086        long timeout;
12087        synchronized (this) {
12088            synchronized (mPidsSelfLocked) {
12089                proc = mPidsSelfLocked.get(pid);
12090            }
12091            timeout = getInputDispatchingTimeoutLocked(proc);
12092        }
12093
12094        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12095            return -1;
12096        }
12097
12098        return timeout;
12099    }
12100
12101    /**
12102     * Handle input dispatching timeouts.
12103     * Returns whether input dispatching should be aborted or not.
12104     */
12105    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12106            final ActivityRecord activity, final ActivityRecord parent,
12107            final boolean aboveSystem, String reason) {
12108        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12109                != PackageManager.PERMISSION_GRANTED) {
12110            throw new SecurityException("Requires permission "
12111                    + android.Manifest.permission.FILTER_EVENTS);
12112        }
12113
12114        final String annotation;
12115        if (reason == null) {
12116            annotation = "Input dispatching timed out";
12117        } else {
12118            annotation = "Input dispatching timed out (" + reason + ")";
12119        }
12120
12121        if (proc != null) {
12122            synchronized (this) {
12123                if (proc.debugging) {
12124                    return false;
12125                }
12126
12127                if (mDidDexOpt) {
12128                    // Give more time since we were dexopting.
12129                    mDidDexOpt = false;
12130                    return false;
12131                }
12132
12133                if (proc.instrumentationClass != null) {
12134                    Bundle info = new Bundle();
12135                    info.putString("shortMsg", "keyDispatchingTimedOut");
12136                    info.putString("longMsg", annotation);
12137                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12138                    return true;
12139                }
12140            }
12141            mHandler.post(new Runnable() {
12142                @Override
12143                public void run() {
12144                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12145                }
12146            });
12147        }
12148
12149        return true;
12150    }
12151
12152    @Override
12153    public Bundle getAssistContextExtras(int requestType) {
12154        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12155                null, null, true /* focused */, true /* newSessionId */,
12156                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12157        if (pae == null) {
12158            return null;
12159        }
12160        synchronized (pae) {
12161            while (!pae.haveResult) {
12162                try {
12163                    pae.wait();
12164                } catch (InterruptedException e) {
12165                }
12166            }
12167        }
12168        synchronized (this) {
12169            buildAssistBundleLocked(pae, pae.result);
12170            mPendingAssistExtras.remove(pae);
12171            mUiHandler.removeCallbacks(pae);
12172        }
12173        return pae.extras;
12174    }
12175
12176    @Override
12177    public boolean isAssistDataAllowedOnCurrentActivity() {
12178        int userId;
12179        synchronized (this) {
12180            userId = mUserController.getCurrentUserIdLocked();
12181            ActivityRecord activity = getFocusedStack().topActivity();
12182            if (activity == null) {
12183                return false;
12184            }
12185            userId = activity.userId;
12186        }
12187        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12188                Context.DEVICE_POLICY_SERVICE);
12189        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12190    }
12191
12192    @Override
12193    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12194        long ident = Binder.clearCallingIdentity();
12195        try {
12196            synchronized (this) {
12197                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12198                ActivityRecord top = getFocusedStack().topActivity();
12199                if (top != caller) {
12200                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12201                            + " is not current top " + top);
12202                    return false;
12203                }
12204                if (!top.nowVisible) {
12205                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12206                            + " is not visible");
12207                    return false;
12208                }
12209            }
12210            AssistUtils utils = new AssistUtils(mContext);
12211            return utils.showSessionForActiveService(args,
12212                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12213        } finally {
12214            Binder.restoreCallingIdentity(ident);
12215        }
12216    }
12217
12218    @Override
12219    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12220            Bundle receiverExtras,
12221            IBinder activityToken, boolean focused, boolean newSessionId) {
12222        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12223                activityToken, focused, newSessionId,
12224                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12225                != null;
12226    }
12227
12228    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12229            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12230            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12231        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12232                "enqueueAssistContext()");
12233        synchronized (this) {
12234            ActivityRecord activity = getFocusedStack().topActivity();
12235            if (activity == null) {
12236                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12237                return null;
12238            }
12239            if (activity.app == null || activity.app.thread == null) {
12240                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12241                return null;
12242            }
12243            if (focused) {
12244                if (activityToken != null) {
12245                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12246                    if (activity != caller) {
12247                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12248                                + " is not current top " + activity);
12249                        return null;
12250                    }
12251                }
12252            } else {
12253                activity = ActivityRecord.forTokenLocked(activityToken);
12254                if (activity == null) {
12255                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12256                            + " couldn't be found");
12257                    return null;
12258                }
12259            }
12260
12261            PendingAssistExtras pae;
12262            Bundle extras = new Bundle();
12263            if (args != null) {
12264                extras.putAll(args);
12265            }
12266            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12267            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12268            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12269                    userHandle);
12270            // Increment the sessionId if necessary
12271            if (newSessionId) {
12272                mViSessionId++;
12273            }
12274            try {
12275                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12276                        requestType, mViSessionId);
12277                mPendingAssistExtras.add(pae);
12278                mUiHandler.postDelayed(pae, timeout);
12279            } catch (RemoteException e) {
12280                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12281                return null;
12282            }
12283            return pae;
12284        }
12285    }
12286
12287    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12288        IResultReceiver receiver;
12289        synchronized (this) {
12290            mPendingAssistExtras.remove(pae);
12291            receiver = pae.receiver;
12292        }
12293        if (receiver != null) {
12294            // Caller wants result sent back to them.
12295            Bundle sendBundle = new Bundle();
12296            // At least return the receiver extras
12297            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12298                    pae.receiverExtras);
12299            try {
12300                pae.receiver.send(0, sendBundle);
12301            } catch (RemoteException e) {
12302            }
12303        }
12304    }
12305
12306    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12307        if (result != null) {
12308            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12309        }
12310        if (pae.hint != null) {
12311            pae.extras.putBoolean(pae.hint, true);
12312        }
12313    }
12314
12315    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12316            AssistContent content, Uri referrer) {
12317        PendingAssistExtras pae = (PendingAssistExtras)token;
12318        synchronized (pae) {
12319            pae.result = extras;
12320            pae.structure = structure;
12321            pae.content = content;
12322            if (referrer != null) {
12323                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12324            }
12325            pae.haveResult = true;
12326            pae.notifyAll();
12327            if (pae.intent == null && pae.receiver == null) {
12328                // Caller is just waiting for the result.
12329                return;
12330            }
12331        }
12332
12333        // We are now ready to launch the assist activity.
12334        IResultReceiver sendReceiver = null;
12335        Bundle sendBundle = null;
12336        synchronized (this) {
12337            buildAssistBundleLocked(pae, extras);
12338            boolean exists = mPendingAssistExtras.remove(pae);
12339            mUiHandler.removeCallbacks(pae);
12340            if (!exists) {
12341                // Timed out.
12342                return;
12343            }
12344            if ((sendReceiver=pae.receiver) != null) {
12345                // Caller wants result sent back to them.
12346                sendBundle = new Bundle();
12347                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12348                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12349                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12350                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12351                        pae.receiverExtras);
12352            }
12353        }
12354        if (sendReceiver != null) {
12355            try {
12356                sendReceiver.send(0, sendBundle);
12357            } catch (RemoteException e) {
12358            }
12359            return;
12360        }
12361
12362        long ident = Binder.clearCallingIdentity();
12363        try {
12364            pae.intent.replaceExtras(pae.extras);
12365            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12366                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12367                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12368            closeSystemDialogs("assist");
12369            try {
12370                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12371            } catch (ActivityNotFoundException e) {
12372                Slog.w(TAG, "No activity to handle assist action.", e);
12373            }
12374        } finally {
12375            Binder.restoreCallingIdentity(ident);
12376        }
12377    }
12378
12379    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12380            Bundle args) {
12381        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12382                true /* focused */, true /* newSessionId */,
12383                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12384    }
12385
12386    public void registerProcessObserver(IProcessObserver observer) {
12387        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12388                "registerProcessObserver()");
12389        synchronized (this) {
12390            mProcessObservers.register(observer);
12391        }
12392    }
12393
12394    @Override
12395    public void unregisterProcessObserver(IProcessObserver observer) {
12396        synchronized (this) {
12397            mProcessObservers.unregister(observer);
12398        }
12399    }
12400
12401    @Override
12402    public void registerUidObserver(IUidObserver observer, int which) {
12403        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12404                "registerUidObserver()");
12405        synchronized (this) {
12406            mUidObservers.register(observer, which);
12407        }
12408    }
12409
12410    @Override
12411    public void unregisterUidObserver(IUidObserver observer) {
12412        synchronized (this) {
12413            mUidObservers.unregister(observer);
12414        }
12415    }
12416
12417    @Override
12418    public boolean convertFromTranslucent(IBinder token) {
12419        final long origId = Binder.clearCallingIdentity();
12420        try {
12421            synchronized (this) {
12422                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12423                if (r == null) {
12424                    return false;
12425                }
12426                final boolean translucentChanged = r.changeWindowTranslucency(true);
12427                if (translucentChanged) {
12428                    r.task.stack.releaseBackgroundResources(r);
12429                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12430                }
12431                mWindowManager.setAppFullscreen(token, true);
12432                return translucentChanged;
12433            }
12434        } finally {
12435            Binder.restoreCallingIdentity(origId);
12436        }
12437    }
12438
12439    @Override
12440    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12441        final long origId = Binder.clearCallingIdentity();
12442        try {
12443            synchronized (this) {
12444                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12445                if (r == null) {
12446                    return false;
12447                }
12448                int index = r.task.mActivities.lastIndexOf(r);
12449                if (index > 0) {
12450                    ActivityRecord under = r.task.mActivities.get(index - 1);
12451                    under.returningOptions = options;
12452                }
12453                final boolean translucentChanged = r.changeWindowTranslucency(false);
12454                if (translucentChanged) {
12455                    r.task.stack.convertActivityToTranslucent(r);
12456                }
12457                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12458                mWindowManager.setAppFullscreen(token, false);
12459                return translucentChanged;
12460            }
12461        } finally {
12462            Binder.restoreCallingIdentity(origId);
12463        }
12464    }
12465
12466    @Override
12467    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12468        final long origId = Binder.clearCallingIdentity();
12469        try {
12470            synchronized (this) {
12471                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12472                if (r != null) {
12473                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12474                }
12475            }
12476            return false;
12477        } finally {
12478            Binder.restoreCallingIdentity(origId);
12479        }
12480    }
12481
12482    @Override
12483    public boolean isBackgroundVisibleBehind(IBinder token) {
12484        final long origId = Binder.clearCallingIdentity();
12485        try {
12486            synchronized (this) {
12487                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12488                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12489                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12490                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12491                return visible;
12492            }
12493        } finally {
12494            Binder.restoreCallingIdentity(origId);
12495        }
12496    }
12497
12498    @Override
12499    public ActivityOptions getActivityOptions(IBinder token) {
12500        final long origId = Binder.clearCallingIdentity();
12501        try {
12502            synchronized (this) {
12503                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12504                if (r != null) {
12505                    final ActivityOptions activityOptions = r.pendingOptions;
12506                    r.pendingOptions = null;
12507                    return activityOptions;
12508                }
12509                return null;
12510            }
12511        } finally {
12512            Binder.restoreCallingIdentity(origId);
12513        }
12514    }
12515
12516    @Override
12517    public void setImmersive(IBinder token, boolean immersive) {
12518        synchronized(this) {
12519            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12520            if (r == null) {
12521                throw new IllegalArgumentException();
12522            }
12523            r.immersive = immersive;
12524
12525            // update associated state if we're frontmost
12526            if (r == mFocusedActivity) {
12527                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12528                applyUpdateLockStateLocked(r);
12529            }
12530        }
12531    }
12532
12533    @Override
12534    public boolean isImmersive(IBinder token) {
12535        synchronized (this) {
12536            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12537            if (r == null) {
12538                throw new IllegalArgumentException();
12539            }
12540            return r.immersive;
12541        }
12542    }
12543
12544    public void setVrThread(int tid) {
12545        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12546            throw new UnsupportedOperationException("VR mode not supported on this device!");
12547        }
12548
12549        synchronized (this) {
12550            ProcessRecord proc;
12551            synchronized (mPidsSelfLocked) {
12552                final int pid = Binder.getCallingPid();
12553                proc = mPidsSelfLocked.get(pid);
12554                if (proc != null && mInVrMode && tid >= 0) {
12555                    // ensure the tid belongs to the process
12556                    if (!Process.isThreadInProcess(pid, tid)) {
12557                        throw new IllegalArgumentException("VR thread does not belong to process");
12558                    }
12559                    // reset existing VR thread to CFS
12560                    if (proc.vrThreadTid != 0) {
12561                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12562                    }
12563                    // add check to guarantee that tid belongs to pid?
12564                    proc.vrThreadTid = tid;
12565                    // promote to FIFO now if the tid is non-zero
12566                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12567                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12568                    }
12569                } else {
12570                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12571                }
12572            }
12573        }
12574    }
12575
12576    @Override
12577    public void setRenderThread(int tid) {
12578        synchronized (this) {
12579            ProcessRecord proc;
12580            synchronized (mPidsSelfLocked) {
12581                int pid = Binder.getCallingPid();
12582                proc = mPidsSelfLocked.get(pid);
12583                if (mUseFifoUiScheduling && proc != null && proc.renderThreadTid == 0 && tid > 0) {
12584                    // ensure the tid belongs to the process
12585                    if (!Process.isThreadInProcess(pid, tid)) {
12586                        throw new IllegalArgumentException(
12587                            "Render thread does not belong to process");
12588                    }
12589                    proc.renderThreadTid = tid;
12590                    if (DEBUG_OOM_ADJ) {
12591                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12592                    }
12593                    // promote to FIFO now
12594                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12595                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12596                        Process.setThreadScheduler(proc.renderThreadTid,
12597                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12598                    }
12599                } else {
12600                    if (DEBUG_OOM_ADJ) {
12601                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12602                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12603                               mUseFifoUiScheduling);
12604                    }
12605                }
12606            }
12607        }
12608    }
12609
12610    @Override
12611    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12612        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12613            throw new UnsupportedOperationException("VR mode not supported on this device!");
12614        }
12615
12616        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12617
12618        ActivityRecord r;
12619        synchronized (this) {
12620            r = ActivityRecord.isInStackLocked(token);
12621        }
12622
12623        if (r == null) {
12624            throw new IllegalArgumentException();
12625        }
12626
12627        int err;
12628        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12629                VrManagerInternal.NO_ERROR) {
12630            return err;
12631        }
12632
12633        synchronized(this) {
12634            r.requestedVrComponent = (enabled) ? packageName : null;
12635
12636            // Update associated state if this activity is currently focused
12637            if (r == mFocusedActivity) {
12638                applyUpdateVrModeLocked(r);
12639            }
12640            return 0;
12641        }
12642    }
12643
12644    @Override
12645    public boolean isVrModePackageEnabled(ComponentName packageName) {
12646        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12647            throw new UnsupportedOperationException("VR mode not supported on this device!");
12648        }
12649
12650        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12651
12652        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12653                VrManagerInternal.NO_ERROR;
12654    }
12655
12656    public boolean isTopActivityImmersive() {
12657        enforceNotIsolatedCaller("startActivity");
12658        synchronized (this) {
12659            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12660            return (r != null) ? r.immersive : false;
12661        }
12662    }
12663
12664    @Override
12665    public boolean isTopOfTask(IBinder token) {
12666        synchronized (this) {
12667            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12668            if (r == null) {
12669                throw new IllegalArgumentException();
12670            }
12671            return r.task.getTopActivity() == r;
12672        }
12673    }
12674
12675    public final void enterSafeMode() {
12676        synchronized(this) {
12677            // It only makes sense to do this before the system is ready
12678            // and started launching other packages.
12679            if (!mSystemReady) {
12680                try {
12681                    AppGlobals.getPackageManager().enterSafeMode();
12682                } catch (RemoteException e) {
12683                }
12684            }
12685
12686            mSafeMode = true;
12687        }
12688    }
12689
12690    public final void showSafeModeOverlay() {
12691        View v = LayoutInflater.from(mContext).inflate(
12692                com.android.internal.R.layout.safe_mode, null);
12693        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12694        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12695        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12696        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12697        lp.gravity = Gravity.BOTTOM | Gravity.START;
12698        lp.format = v.getBackground().getOpacity();
12699        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12700                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12701        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12702        ((WindowManager)mContext.getSystemService(
12703                Context.WINDOW_SERVICE)).addView(v, lp);
12704    }
12705
12706    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12707        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12708            return;
12709        }
12710        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12711        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12712        synchronized (stats) {
12713            if (mBatteryStatsService.isOnBattery()) {
12714                mBatteryStatsService.enforceCallingPermission();
12715                int MY_UID = Binder.getCallingUid();
12716                final int uid;
12717                if (sender == null) {
12718                    uid = sourceUid;
12719                } else {
12720                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12721                }
12722                BatteryStatsImpl.Uid.Pkg pkg =
12723                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12724                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12725                pkg.noteWakeupAlarmLocked(tag);
12726            }
12727        }
12728    }
12729
12730    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12731        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12732            return;
12733        }
12734        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12735        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12736        synchronized (stats) {
12737            mBatteryStatsService.enforceCallingPermission();
12738            int MY_UID = Binder.getCallingUid();
12739            final int uid;
12740            if (sender == null) {
12741                uid = sourceUid;
12742            } else {
12743                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12744            }
12745            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12746        }
12747    }
12748
12749    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12750        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12751            return;
12752        }
12753        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12754        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12755        synchronized (stats) {
12756            mBatteryStatsService.enforceCallingPermission();
12757            int MY_UID = Binder.getCallingUid();
12758            final int uid;
12759            if (sender == null) {
12760                uid = sourceUid;
12761            } else {
12762                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12763            }
12764            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12765        }
12766    }
12767
12768    public boolean killPids(int[] pids, String pReason, boolean secure) {
12769        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12770            throw new SecurityException("killPids only available to the system");
12771        }
12772        String reason = (pReason == null) ? "Unknown" : pReason;
12773        // XXX Note: don't acquire main activity lock here, because the window
12774        // manager calls in with its locks held.
12775
12776        boolean killed = false;
12777        synchronized (mPidsSelfLocked) {
12778            int worstType = 0;
12779            for (int i=0; i<pids.length; i++) {
12780                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12781                if (proc != null) {
12782                    int type = proc.setAdj;
12783                    if (type > worstType) {
12784                        worstType = type;
12785                    }
12786                }
12787            }
12788
12789            // If the worst oom_adj is somewhere in the cached proc LRU range,
12790            // then constrain it so we will kill all cached procs.
12791            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12792                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12793                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12794            }
12795
12796            // If this is not a secure call, don't let it kill processes that
12797            // are important.
12798            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12799                worstType = ProcessList.SERVICE_ADJ;
12800            }
12801
12802            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12803            for (int i=0; i<pids.length; i++) {
12804                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12805                if (proc == null) {
12806                    continue;
12807                }
12808                int adj = proc.setAdj;
12809                if (adj >= worstType && !proc.killedByAm) {
12810                    proc.kill(reason, true);
12811                    killed = true;
12812                }
12813            }
12814        }
12815        return killed;
12816    }
12817
12818    @Override
12819    public void killUid(int appId, int userId, String reason) {
12820        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12821        synchronized (this) {
12822            final long identity = Binder.clearCallingIdentity();
12823            try {
12824                killPackageProcessesLocked(null, appId, userId,
12825                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12826                        reason != null ? reason : "kill uid");
12827            } finally {
12828                Binder.restoreCallingIdentity(identity);
12829            }
12830        }
12831    }
12832
12833    @Override
12834    public boolean killProcessesBelowForeground(String reason) {
12835        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12836            throw new SecurityException("killProcessesBelowForeground() only available to system");
12837        }
12838
12839        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12840    }
12841
12842    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12843        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12844            throw new SecurityException("killProcessesBelowAdj() only available to system");
12845        }
12846
12847        boolean killed = false;
12848        synchronized (mPidsSelfLocked) {
12849            final int size = mPidsSelfLocked.size();
12850            for (int i = 0; i < size; i++) {
12851                final int pid = mPidsSelfLocked.keyAt(i);
12852                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12853                if (proc == null) continue;
12854
12855                final int adj = proc.setAdj;
12856                if (adj > belowAdj && !proc.killedByAm) {
12857                    proc.kill(reason, true);
12858                    killed = true;
12859                }
12860            }
12861        }
12862        return killed;
12863    }
12864
12865    @Override
12866    public void hang(final IBinder who, boolean allowRestart) {
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        final IBinder.DeathRecipient death = new DeathRecipient() {
12874            @Override
12875            public void binderDied() {
12876                synchronized (this) {
12877                    notifyAll();
12878                }
12879            }
12880        };
12881
12882        try {
12883            who.linkToDeath(death, 0);
12884        } catch (RemoteException e) {
12885            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12886            return;
12887        }
12888
12889        synchronized (this) {
12890            Watchdog.getInstance().setAllowRestart(allowRestart);
12891            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12892            synchronized (death) {
12893                while (who.isBinderAlive()) {
12894                    try {
12895                        death.wait();
12896                    } catch (InterruptedException e) {
12897                    }
12898                }
12899            }
12900            Watchdog.getInstance().setAllowRestart(true);
12901        }
12902    }
12903
12904    @Override
12905    public void restart() {
12906        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12907                != PackageManager.PERMISSION_GRANTED) {
12908            throw new SecurityException("Requires permission "
12909                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12910        }
12911
12912        Log.i(TAG, "Sending shutdown broadcast...");
12913
12914        BroadcastReceiver br = new BroadcastReceiver() {
12915            @Override public void onReceive(Context context, Intent intent) {
12916                // Now the broadcast is done, finish up the low-level shutdown.
12917                Log.i(TAG, "Shutting down activity manager...");
12918                shutdown(10000);
12919                Log.i(TAG, "Shutdown complete, restarting!");
12920                Process.killProcess(Process.myPid());
12921                System.exit(10);
12922            }
12923        };
12924
12925        // First send the high-level shut down broadcast.
12926        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12927        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12928        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12929        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12930        mContext.sendOrderedBroadcastAsUser(intent,
12931                UserHandle.ALL, null, br, mHandler, 0, null, null);
12932        */
12933        br.onReceive(mContext, intent);
12934    }
12935
12936    private long getLowRamTimeSinceIdle(long now) {
12937        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12938    }
12939
12940    @Override
12941    public void performIdleMaintenance() {
12942        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12943                != PackageManager.PERMISSION_GRANTED) {
12944            throw new SecurityException("Requires permission "
12945                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12946        }
12947
12948        synchronized (this) {
12949            final long now = SystemClock.uptimeMillis();
12950            final long timeSinceLastIdle = now - mLastIdleTime;
12951            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12952            mLastIdleTime = now;
12953            mLowRamTimeSinceLastIdle = 0;
12954            if (mLowRamStartTime != 0) {
12955                mLowRamStartTime = now;
12956            }
12957
12958            StringBuilder sb = new StringBuilder(128);
12959            sb.append("Idle maintenance over ");
12960            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12961            sb.append(" low RAM for ");
12962            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12963            Slog.i(TAG, sb.toString());
12964
12965            // If at least 1/3 of our time since the last idle period has been spent
12966            // with RAM low, then we want to kill processes.
12967            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12968
12969            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12970                ProcessRecord proc = mLruProcesses.get(i);
12971                if (proc.notCachedSinceIdle) {
12972                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12973                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12974                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12975                        if (doKilling && proc.initialIdlePss != 0
12976                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12977                            sb = new StringBuilder(128);
12978                            sb.append("Kill");
12979                            sb.append(proc.processName);
12980                            sb.append(" in idle maint: pss=");
12981                            sb.append(proc.lastPss);
12982                            sb.append(", swapPss=");
12983                            sb.append(proc.lastSwapPss);
12984                            sb.append(", initialPss=");
12985                            sb.append(proc.initialIdlePss);
12986                            sb.append(", period=");
12987                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12988                            sb.append(", lowRamPeriod=");
12989                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12990                            Slog.wtfQuiet(TAG, sb.toString());
12991                            proc.kill("idle maint (pss " + proc.lastPss
12992                                    + " from " + proc.initialIdlePss + ")", true);
12993                        }
12994                    }
12995                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12996                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12997                    proc.notCachedSinceIdle = true;
12998                    proc.initialIdlePss = 0;
12999                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13000                            mTestPssMode, isSleepingLocked(), now);
13001                }
13002            }
13003
13004            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13005            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13006        }
13007    }
13008
13009    @Override
13010    public void sendIdleJobTrigger() {
13011        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13012                != PackageManager.PERMISSION_GRANTED) {
13013            throw new SecurityException("Requires permission "
13014                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13015        }
13016
13017        final long ident = Binder.clearCallingIdentity();
13018        try {
13019            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13020                    .setPackage("android")
13021                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13022            broadcastIntent(null, intent, null, null, 0, null, null, null,
13023                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13024        } finally {
13025            Binder.restoreCallingIdentity(ident);
13026        }
13027    }
13028
13029    private void retrieveSettings() {
13030        final ContentResolver resolver = mContext.getContentResolver();
13031        final boolean freeformWindowManagement =
13032                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13033                        || Settings.Global.getInt(
13034                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13035        final boolean supportsPictureInPicture =
13036                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13037
13038        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13039        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13040        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13041        final boolean alwaysFinishActivities =
13042                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13043        final boolean lenientBackgroundCheck =
13044                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13045        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13046        final boolean forceResizable = Settings.Global.getInt(
13047                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13048        final boolean supportsLeanbackOnly =
13049                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13050
13051        // Transfer any global setting for forcing RTL layout, into a System Property
13052        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13053
13054        final Configuration configuration = new Configuration();
13055        Settings.System.getConfiguration(resolver, configuration);
13056        if (forceRtl) {
13057            // This will take care of setting the correct layout direction flags
13058            configuration.setLayoutDirection(configuration.locale);
13059        }
13060
13061        synchronized (this) {
13062            mDebugApp = mOrigDebugApp = debugApp;
13063            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13064            mAlwaysFinishActivities = alwaysFinishActivities;
13065            mLenientBackgroundCheck = lenientBackgroundCheck;
13066            mSupportsLeanbackOnly = supportsLeanbackOnly;
13067            mForceResizableActivities = forceResizable;
13068            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13069            if (supportsMultiWindow || forceResizable) {
13070                mSupportsMultiWindow = true;
13071                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13072                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13073            } else {
13074                mSupportsMultiWindow = false;
13075                mSupportsFreeformWindowManagement = false;
13076                mSupportsPictureInPicture = false;
13077            }
13078            // This happens before any activities are started, so we can
13079            // change mConfiguration in-place.
13080            updateConfigurationLocked(configuration, null, true);
13081            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13082                    "Initial config: " + mConfiguration);
13083
13084            // Load resources only after the current configuration has been set.
13085            final Resources res = mContext.getResources();
13086            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13087            mThumbnailWidth = res.getDimensionPixelSize(
13088                    com.android.internal.R.dimen.thumbnail_width);
13089            mThumbnailHeight = res.getDimensionPixelSize(
13090                    com.android.internal.R.dimen.thumbnail_height);
13091            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13092                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13093            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13094                    com.android.internal.R.string.config_appsNotReportingCrashes));
13095            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13096                mFullscreenThumbnailScale = (float) res
13097                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13098                    (float) mConfiguration.screenWidthDp;
13099            } else {
13100                mFullscreenThumbnailScale = res.getFraction(
13101                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13102            }
13103        }
13104    }
13105
13106    public boolean testIsSystemReady() {
13107        // no need to synchronize(this) just to read & return the value
13108        return mSystemReady;
13109    }
13110
13111    public void systemReady(final Runnable goingCallback) {
13112        synchronized(this) {
13113            if (mSystemReady) {
13114                // If we're done calling all the receivers, run the next "boot phase" passed in
13115                // by the SystemServer
13116                if (goingCallback != null) {
13117                    goingCallback.run();
13118                }
13119                return;
13120            }
13121
13122            mLocalDeviceIdleController
13123                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13124
13125            // Make sure we have the current profile info, since it is needed for security checks.
13126            mUserController.onSystemReady();
13127            mRecentTasks.onSystemReadyLocked();
13128            mAppOpsService.systemReady();
13129            mSystemReady = true;
13130        }
13131
13132        ArrayList<ProcessRecord> procsToKill = null;
13133        synchronized(mPidsSelfLocked) {
13134            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13135                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13136                if (!isAllowedWhileBooting(proc.info)){
13137                    if (procsToKill == null) {
13138                        procsToKill = new ArrayList<ProcessRecord>();
13139                    }
13140                    procsToKill.add(proc);
13141                }
13142            }
13143        }
13144
13145        synchronized(this) {
13146            if (procsToKill != null) {
13147                for (int i=procsToKill.size()-1; i>=0; i--) {
13148                    ProcessRecord proc = procsToKill.get(i);
13149                    Slog.i(TAG, "Removing system update proc: " + proc);
13150                    removeProcessLocked(proc, true, false, "system update done");
13151                }
13152            }
13153
13154            // Now that we have cleaned up any update processes, we
13155            // are ready to start launching real processes and know that
13156            // we won't trample on them any more.
13157            mProcessesReady = true;
13158        }
13159
13160        Slog.i(TAG, "System now ready");
13161        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13162            SystemClock.uptimeMillis());
13163
13164        synchronized(this) {
13165            // Make sure we have no pre-ready processes sitting around.
13166
13167            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13168                ResolveInfo ri = mContext.getPackageManager()
13169                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13170                                STOCK_PM_FLAGS);
13171                CharSequence errorMsg = null;
13172                if (ri != null) {
13173                    ActivityInfo ai = ri.activityInfo;
13174                    ApplicationInfo app = ai.applicationInfo;
13175                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13176                        mTopAction = Intent.ACTION_FACTORY_TEST;
13177                        mTopData = null;
13178                        mTopComponent = new ComponentName(app.packageName,
13179                                ai.name);
13180                    } else {
13181                        errorMsg = mContext.getResources().getText(
13182                                com.android.internal.R.string.factorytest_not_system);
13183                    }
13184                } else {
13185                    errorMsg = mContext.getResources().getText(
13186                            com.android.internal.R.string.factorytest_no_action);
13187                }
13188                if (errorMsg != null) {
13189                    mTopAction = null;
13190                    mTopData = null;
13191                    mTopComponent = null;
13192                    Message msg = Message.obtain();
13193                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13194                    msg.getData().putCharSequence("msg", errorMsg);
13195                    mUiHandler.sendMessage(msg);
13196                }
13197            }
13198        }
13199
13200        retrieveSettings();
13201        final int currentUserId;
13202        synchronized (this) {
13203            currentUserId = mUserController.getCurrentUserIdLocked();
13204            readGrantedUriPermissionsLocked();
13205        }
13206
13207        if (goingCallback != null) goingCallback.run();
13208
13209        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13210                Integer.toString(currentUserId), currentUserId);
13211        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13212                Integer.toString(currentUserId), currentUserId);
13213        mSystemServiceManager.startUser(currentUserId);
13214
13215        synchronized (this) {
13216            // Only start up encryption-aware persistent apps; once user is
13217            // unlocked we'll come back around and start unaware apps
13218            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13219
13220            // Start up initial activity.
13221            mBooting = true;
13222            // Enable home activity for system user, so that the system can always boot
13223            if (UserManager.isSplitSystemUser()) {
13224                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13225                try {
13226                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13227                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13228                            UserHandle.USER_SYSTEM);
13229                } catch (RemoteException e) {
13230                    throw e.rethrowAsRuntimeException();
13231                }
13232            }
13233            startHomeActivityLocked(currentUserId, "systemReady");
13234
13235            try {
13236                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13237                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13238                            + " data partition or your device will be unstable.");
13239                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13240                }
13241            } catch (RemoteException e) {
13242            }
13243
13244            if (!Build.isBuildConsistent()) {
13245                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13246                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13247            }
13248
13249            long ident = Binder.clearCallingIdentity();
13250            try {
13251                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13252                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13253                        | Intent.FLAG_RECEIVER_FOREGROUND);
13254                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13255                broadcastIntentLocked(null, null, intent,
13256                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13257                        null, false, false, MY_PID, Process.SYSTEM_UID,
13258                        currentUserId);
13259                intent = new Intent(Intent.ACTION_USER_STARTING);
13260                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13261                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13262                broadcastIntentLocked(null, null, intent,
13263                        null, new IIntentReceiver.Stub() {
13264                            @Override
13265                            public void performReceive(Intent intent, int resultCode, String data,
13266                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13267                                    throws RemoteException {
13268                            }
13269                        }, 0, null, null,
13270                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13271                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13272            } catch (Throwable t) {
13273                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13274            } finally {
13275                Binder.restoreCallingIdentity(ident);
13276            }
13277            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13278            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13279        }
13280    }
13281
13282    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13283        synchronized (this) {
13284            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13285        }
13286    }
13287
13288    void skipCurrentReceiverLocked(ProcessRecord app) {
13289        for (BroadcastQueue queue : mBroadcastQueues) {
13290            queue.skipCurrentReceiverLocked(app);
13291        }
13292    }
13293
13294    /**
13295     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13296     * The application process will exit immediately after this call returns.
13297     * @param app object of the crashing app, null for the system server
13298     * @param crashInfo describing the exception
13299     */
13300    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13301        ProcessRecord r = findAppProcess(app, "Crash");
13302        final String processName = app == null ? "system_server"
13303                : (r == null ? "unknown" : r.processName);
13304
13305        handleApplicationCrashInner("crash", r, processName, crashInfo);
13306    }
13307
13308    /* Native crash reporting uses this inner version because it needs to be somewhat
13309     * decoupled from the AM-managed cleanup lifecycle
13310     */
13311    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13312            ApplicationErrorReport.CrashInfo crashInfo) {
13313        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13314                UserHandle.getUserId(Binder.getCallingUid()), processName,
13315                r == null ? -1 : r.info.flags,
13316                crashInfo.exceptionClassName,
13317                crashInfo.exceptionMessage,
13318                crashInfo.throwFileName,
13319                crashInfo.throwLineNumber);
13320
13321        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13322
13323        mAppErrors.crashApplication(r, crashInfo);
13324    }
13325
13326    public void handleApplicationStrictModeViolation(
13327            IBinder app,
13328            int violationMask,
13329            StrictMode.ViolationInfo info) {
13330        ProcessRecord r = findAppProcess(app, "StrictMode");
13331        if (r == null) {
13332            return;
13333        }
13334
13335        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13336            Integer stackFingerprint = info.hashCode();
13337            boolean logIt = true;
13338            synchronized (mAlreadyLoggedViolatedStacks) {
13339                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13340                    logIt = false;
13341                    // TODO: sub-sample into EventLog for these, with
13342                    // the info.durationMillis?  Then we'd get
13343                    // the relative pain numbers, without logging all
13344                    // the stack traces repeatedly.  We'd want to do
13345                    // likewise in the client code, which also does
13346                    // dup suppression, before the Binder call.
13347                } else {
13348                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13349                        mAlreadyLoggedViolatedStacks.clear();
13350                    }
13351                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13352                }
13353            }
13354            if (logIt) {
13355                logStrictModeViolationToDropBox(r, info);
13356            }
13357        }
13358
13359        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13360            AppErrorResult result = new AppErrorResult();
13361            synchronized (this) {
13362                final long origId = Binder.clearCallingIdentity();
13363
13364                Message msg = Message.obtain();
13365                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13366                HashMap<String, Object> data = new HashMap<String, Object>();
13367                data.put("result", result);
13368                data.put("app", r);
13369                data.put("violationMask", violationMask);
13370                data.put("info", info);
13371                msg.obj = data;
13372                mUiHandler.sendMessage(msg);
13373
13374                Binder.restoreCallingIdentity(origId);
13375            }
13376            int res = result.get();
13377            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13378        }
13379    }
13380
13381    // Depending on the policy in effect, there could be a bunch of
13382    // these in quick succession so we try to batch these together to
13383    // minimize disk writes, number of dropbox entries, and maximize
13384    // compression, by having more fewer, larger records.
13385    private void logStrictModeViolationToDropBox(
13386            ProcessRecord process,
13387            StrictMode.ViolationInfo info) {
13388        if (info == null) {
13389            return;
13390        }
13391        final boolean isSystemApp = process == null ||
13392                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13393                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13394        final String processName = process == null ? "unknown" : process.processName;
13395        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13396        final DropBoxManager dbox = (DropBoxManager)
13397                mContext.getSystemService(Context.DROPBOX_SERVICE);
13398
13399        // Exit early if the dropbox isn't configured to accept this report type.
13400        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13401
13402        boolean bufferWasEmpty;
13403        boolean needsFlush;
13404        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13405        synchronized (sb) {
13406            bufferWasEmpty = sb.length() == 0;
13407            appendDropBoxProcessHeaders(process, processName, sb);
13408            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13409            sb.append("System-App: ").append(isSystemApp).append("\n");
13410            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13411            if (info.violationNumThisLoop != 0) {
13412                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13413            }
13414            if (info.numAnimationsRunning != 0) {
13415                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13416            }
13417            if (info.broadcastIntentAction != null) {
13418                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13419            }
13420            if (info.durationMillis != -1) {
13421                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13422            }
13423            if (info.numInstances != -1) {
13424                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13425            }
13426            if (info.tags != null) {
13427                for (String tag : info.tags) {
13428                    sb.append("Span-Tag: ").append(tag).append("\n");
13429                }
13430            }
13431            sb.append("\n");
13432            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13433                sb.append(info.crashInfo.stackTrace);
13434                sb.append("\n");
13435            }
13436            if (info.message != null) {
13437                sb.append(info.message);
13438                sb.append("\n");
13439            }
13440
13441            // Only buffer up to ~64k.  Various logging bits truncate
13442            // things at 128k.
13443            needsFlush = (sb.length() > 64 * 1024);
13444        }
13445
13446        // Flush immediately if the buffer's grown too large, or this
13447        // is a non-system app.  Non-system apps are isolated with a
13448        // different tag & policy and not batched.
13449        //
13450        // Batching is useful during internal testing with
13451        // StrictMode settings turned up high.  Without batching,
13452        // thousands of separate files could be created on boot.
13453        if (!isSystemApp || needsFlush) {
13454            new Thread("Error dump: " + dropboxTag) {
13455                @Override
13456                public void run() {
13457                    String report;
13458                    synchronized (sb) {
13459                        report = sb.toString();
13460                        sb.delete(0, sb.length());
13461                        sb.trimToSize();
13462                    }
13463                    if (report.length() != 0) {
13464                        dbox.addText(dropboxTag, report);
13465                    }
13466                }
13467            }.start();
13468            return;
13469        }
13470
13471        // System app batching:
13472        if (!bufferWasEmpty) {
13473            // An existing dropbox-writing thread is outstanding, so
13474            // we don't need to start it up.  The existing thread will
13475            // catch the buffer appends we just did.
13476            return;
13477        }
13478
13479        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13480        // (After this point, we shouldn't access AMS internal data structures.)
13481        new Thread("Error dump: " + dropboxTag) {
13482            @Override
13483            public void run() {
13484                // 5 second sleep to let stacks arrive and be batched together
13485                try {
13486                    Thread.sleep(5000);  // 5 seconds
13487                } catch (InterruptedException e) {}
13488
13489                String errorReport;
13490                synchronized (mStrictModeBuffer) {
13491                    errorReport = mStrictModeBuffer.toString();
13492                    if (errorReport.length() == 0) {
13493                        return;
13494                    }
13495                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13496                    mStrictModeBuffer.trimToSize();
13497                }
13498                dbox.addText(dropboxTag, errorReport);
13499            }
13500        }.start();
13501    }
13502
13503    /**
13504     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13505     * @param app object of the crashing app, null for the system server
13506     * @param tag reported by the caller
13507     * @param system whether this wtf is coming from the system
13508     * @param crashInfo describing the context of the error
13509     * @return true if the process should exit immediately (WTF is fatal)
13510     */
13511    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13512            final ApplicationErrorReport.CrashInfo crashInfo) {
13513        final int callingUid = Binder.getCallingUid();
13514        final int callingPid = Binder.getCallingPid();
13515
13516        if (system) {
13517            // If this is coming from the system, we could very well have low-level
13518            // system locks held, so we want to do this all asynchronously.  And we
13519            // never want this to become fatal, so there is that too.
13520            mHandler.post(new Runnable() {
13521                @Override public void run() {
13522                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13523                }
13524            });
13525            return false;
13526        }
13527
13528        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13529                crashInfo);
13530
13531        if (r != null && r.pid != Process.myPid() &&
13532                Settings.Global.getInt(mContext.getContentResolver(),
13533                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13534            mAppErrors.crashApplication(r, crashInfo);
13535            return true;
13536        } else {
13537            return false;
13538        }
13539    }
13540
13541    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13542            final ApplicationErrorReport.CrashInfo crashInfo) {
13543        final ProcessRecord r = findAppProcess(app, "WTF");
13544        final String processName = app == null ? "system_server"
13545                : (r == null ? "unknown" : r.processName);
13546
13547        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13548                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13549
13550        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13551
13552        return r;
13553    }
13554
13555    /**
13556     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13557     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13558     */
13559    private ProcessRecord findAppProcess(IBinder app, String reason) {
13560        if (app == null) {
13561            return null;
13562        }
13563
13564        synchronized (this) {
13565            final int NP = mProcessNames.getMap().size();
13566            for (int ip=0; ip<NP; ip++) {
13567                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13568                final int NA = apps.size();
13569                for (int ia=0; ia<NA; ia++) {
13570                    ProcessRecord p = apps.valueAt(ia);
13571                    if (p.thread != null && p.thread.asBinder() == app) {
13572                        return p;
13573                    }
13574                }
13575            }
13576
13577            Slog.w(TAG, "Can't find mystery application for " + reason
13578                    + " from pid=" + Binder.getCallingPid()
13579                    + " uid=" + Binder.getCallingUid() + ": " + app);
13580            return null;
13581        }
13582    }
13583
13584    /**
13585     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13586     * to append various headers to the dropbox log text.
13587     */
13588    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13589            StringBuilder sb) {
13590        // Watchdog thread ends up invoking this function (with
13591        // a null ProcessRecord) to add the stack file to dropbox.
13592        // Do not acquire a lock on this (am) in such cases, as it
13593        // could cause a potential deadlock, if and when watchdog
13594        // is invoked due to unavailability of lock on am and it
13595        // would prevent watchdog from killing system_server.
13596        if (process == null) {
13597            sb.append("Process: ").append(processName).append("\n");
13598            return;
13599        }
13600        // Note: ProcessRecord 'process' is guarded by the service
13601        // instance.  (notably process.pkgList, which could otherwise change
13602        // concurrently during execution of this method)
13603        synchronized (this) {
13604            sb.append("Process: ").append(processName).append("\n");
13605            int flags = process.info.flags;
13606            IPackageManager pm = AppGlobals.getPackageManager();
13607            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13608            for (int ip=0; ip<process.pkgList.size(); ip++) {
13609                String pkg = process.pkgList.keyAt(ip);
13610                sb.append("Package: ").append(pkg);
13611                try {
13612                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13613                    if (pi != null) {
13614                        sb.append(" v").append(pi.versionCode);
13615                        if (pi.versionName != null) {
13616                            sb.append(" (").append(pi.versionName).append(")");
13617                        }
13618                    }
13619                } catch (RemoteException e) {
13620                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13621                }
13622                sb.append("\n");
13623            }
13624        }
13625    }
13626
13627    private static String processClass(ProcessRecord process) {
13628        if (process == null || process.pid == MY_PID) {
13629            return "system_server";
13630        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13631            return "system_app";
13632        } else {
13633            return "data_app";
13634        }
13635    }
13636
13637    private volatile long mWtfClusterStart;
13638    private volatile int mWtfClusterCount;
13639
13640    /**
13641     * Write a description of an error (crash, WTF, ANR) to the drop box.
13642     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13643     * @param process which caused the error, null means the system server
13644     * @param activity which triggered the error, null if unknown
13645     * @param parent activity related to the error, null if unknown
13646     * @param subject line related to the error, null if absent
13647     * @param report in long form describing the error, null if absent
13648     * @param dataFile text file to include in the report, null if none
13649     * @param crashInfo giving an application stack trace, null if absent
13650     */
13651    public void addErrorToDropBox(String eventType,
13652            ProcessRecord process, String processName, ActivityRecord activity,
13653            ActivityRecord parent, String subject,
13654            final String report, final File dataFile,
13655            final ApplicationErrorReport.CrashInfo crashInfo) {
13656        // NOTE -- this must never acquire the ActivityManagerService lock,
13657        // otherwise the watchdog may be prevented from resetting the system.
13658
13659        final String dropboxTag = processClass(process) + "_" + eventType;
13660        final DropBoxManager dbox = (DropBoxManager)
13661                mContext.getSystemService(Context.DROPBOX_SERVICE);
13662
13663        // Exit early if the dropbox isn't configured to accept this report type.
13664        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13665
13666        // Rate-limit how often we're willing to do the heavy lifting below to
13667        // collect and record logs; currently 5 logs per 10 second period.
13668        final long now = SystemClock.elapsedRealtime();
13669        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13670            mWtfClusterStart = now;
13671            mWtfClusterCount = 1;
13672        } else {
13673            if (mWtfClusterCount++ >= 5) return;
13674        }
13675
13676        final StringBuilder sb = new StringBuilder(1024);
13677        appendDropBoxProcessHeaders(process, processName, sb);
13678        if (process != null) {
13679            sb.append("Foreground: ")
13680                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13681                    .append("\n");
13682        }
13683        if (activity != null) {
13684            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13685        }
13686        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13687            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13688        }
13689        if (parent != null && parent != activity) {
13690            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13691        }
13692        if (subject != null) {
13693            sb.append("Subject: ").append(subject).append("\n");
13694        }
13695        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13696        if (Debug.isDebuggerConnected()) {
13697            sb.append("Debugger: Connected\n");
13698        }
13699        sb.append("\n");
13700
13701        // Do the rest in a worker thread to avoid blocking the caller on I/O
13702        // (After this point, we shouldn't access AMS internal data structures.)
13703        Thread worker = new Thread("Error dump: " + dropboxTag) {
13704            @Override
13705            public void run() {
13706                if (report != null) {
13707                    sb.append(report);
13708                }
13709
13710                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13711                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13712                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13713                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13714
13715                if (dataFile != null && maxDataFileSize > 0) {
13716                    try {
13717                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13718                                    "\n\n[[TRUNCATED]]"));
13719                    } catch (IOException e) {
13720                        Slog.e(TAG, "Error reading " + dataFile, e);
13721                    }
13722                }
13723                if (crashInfo != null && crashInfo.stackTrace != null) {
13724                    sb.append(crashInfo.stackTrace);
13725                }
13726
13727                if (lines > 0) {
13728                    sb.append("\n");
13729
13730                    // Merge several logcat streams, and take the last N lines
13731                    InputStreamReader input = null;
13732                    try {
13733                        java.lang.Process logcat = new ProcessBuilder(
13734                                "/system/bin/timeout", "-k", "15s", "10s",
13735                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13736                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13737                                        .redirectErrorStream(true).start();
13738
13739                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13740                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13741                        input = new InputStreamReader(logcat.getInputStream());
13742
13743                        int num;
13744                        char[] buf = new char[8192];
13745                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13746                    } catch (IOException e) {
13747                        Slog.e(TAG, "Error running logcat", e);
13748                    } finally {
13749                        if (input != null) try { input.close(); } catch (IOException e) {}
13750                    }
13751                }
13752
13753                dbox.addText(dropboxTag, sb.toString());
13754            }
13755        };
13756
13757        if (process == null) {
13758            // If process is null, we are being called from some internal code
13759            // and may be about to die -- run this synchronously.
13760            worker.run();
13761        } else {
13762            worker.start();
13763        }
13764    }
13765
13766    @Override
13767    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13768        enforceNotIsolatedCaller("getProcessesInErrorState");
13769        // assume our apps are happy - lazy create the list
13770        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13771
13772        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13773                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13774        int userId = UserHandle.getUserId(Binder.getCallingUid());
13775
13776        synchronized (this) {
13777
13778            // iterate across all processes
13779            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13780                ProcessRecord app = mLruProcesses.get(i);
13781                if (!allUsers && app.userId != userId) {
13782                    continue;
13783                }
13784                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13785                    // This one's in trouble, so we'll generate a report for it
13786                    // crashes are higher priority (in case there's a crash *and* an anr)
13787                    ActivityManager.ProcessErrorStateInfo report = null;
13788                    if (app.crashing) {
13789                        report = app.crashingReport;
13790                    } else if (app.notResponding) {
13791                        report = app.notRespondingReport;
13792                    }
13793
13794                    if (report != null) {
13795                        if (errList == null) {
13796                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13797                        }
13798                        errList.add(report);
13799                    } else {
13800                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13801                                " crashing = " + app.crashing +
13802                                " notResponding = " + app.notResponding);
13803                    }
13804                }
13805            }
13806        }
13807
13808        return errList;
13809    }
13810
13811    static int procStateToImportance(int procState, int memAdj,
13812            ActivityManager.RunningAppProcessInfo currApp) {
13813        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13814        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13815            currApp.lru = memAdj;
13816        } else {
13817            currApp.lru = 0;
13818        }
13819        return imp;
13820    }
13821
13822    private void fillInProcMemInfo(ProcessRecord app,
13823            ActivityManager.RunningAppProcessInfo outInfo) {
13824        outInfo.pid = app.pid;
13825        outInfo.uid = app.info.uid;
13826        if (mHeavyWeightProcess == app) {
13827            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13828        }
13829        if (app.persistent) {
13830            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13831        }
13832        if (app.activities.size() > 0) {
13833            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13834        }
13835        outInfo.lastTrimLevel = app.trimMemoryLevel;
13836        int adj = app.curAdj;
13837        int procState = app.curProcState;
13838        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13839        outInfo.importanceReasonCode = app.adjTypeCode;
13840        outInfo.processState = app.curProcState;
13841    }
13842
13843    @Override
13844    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13845        enforceNotIsolatedCaller("getRunningAppProcesses");
13846
13847        final int callingUid = Binder.getCallingUid();
13848
13849        // Lazy instantiation of list
13850        List<ActivityManager.RunningAppProcessInfo> runList = null;
13851        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13852                callingUid) == PackageManager.PERMISSION_GRANTED;
13853        final int userId = UserHandle.getUserId(callingUid);
13854        final boolean allUids = isGetTasksAllowed(
13855                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13856
13857        synchronized (this) {
13858            // Iterate across all processes
13859            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13860                ProcessRecord app = mLruProcesses.get(i);
13861                if ((!allUsers && app.userId != userId)
13862                        || (!allUids && app.uid != callingUid)) {
13863                    continue;
13864                }
13865                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13866                    // Generate process state info for running application
13867                    ActivityManager.RunningAppProcessInfo currApp =
13868                        new ActivityManager.RunningAppProcessInfo(app.processName,
13869                                app.pid, app.getPackageList());
13870                    fillInProcMemInfo(app, currApp);
13871                    if (app.adjSource instanceof ProcessRecord) {
13872                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13873                        currApp.importanceReasonImportance =
13874                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13875                                        app.adjSourceProcState);
13876                    } else if (app.adjSource instanceof ActivityRecord) {
13877                        ActivityRecord r = (ActivityRecord)app.adjSource;
13878                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13879                    }
13880                    if (app.adjTarget instanceof ComponentName) {
13881                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13882                    }
13883                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13884                    //        + " lru=" + currApp.lru);
13885                    if (runList == null) {
13886                        runList = new ArrayList<>();
13887                    }
13888                    runList.add(currApp);
13889                }
13890            }
13891        }
13892        return runList;
13893    }
13894
13895    @Override
13896    public List<ApplicationInfo> getRunningExternalApplications() {
13897        enforceNotIsolatedCaller("getRunningExternalApplications");
13898        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13899        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13900        if (runningApps != null && runningApps.size() > 0) {
13901            Set<String> extList = new HashSet<String>();
13902            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13903                if (app.pkgList != null) {
13904                    for (String pkg : app.pkgList) {
13905                        extList.add(pkg);
13906                    }
13907                }
13908            }
13909            IPackageManager pm = AppGlobals.getPackageManager();
13910            for (String pkg : extList) {
13911                try {
13912                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13913                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13914                        retList.add(info);
13915                    }
13916                } catch (RemoteException e) {
13917                }
13918            }
13919        }
13920        return retList;
13921    }
13922
13923    @Override
13924    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13925        enforceNotIsolatedCaller("getMyMemoryState");
13926        synchronized (this) {
13927            ProcessRecord proc;
13928            synchronized (mPidsSelfLocked) {
13929                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13930            }
13931            fillInProcMemInfo(proc, outInfo);
13932        }
13933    }
13934
13935    @Override
13936    public int getMemoryTrimLevel() {
13937        enforceNotIsolatedCaller("getMyMemoryState");
13938        synchronized (this) {
13939            return mLastMemoryLevel;
13940        }
13941    }
13942
13943    @Override
13944    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13945            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13946        (new ActivityManagerShellCommand(this, false)).exec(
13947                this, in, out, err, args, resultReceiver);
13948    }
13949
13950    @Override
13951    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13952        if (checkCallingPermission(android.Manifest.permission.DUMP)
13953                != PackageManager.PERMISSION_GRANTED) {
13954            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13955                    + Binder.getCallingPid()
13956                    + ", uid=" + Binder.getCallingUid()
13957                    + " without permission "
13958                    + android.Manifest.permission.DUMP);
13959            return;
13960        }
13961
13962        boolean dumpAll = false;
13963        boolean dumpClient = false;
13964        boolean dumpCheckin = false;
13965        boolean dumpCheckinFormat = false;
13966        String dumpPackage = null;
13967
13968        int opti = 0;
13969        while (opti < args.length) {
13970            String opt = args[opti];
13971            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13972                break;
13973            }
13974            opti++;
13975            if ("-a".equals(opt)) {
13976                dumpAll = true;
13977            } else if ("-c".equals(opt)) {
13978                dumpClient = true;
13979            } else if ("-p".equals(opt)) {
13980                if (opti < args.length) {
13981                    dumpPackage = args[opti];
13982                    opti++;
13983                } else {
13984                    pw.println("Error: -p option requires package argument");
13985                    return;
13986                }
13987                dumpClient = true;
13988            } else if ("--checkin".equals(opt)) {
13989                dumpCheckin = dumpCheckinFormat = true;
13990            } else if ("-C".equals(opt)) {
13991                dumpCheckinFormat = true;
13992            } else if ("-h".equals(opt)) {
13993                ActivityManagerShellCommand.dumpHelp(pw, true);
13994                return;
13995            } else {
13996                pw.println("Unknown argument: " + opt + "; use -h for help");
13997            }
13998        }
13999
14000        long origId = Binder.clearCallingIdentity();
14001        boolean more = false;
14002        // Is the caller requesting to dump a particular piece of data?
14003        if (opti < args.length) {
14004            String cmd = args[opti];
14005            opti++;
14006            if ("activities".equals(cmd) || "a".equals(cmd)) {
14007                synchronized (this) {
14008                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14009                }
14010            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14011                synchronized (this) {
14012                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14013                }
14014            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14015                String[] newArgs;
14016                String name;
14017                if (opti >= args.length) {
14018                    name = null;
14019                    newArgs = EMPTY_STRING_ARRAY;
14020                } else {
14021                    dumpPackage = args[opti];
14022                    opti++;
14023                    newArgs = new String[args.length - opti];
14024                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14025                            args.length - opti);
14026                }
14027                synchronized (this) {
14028                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14029                }
14030            } else if ("broadcast-stats".equals(cmd)) {
14031                String[] newArgs;
14032                String name;
14033                if (opti >= args.length) {
14034                    name = null;
14035                    newArgs = EMPTY_STRING_ARRAY;
14036                } else {
14037                    dumpPackage = args[opti];
14038                    opti++;
14039                    newArgs = new String[args.length - opti];
14040                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14041                            args.length - opti);
14042                }
14043                synchronized (this) {
14044                    if (dumpCheckinFormat) {
14045                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14046                                dumpPackage);
14047                    } else {
14048                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14049                    }
14050                }
14051            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14052                String[] newArgs;
14053                String name;
14054                if (opti >= args.length) {
14055                    name = null;
14056                    newArgs = EMPTY_STRING_ARRAY;
14057                } else {
14058                    dumpPackage = args[opti];
14059                    opti++;
14060                    newArgs = new String[args.length - opti];
14061                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14062                            args.length - opti);
14063                }
14064                synchronized (this) {
14065                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14066                }
14067            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14068                String[] newArgs;
14069                String name;
14070                if (opti >= args.length) {
14071                    name = null;
14072                    newArgs = EMPTY_STRING_ARRAY;
14073                } else {
14074                    dumpPackage = args[opti];
14075                    opti++;
14076                    newArgs = new String[args.length - opti];
14077                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14078                            args.length - opti);
14079                }
14080                synchronized (this) {
14081                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14082                }
14083            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14084                synchronized (this) {
14085                    dumpOomLocked(fd, pw, args, opti, true);
14086                }
14087            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14088                synchronized (this) {
14089                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14090                }
14091            } else if ("provider".equals(cmd)) {
14092                String[] newArgs;
14093                String name;
14094                if (opti >= args.length) {
14095                    name = null;
14096                    newArgs = EMPTY_STRING_ARRAY;
14097                } else {
14098                    name = args[opti];
14099                    opti++;
14100                    newArgs = new String[args.length - opti];
14101                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14102                }
14103                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14104                    pw.println("No providers match: " + name);
14105                    pw.println("Use -h for help.");
14106                }
14107            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14108                synchronized (this) {
14109                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14110                }
14111            } else if ("service".equals(cmd)) {
14112                String[] newArgs;
14113                String name;
14114                if (opti >= args.length) {
14115                    name = null;
14116                    newArgs = EMPTY_STRING_ARRAY;
14117                } else {
14118                    name = args[opti];
14119                    opti++;
14120                    newArgs = new String[args.length - opti];
14121                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14122                            args.length - opti);
14123                }
14124                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14125                    pw.println("No services match: " + name);
14126                    pw.println("Use -h for help.");
14127                }
14128            } else if ("package".equals(cmd)) {
14129                String[] newArgs;
14130                if (opti >= args.length) {
14131                    pw.println("package: no package name specified");
14132                    pw.println("Use -h for help.");
14133                } else {
14134                    dumpPackage = args[opti];
14135                    opti++;
14136                    newArgs = new String[args.length - opti];
14137                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14138                            args.length - opti);
14139                    args = newArgs;
14140                    opti = 0;
14141                    more = true;
14142                }
14143            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14144                synchronized (this) {
14145                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14146                }
14147            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14148                if (dumpClient) {
14149                    ActiveServices.ServiceDumper dumper;
14150                    synchronized (this) {
14151                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14152                                dumpPackage);
14153                    }
14154                    dumper.dumpWithClient();
14155                } else {
14156                    synchronized (this) {
14157                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14158                                dumpPackage).dumpLocked();
14159                    }
14160                }
14161            } else if ("locks".equals(cmd)) {
14162                LockGuard.dump(fd, pw, args);
14163            } else {
14164                // Dumping a single activity?
14165                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14166                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14167                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14168                    if (res < 0) {
14169                        pw.println("Bad activity command, or no activities match: " + cmd);
14170                        pw.println("Use -h for help.");
14171                    }
14172                }
14173            }
14174            if (!more) {
14175                Binder.restoreCallingIdentity(origId);
14176                return;
14177            }
14178        }
14179
14180        // No piece of data specified, dump everything.
14181        if (dumpCheckinFormat) {
14182            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14183        } else if (dumpClient) {
14184            ActiveServices.ServiceDumper sdumper;
14185            synchronized (this) {
14186                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14187                pw.println();
14188                if (dumpAll) {
14189                    pw.println("-------------------------------------------------------------------------------");
14190                }
14191                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14192                pw.println();
14193                if (dumpAll) {
14194                    pw.println("-------------------------------------------------------------------------------");
14195                }
14196                if (dumpAll || dumpPackage != null) {
14197                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14198                    pw.println();
14199                    if (dumpAll) {
14200                        pw.println("-------------------------------------------------------------------------------");
14201                    }
14202                }
14203                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14204                pw.println();
14205                if (dumpAll) {
14206                    pw.println("-------------------------------------------------------------------------------");
14207                }
14208                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14209                pw.println();
14210                if (dumpAll) {
14211                    pw.println("-------------------------------------------------------------------------------");
14212                }
14213                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14214                        dumpPackage);
14215            }
14216            sdumper.dumpWithClient();
14217            pw.println();
14218            synchronized (this) {
14219                if (dumpAll) {
14220                    pw.println("-------------------------------------------------------------------------------");
14221                }
14222                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14223                pw.println();
14224                if (dumpAll) {
14225                    pw.println("-------------------------------------------------------------------------------");
14226                }
14227                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14228                if (mAssociations.size() > 0) {
14229                    pw.println();
14230                    if (dumpAll) {
14231                        pw.println("-------------------------------------------------------------------------------");
14232                    }
14233                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14234                }
14235                pw.println();
14236                if (dumpAll) {
14237                    pw.println("-------------------------------------------------------------------------------");
14238                }
14239                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14240            }
14241
14242        } else {
14243            synchronized (this) {
14244                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14245                pw.println();
14246                if (dumpAll) {
14247                    pw.println("-------------------------------------------------------------------------------");
14248                }
14249                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14250                pw.println();
14251                if (dumpAll) {
14252                    pw.println("-------------------------------------------------------------------------------");
14253                }
14254                if (dumpAll || dumpPackage != null) {
14255                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14256                    pw.println();
14257                    if (dumpAll) {
14258                        pw.println("-------------------------------------------------------------------------------");
14259                    }
14260                }
14261                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14262                pw.println();
14263                if (dumpAll) {
14264                    pw.println("-------------------------------------------------------------------------------");
14265                }
14266                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14267                pw.println();
14268                if (dumpAll) {
14269                    pw.println("-------------------------------------------------------------------------------");
14270                }
14271                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14272                        .dumpLocked();
14273                pw.println();
14274                if (dumpAll) {
14275                    pw.println("-------------------------------------------------------------------------------");
14276                }
14277                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14278                pw.println();
14279                if (dumpAll) {
14280                    pw.println("-------------------------------------------------------------------------------");
14281                }
14282                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14283                if (mAssociations.size() > 0) {
14284                    pw.println();
14285                    if (dumpAll) {
14286                        pw.println("-------------------------------------------------------------------------------");
14287                    }
14288                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14289                }
14290                pw.println();
14291                if (dumpAll) {
14292                    pw.println("-------------------------------------------------------------------------------");
14293                }
14294                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14295            }
14296        }
14297        Binder.restoreCallingIdentity(origId);
14298    }
14299
14300    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14301            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14302        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14303
14304        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14305                dumpPackage);
14306        boolean needSep = printedAnything;
14307
14308        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14309                dumpPackage, needSep, "  mFocusedActivity: ");
14310        if (printed) {
14311            printedAnything = true;
14312            needSep = false;
14313        }
14314
14315        if (dumpPackage == null) {
14316            if (needSep) {
14317                pw.println();
14318            }
14319            needSep = true;
14320            printedAnything = true;
14321            mStackSupervisor.dump(pw, "  ");
14322        }
14323
14324        if (!printedAnything) {
14325            pw.println("  (nothing)");
14326        }
14327    }
14328
14329    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14330            int opti, boolean dumpAll, String dumpPackage) {
14331        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14332
14333        boolean printedAnything = false;
14334
14335        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14336            boolean printedHeader = false;
14337
14338            final int N = mRecentTasks.size();
14339            for (int i=0; i<N; i++) {
14340                TaskRecord tr = mRecentTasks.get(i);
14341                if (dumpPackage != null) {
14342                    if (tr.realActivity == null ||
14343                            !dumpPackage.equals(tr.realActivity)) {
14344                        continue;
14345                    }
14346                }
14347                if (!printedHeader) {
14348                    pw.println("  Recent tasks:");
14349                    printedHeader = true;
14350                    printedAnything = true;
14351                }
14352                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14353                        pw.println(tr);
14354                if (dumpAll) {
14355                    mRecentTasks.get(i).dump(pw, "    ");
14356                }
14357            }
14358        }
14359
14360        if (!printedAnything) {
14361            pw.println("  (nothing)");
14362        }
14363    }
14364
14365    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14366            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14367        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14368
14369        int dumpUid = 0;
14370        if (dumpPackage != null) {
14371            IPackageManager pm = AppGlobals.getPackageManager();
14372            try {
14373                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14374            } catch (RemoteException e) {
14375            }
14376        }
14377
14378        boolean printedAnything = false;
14379
14380        final long now = SystemClock.uptimeMillis();
14381
14382        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14383            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14384                    = mAssociations.valueAt(i1);
14385            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14386                SparseArray<ArrayMap<String, Association>> sourceUids
14387                        = targetComponents.valueAt(i2);
14388                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14389                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14390                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14391                        Association ass = sourceProcesses.valueAt(i4);
14392                        if (dumpPackage != null) {
14393                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14394                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14395                                continue;
14396                            }
14397                        }
14398                        printedAnything = true;
14399                        pw.print("  ");
14400                        pw.print(ass.mTargetProcess);
14401                        pw.print("/");
14402                        UserHandle.formatUid(pw, ass.mTargetUid);
14403                        pw.print(" <- ");
14404                        pw.print(ass.mSourceProcess);
14405                        pw.print("/");
14406                        UserHandle.formatUid(pw, ass.mSourceUid);
14407                        pw.println();
14408                        pw.print("    via ");
14409                        pw.print(ass.mTargetComponent.flattenToShortString());
14410                        pw.println();
14411                        pw.print("    ");
14412                        long dur = ass.mTime;
14413                        if (ass.mNesting > 0) {
14414                            dur += now - ass.mStartTime;
14415                        }
14416                        TimeUtils.formatDuration(dur, pw);
14417                        pw.print(" (");
14418                        pw.print(ass.mCount);
14419                        pw.print(" times)");
14420                        pw.print("  ");
14421                        for (int i=0; i<ass.mStateTimes.length; i++) {
14422                            long amt = ass.mStateTimes[i];
14423                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14424                                amt += now - ass.mLastStateUptime;
14425                            }
14426                            if (amt != 0) {
14427                                pw.print(" ");
14428                                pw.print(ProcessList.makeProcStateString(
14429                                            i + ActivityManager.MIN_PROCESS_STATE));
14430                                pw.print("=");
14431                                TimeUtils.formatDuration(amt, pw);
14432                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14433                                    pw.print("*");
14434                                }
14435                            }
14436                        }
14437                        pw.println();
14438                        if (ass.mNesting > 0) {
14439                            pw.print("    Currently active: ");
14440                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14441                            pw.println();
14442                        }
14443                    }
14444                }
14445            }
14446
14447        }
14448
14449        if (!printedAnything) {
14450            pw.println("  (nothing)");
14451        }
14452    }
14453
14454    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14455            String header, boolean needSep) {
14456        boolean printed = false;
14457        int whichAppId = -1;
14458        if (dumpPackage != null) {
14459            try {
14460                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14461                        dumpPackage, 0);
14462                whichAppId = UserHandle.getAppId(info.uid);
14463            } catch (NameNotFoundException e) {
14464                e.printStackTrace();
14465            }
14466        }
14467        for (int i=0; i<uids.size(); i++) {
14468            UidRecord uidRec = uids.valueAt(i);
14469            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14470                continue;
14471            }
14472            if (!printed) {
14473                printed = true;
14474                if (needSep) {
14475                    pw.println();
14476                }
14477                pw.print("  ");
14478                pw.println(header);
14479                needSep = true;
14480            }
14481            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14482            pw.print(": "); pw.println(uidRec);
14483        }
14484        return printed;
14485    }
14486
14487    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14488            int opti, boolean dumpAll, String dumpPackage) {
14489        boolean needSep = false;
14490        boolean printedAnything = false;
14491        int numPers = 0;
14492
14493        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14494
14495        if (dumpAll) {
14496            final int NP = mProcessNames.getMap().size();
14497            for (int ip=0; ip<NP; ip++) {
14498                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14499                final int NA = procs.size();
14500                for (int ia=0; ia<NA; ia++) {
14501                    ProcessRecord r = procs.valueAt(ia);
14502                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14503                        continue;
14504                    }
14505                    if (!needSep) {
14506                        pw.println("  All known processes:");
14507                        needSep = true;
14508                        printedAnything = true;
14509                    }
14510                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14511                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14512                        pw.print(" "); pw.println(r);
14513                    r.dump(pw, "    ");
14514                    if (r.persistent) {
14515                        numPers++;
14516                    }
14517                }
14518            }
14519        }
14520
14521        if (mIsolatedProcesses.size() > 0) {
14522            boolean printed = false;
14523            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14524                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14525                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14526                    continue;
14527                }
14528                if (!printed) {
14529                    if (needSep) {
14530                        pw.println();
14531                    }
14532                    pw.println("  Isolated process list (sorted by uid):");
14533                    printedAnything = true;
14534                    printed = true;
14535                    needSep = true;
14536                }
14537                pw.println(String.format("%sIsolated #%2d: %s",
14538                        "    ", i, r.toString()));
14539            }
14540        }
14541
14542        if (mActiveUids.size() > 0) {
14543            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14544                printedAnything = needSep = true;
14545            }
14546        }
14547        if (mValidateUids.size() > 0) {
14548            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14549                printedAnything = needSep = true;
14550            }
14551        }
14552
14553        if (mLruProcesses.size() > 0) {
14554            if (needSep) {
14555                pw.println();
14556            }
14557            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14558                    pw.print(" total, non-act at ");
14559                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14560                    pw.print(", non-svc at ");
14561                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14562                    pw.println("):");
14563            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14564            needSep = true;
14565            printedAnything = true;
14566        }
14567
14568        if (dumpAll || dumpPackage != null) {
14569            synchronized (mPidsSelfLocked) {
14570                boolean printed = false;
14571                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14572                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14573                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14574                        continue;
14575                    }
14576                    if (!printed) {
14577                        if (needSep) pw.println();
14578                        needSep = true;
14579                        pw.println("  PID mappings:");
14580                        printed = true;
14581                        printedAnything = true;
14582                    }
14583                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14584                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14585                }
14586            }
14587        }
14588
14589        if (mForegroundProcesses.size() > 0) {
14590            synchronized (mPidsSelfLocked) {
14591                boolean printed = false;
14592                for (int i=0; i<mForegroundProcesses.size(); i++) {
14593                    ProcessRecord r = mPidsSelfLocked.get(
14594                            mForegroundProcesses.valueAt(i).pid);
14595                    if (dumpPackage != null && (r == null
14596                            || !r.pkgList.containsKey(dumpPackage))) {
14597                        continue;
14598                    }
14599                    if (!printed) {
14600                        if (needSep) pw.println();
14601                        needSep = true;
14602                        pw.println("  Foreground Processes:");
14603                        printed = true;
14604                        printedAnything = true;
14605                    }
14606                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14607                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14608                }
14609            }
14610        }
14611
14612        if (mPersistentStartingProcesses.size() > 0) {
14613            if (needSep) pw.println();
14614            needSep = true;
14615            printedAnything = true;
14616            pw.println("  Persisent processes that are starting:");
14617            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14618                    "Starting Norm", "Restarting PERS", dumpPackage);
14619        }
14620
14621        if (mRemovedProcesses.size() > 0) {
14622            if (needSep) pw.println();
14623            needSep = true;
14624            printedAnything = true;
14625            pw.println("  Processes that are being removed:");
14626            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14627                    "Removed Norm", "Removed PERS", dumpPackage);
14628        }
14629
14630        if (mProcessesOnHold.size() > 0) {
14631            if (needSep) pw.println();
14632            needSep = true;
14633            printedAnything = true;
14634            pw.println("  Processes that are on old until the system is ready:");
14635            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14636                    "OnHold Norm", "OnHold PERS", dumpPackage);
14637        }
14638
14639        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14640
14641        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14642        if (needSep) {
14643            printedAnything = true;
14644        }
14645
14646        if (dumpPackage == null) {
14647            pw.println();
14648            needSep = false;
14649            mUserController.dump(pw, dumpAll);
14650        }
14651        if (mHomeProcess != null && (dumpPackage == null
14652                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14653            if (needSep) {
14654                pw.println();
14655                needSep = false;
14656            }
14657            pw.println("  mHomeProcess: " + mHomeProcess);
14658        }
14659        if (mPreviousProcess != null && (dumpPackage == null
14660                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14661            if (needSep) {
14662                pw.println();
14663                needSep = false;
14664            }
14665            pw.println("  mPreviousProcess: " + mPreviousProcess);
14666        }
14667        if (dumpAll) {
14668            StringBuilder sb = new StringBuilder(128);
14669            sb.append("  mPreviousProcessVisibleTime: ");
14670            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14671            pw.println(sb);
14672        }
14673        if (mHeavyWeightProcess != null && (dumpPackage == null
14674                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14675            if (needSep) {
14676                pw.println();
14677                needSep = false;
14678            }
14679            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14680        }
14681        if (dumpPackage == null) {
14682            pw.println("  mConfiguration: " + mConfiguration);
14683        }
14684        if (dumpAll) {
14685            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14686            if (mCompatModePackages.getPackages().size() > 0) {
14687                boolean printed = false;
14688                for (Map.Entry<String, Integer> entry
14689                        : mCompatModePackages.getPackages().entrySet()) {
14690                    String pkg = entry.getKey();
14691                    int mode = entry.getValue();
14692                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14693                        continue;
14694                    }
14695                    if (!printed) {
14696                        pw.println("  mScreenCompatPackages:");
14697                        printed = true;
14698                    }
14699                    pw.print("    "); pw.print(pkg); pw.print(": ");
14700                            pw.print(mode); pw.println();
14701                }
14702            }
14703        }
14704        if (dumpPackage == null) {
14705            pw.println("  mWakefulness="
14706                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14707            pw.println("  mSleepTokens=" + mSleepTokens);
14708            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14709                    + lockScreenShownToString());
14710            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14711            if (mRunningVoice != null) {
14712                pw.println("  mRunningVoice=" + mRunningVoice);
14713                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14714            }
14715        }
14716        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14717                || mOrigWaitForDebugger) {
14718            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14719                    || dumpPackage.equals(mOrigDebugApp)) {
14720                if (needSep) {
14721                    pw.println();
14722                    needSep = false;
14723                }
14724                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14725                        + " mDebugTransient=" + mDebugTransient
14726                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14727            }
14728        }
14729        if (mCurAppTimeTracker != null) {
14730            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14731        }
14732        if (mMemWatchProcesses.getMap().size() > 0) {
14733            pw.println("  Mem watch processes:");
14734            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14735                    = mMemWatchProcesses.getMap();
14736            for (int i=0; i<procs.size(); i++) {
14737                final String proc = procs.keyAt(i);
14738                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14739                for (int j=0; j<uids.size(); j++) {
14740                    if (needSep) {
14741                        pw.println();
14742                        needSep = false;
14743                    }
14744                    StringBuilder sb = new StringBuilder();
14745                    sb.append("    ").append(proc).append('/');
14746                    UserHandle.formatUid(sb, uids.keyAt(j));
14747                    Pair<Long, String> val = uids.valueAt(j);
14748                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14749                    if (val.second != null) {
14750                        sb.append(", report to ").append(val.second);
14751                    }
14752                    pw.println(sb.toString());
14753                }
14754            }
14755            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14756            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14757            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14758                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14759        }
14760        if (mTrackAllocationApp != null) {
14761            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14762                if (needSep) {
14763                    pw.println();
14764                    needSep = false;
14765                }
14766                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14767            }
14768        }
14769        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14770                || mProfileFd != null) {
14771            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14772                if (needSep) {
14773                    pw.println();
14774                    needSep = false;
14775                }
14776                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14777                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14778                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14779                        + mAutoStopProfiler);
14780                pw.println("  mProfileType=" + mProfileType);
14781            }
14782        }
14783        if (mNativeDebuggingApp != null) {
14784            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14785                if (needSep) {
14786                    pw.println();
14787                    needSep = false;
14788                }
14789                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14790            }
14791        }
14792        if (dumpPackage == null) {
14793            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14794                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14795                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14796            }
14797            if (mController != null) {
14798                pw.println("  mController=" + mController
14799                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14800            }
14801            if (dumpAll) {
14802                pw.println("  Total persistent processes: " + numPers);
14803                pw.println("  mProcessesReady=" + mProcessesReady
14804                        + " mSystemReady=" + mSystemReady
14805                        + " mBooted=" + mBooted
14806                        + " mFactoryTest=" + mFactoryTest);
14807                pw.println("  mBooting=" + mBooting
14808                        + " mCallFinishBooting=" + mCallFinishBooting
14809                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14810                pw.print("  mLastPowerCheckRealtime=");
14811                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14812                        pw.println("");
14813                pw.print("  mLastPowerCheckUptime=");
14814                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14815                        pw.println("");
14816                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14817                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14818                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14819                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14820                        + " (" + mLruProcesses.size() + " total)"
14821                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14822                        + " mNumServiceProcs=" + mNumServiceProcs
14823                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14824                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14825                        + " mLastMemoryLevel=" + mLastMemoryLevel
14826                        + " mLastNumProcesses=" + mLastNumProcesses);
14827                long now = SystemClock.uptimeMillis();
14828                pw.print("  mLastIdleTime=");
14829                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14830                        pw.print(" mLowRamSinceLastIdle=");
14831                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14832                        pw.println();
14833            }
14834        }
14835
14836        if (!printedAnything) {
14837            pw.println("  (nothing)");
14838        }
14839    }
14840
14841    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14842            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14843        if (mProcessesToGc.size() > 0) {
14844            boolean printed = false;
14845            long now = SystemClock.uptimeMillis();
14846            for (int i=0; i<mProcessesToGc.size(); i++) {
14847                ProcessRecord proc = mProcessesToGc.get(i);
14848                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14849                    continue;
14850                }
14851                if (!printed) {
14852                    if (needSep) pw.println();
14853                    needSep = true;
14854                    pw.println("  Processes that are waiting to GC:");
14855                    printed = true;
14856                }
14857                pw.print("    Process "); pw.println(proc);
14858                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14859                        pw.print(", last gced=");
14860                        pw.print(now-proc.lastRequestedGc);
14861                        pw.print(" ms ago, last lowMem=");
14862                        pw.print(now-proc.lastLowMemory);
14863                        pw.println(" ms ago");
14864
14865            }
14866        }
14867        return needSep;
14868    }
14869
14870    void printOomLevel(PrintWriter pw, String name, int adj) {
14871        pw.print("    ");
14872        if (adj >= 0) {
14873            pw.print(' ');
14874            if (adj < 10) pw.print(' ');
14875        } else {
14876            if (adj > -10) pw.print(' ');
14877        }
14878        pw.print(adj);
14879        pw.print(": ");
14880        pw.print(name);
14881        pw.print(" (");
14882        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14883        pw.println(")");
14884    }
14885
14886    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14887            int opti, boolean dumpAll) {
14888        boolean needSep = false;
14889
14890        if (mLruProcesses.size() > 0) {
14891            if (needSep) pw.println();
14892            needSep = true;
14893            pw.println("  OOM levels:");
14894            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14895            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14896            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14897            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14898            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14899            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14900            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14901            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14902            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14903            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14904            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14905            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14906            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14907            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14908
14909            if (needSep) pw.println();
14910            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14911                    pw.print(" total, non-act at ");
14912                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14913                    pw.print(", non-svc at ");
14914                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14915                    pw.println("):");
14916            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14917            needSep = true;
14918        }
14919
14920        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14921
14922        pw.println();
14923        pw.println("  mHomeProcess: " + mHomeProcess);
14924        pw.println("  mPreviousProcess: " + mPreviousProcess);
14925        if (mHeavyWeightProcess != null) {
14926            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14927        }
14928
14929        return true;
14930    }
14931
14932    /**
14933     * There are three ways to call this:
14934     *  - no provider specified: dump all the providers
14935     *  - a flattened component name that matched an existing provider was specified as the
14936     *    first arg: dump that one provider
14937     *  - the first arg isn't the flattened component name of an existing provider:
14938     *    dump all providers whose component contains the first arg as a substring
14939     */
14940    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14941            int opti, boolean dumpAll) {
14942        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14943    }
14944
14945    static class ItemMatcher {
14946        ArrayList<ComponentName> components;
14947        ArrayList<String> strings;
14948        ArrayList<Integer> objects;
14949        boolean all;
14950
14951        ItemMatcher() {
14952            all = true;
14953        }
14954
14955        void build(String name) {
14956            ComponentName componentName = ComponentName.unflattenFromString(name);
14957            if (componentName != null) {
14958                if (components == null) {
14959                    components = new ArrayList<ComponentName>();
14960                }
14961                components.add(componentName);
14962                all = false;
14963            } else {
14964                int objectId = 0;
14965                // Not a '/' separated full component name; maybe an object ID?
14966                try {
14967                    objectId = Integer.parseInt(name, 16);
14968                    if (objects == null) {
14969                        objects = new ArrayList<Integer>();
14970                    }
14971                    objects.add(objectId);
14972                    all = false;
14973                } catch (RuntimeException e) {
14974                    // Not an integer; just do string match.
14975                    if (strings == null) {
14976                        strings = new ArrayList<String>();
14977                    }
14978                    strings.add(name);
14979                    all = false;
14980                }
14981            }
14982        }
14983
14984        int build(String[] args, int opti) {
14985            for (; opti<args.length; opti++) {
14986                String name = args[opti];
14987                if ("--".equals(name)) {
14988                    return opti+1;
14989                }
14990                build(name);
14991            }
14992            return opti;
14993        }
14994
14995        boolean match(Object object, ComponentName comp) {
14996            if (all) {
14997                return true;
14998            }
14999            if (components != null) {
15000                for (int i=0; i<components.size(); i++) {
15001                    if (components.get(i).equals(comp)) {
15002                        return true;
15003                    }
15004                }
15005            }
15006            if (objects != null) {
15007                for (int i=0; i<objects.size(); i++) {
15008                    if (System.identityHashCode(object) == objects.get(i)) {
15009                        return true;
15010                    }
15011                }
15012            }
15013            if (strings != null) {
15014                String flat = comp.flattenToString();
15015                for (int i=0; i<strings.size(); i++) {
15016                    if (flat.contains(strings.get(i))) {
15017                        return true;
15018                    }
15019                }
15020            }
15021            return false;
15022        }
15023    }
15024
15025    /**
15026     * There are three things that cmd can be:
15027     *  - a flattened component name that matches an existing activity
15028     *  - the cmd arg isn't the flattened component name of an existing activity:
15029     *    dump all activity whose component contains the cmd as a substring
15030     *  - A hex number of the ActivityRecord object instance.
15031     */
15032    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15033            int opti, boolean dumpAll) {
15034        ArrayList<ActivityRecord> activities;
15035
15036        synchronized (this) {
15037            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15038        }
15039
15040        if (activities.size() <= 0) {
15041            return false;
15042        }
15043
15044        String[] newArgs = new String[args.length - opti];
15045        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15046
15047        TaskRecord lastTask = null;
15048        boolean needSep = false;
15049        for (int i=activities.size()-1; i>=0; i--) {
15050            ActivityRecord r = activities.get(i);
15051            if (needSep) {
15052                pw.println();
15053            }
15054            needSep = true;
15055            synchronized (this) {
15056                if (lastTask != r.task) {
15057                    lastTask = r.task;
15058                    pw.print("TASK "); pw.print(lastTask.affinity);
15059                            pw.print(" id="); pw.println(lastTask.taskId);
15060                    if (dumpAll) {
15061                        lastTask.dump(pw, "  ");
15062                    }
15063                }
15064            }
15065            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15066        }
15067        return true;
15068    }
15069
15070    /**
15071     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15072     * there is a thread associated with the activity.
15073     */
15074    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15075            final ActivityRecord r, String[] args, boolean dumpAll) {
15076        String innerPrefix = prefix + "  ";
15077        synchronized (this) {
15078            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15079                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15080                    pw.print(" pid=");
15081                    if (r.app != null) pw.println(r.app.pid);
15082                    else pw.println("(not running)");
15083            if (dumpAll) {
15084                r.dump(pw, innerPrefix);
15085            }
15086        }
15087        if (r.app != null && r.app.thread != null) {
15088            // flush anything that is already in the PrintWriter since the thread is going
15089            // to write to the file descriptor directly
15090            pw.flush();
15091            try {
15092                TransferPipe tp = new TransferPipe();
15093                try {
15094                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15095                            r.appToken, innerPrefix, args);
15096                    tp.go(fd);
15097                } finally {
15098                    tp.kill();
15099                }
15100            } catch (IOException e) {
15101                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15102            } catch (RemoteException e) {
15103                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15104            }
15105        }
15106    }
15107
15108    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15109            int opti, boolean dumpAll, String dumpPackage) {
15110        boolean needSep = false;
15111        boolean onlyHistory = false;
15112        boolean printedAnything = false;
15113
15114        if ("history".equals(dumpPackage)) {
15115            if (opti < args.length && "-s".equals(args[opti])) {
15116                dumpAll = false;
15117            }
15118            onlyHistory = true;
15119            dumpPackage = null;
15120        }
15121
15122        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15123        if (!onlyHistory && dumpAll) {
15124            if (mRegisteredReceivers.size() > 0) {
15125                boolean printed = false;
15126                Iterator it = mRegisteredReceivers.values().iterator();
15127                while (it.hasNext()) {
15128                    ReceiverList r = (ReceiverList)it.next();
15129                    if (dumpPackage != null && (r.app == null ||
15130                            !dumpPackage.equals(r.app.info.packageName))) {
15131                        continue;
15132                    }
15133                    if (!printed) {
15134                        pw.println("  Registered Receivers:");
15135                        needSep = true;
15136                        printed = true;
15137                        printedAnything = true;
15138                    }
15139                    pw.print("  * "); pw.println(r);
15140                    r.dump(pw, "    ");
15141                }
15142            }
15143
15144            if (mReceiverResolver.dump(pw, needSep ?
15145                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15146                    "    ", dumpPackage, false, false)) {
15147                needSep = true;
15148                printedAnything = true;
15149            }
15150        }
15151
15152        for (BroadcastQueue q : mBroadcastQueues) {
15153            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15154            printedAnything |= needSep;
15155        }
15156
15157        needSep = true;
15158
15159        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15160            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15161                if (needSep) {
15162                    pw.println();
15163                }
15164                needSep = true;
15165                printedAnything = true;
15166                pw.print("  Sticky broadcasts for user ");
15167                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15168                StringBuilder sb = new StringBuilder(128);
15169                for (Map.Entry<String, ArrayList<Intent>> ent
15170                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15171                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15172                    if (dumpAll) {
15173                        pw.println(":");
15174                        ArrayList<Intent> intents = ent.getValue();
15175                        final int N = intents.size();
15176                        for (int i=0; i<N; i++) {
15177                            sb.setLength(0);
15178                            sb.append("    Intent: ");
15179                            intents.get(i).toShortString(sb, false, true, false, false);
15180                            pw.println(sb.toString());
15181                            Bundle bundle = intents.get(i).getExtras();
15182                            if (bundle != null) {
15183                                pw.print("      ");
15184                                pw.println(bundle.toString());
15185                            }
15186                        }
15187                    } else {
15188                        pw.println("");
15189                    }
15190                }
15191            }
15192        }
15193
15194        if (!onlyHistory && dumpAll) {
15195            pw.println();
15196            for (BroadcastQueue queue : mBroadcastQueues) {
15197                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15198                        + queue.mBroadcastsScheduled);
15199            }
15200            pw.println("  mHandler:");
15201            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15202            needSep = true;
15203            printedAnything = true;
15204        }
15205
15206        if (!printedAnything) {
15207            pw.println("  (nothing)");
15208        }
15209    }
15210
15211    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15212            int opti, boolean dumpAll, String dumpPackage) {
15213        if (mCurBroadcastStats == null) {
15214            return;
15215        }
15216
15217        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15218        final long now = SystemClock.elapsedRealtime();
15219        if (mLastBroadcastStats != null) {
15220            pw.print("  Last stats (from ");
15221            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15222            pw.print(" to ");
15223            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15224            pw.print(", ");
15225            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15226                    - mLastBroadcastStats.mStartUptime, pw);
15227            pw.println(" uptime):");
15228            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15229                pw.println("    (nothing)");
15230            }
15231            pw.println();
15232        }
15233        pw.print("  Current stats (from ");
15234        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15235        pw.print(" to now, ");
15236        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15237                - mCurBroadcastStats.mStartUptime, pw);
15238        pw.println(" uptime):");
15239        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15240            pw.println("    (nothing)");
15241        }
15242    }
15243
15244    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15245            int opti, boolean fullCheckin, String dumpPackage) {
15246        if (mCurBroadcastStats == null) {
15247            return;
15248        }
15249
15250        if (mLastBroadcastStats != null) {
15251            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15252            if (fullCheckin) {
15253                mLastBroadcastStats = null;
15254                return;
15255            }
15256        }
15257        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15258        if (fullCheckin) {
15259            mCurBroadcastStats = null;
15260        }
15261    }
15262
15263    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15264            int opti, boolean dumpAll, String dumpPackage) {
15265        boolean needSep;
15266        boolean printedAnything = false;
15267
15268        ItemMatcher matcher = new ItemMatcher();
15269        matcher.build(args, opti);
15270
15271        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15272
15273        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15274        printedAnything |= needSep;
15275
15276        if (mLaunchingProviders.size() > 0) {
15277            boolean printed = false;
15278            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15279                ContentProviderRecord r = mLaunchingProviders.get(i);
15280                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15281                    continue;
15282                }
15283                if (!printed) {
15284                    if (needSep) pw.println();
15285                    needSep = true;
15286                    pw.println("  Launching content providers:");
15287                    printed = true;
15288                    printedAnything = true;
15289                }
15290                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15291                        pw.println(r);
15292            }
15293        }
15294
15295        if (!printedAnything) {
15296            pw.println("  (nothing)");
15297        }
15298    }
15299
15300    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15301            int opti, boolean dumpAll, String dumpPackage) {
15302        boolean needSep = false;
15303        boolean printedAnything = false;
15304
15305        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15306
15307        if (mGrantedUriPermissions.size() > 0) {
15308            boolean printed = false;
15309            int dumpUid = -2;
15310            if (dumpPackage != null) {
15311                try {
15312                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15313                            MATCH_UNINSTALLED_PACKAGES, 0);
15314                } catch (NameNotFoundException e) {
15315                    dumpUid = -1;
15316                }
15317            }
15318            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15319                int uid = mGrantedUriPermissions.keyAt(i);
15320                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15321                    continue;
15322                }
15323                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15324                if (!printed) {
15325                    if (needSep) pw.println();
15326                    needSep = true;
15327                    pw.println("  Granted Uri Permissions:");
15328                    printed = true;
15329                    printedAnything = true;
15330                }
15331                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15332                for (UriPermission perm : perms.values()) {
15333                    pw.print("    "); pw.println(perm);
15334                    if (dumpAll) {
15335                        perm.dump(pw, "      ");
15336                    }
15337                }
15338            }
15339        }
15340
15341        if (!printedAnything) {
15342            pw.println("  (nothing)");
15343        }
15344    }
15345
15346    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15347            int opti, boolean dumpAll, String dumpPackage) {
15348        boolean printed = false;
15349
15350        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15351
15352        if (mIntentSenderRecords.size() > 0) {
15353            Iterator<WeakReference<PendingIntentRecord>> it
15354                    = mIntentSenderRecords.values().iterator();
15355            while (it.hasNext()) {
15356                WeakReference<PendingIntentRecord> ref = it.next();
15357                PendingIntentRecord rec = ref != null ? ref.get(): null;
15358                if (dumpPackage != null && (rec == null
15359                        || !dumpPackage.equals(rec.key.packageName))) {
15360                    continue;
15361                }
15362                printed = true;
15363                if (rec != null) {
15364                    pw.print("  * "); pw.println(rec);
15365                    if (dumpAll) {
15366                        rec.dump(pw, "    ");
15367                    }
15368                } else {
15369                    pw.print("  * "); pw.println(ref);
15370                }
15371            }
15372        }
15373
15374        if (!printed) {
15375            pw.println("  (nothing)");
15376        }
15377    }
15378
15379    private static final int dumpProcessList(PrintWriter pw,
15380            ActivityManagerService service, List list,
15381            String prefix, String normalLabel, String persistentLabel,
15382            String dumpPackage) {
15383        int numPers = 0;
15384        final int N = list.size()-1;
15385        for (int i=N; i>=0; i--) {
15386            ProcessRecord r = (ProcessRecord)list.get(i);
15387            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15388                continue;
15389            }
15390            pw.println(String.format("%s%s #%2d: %s",
15391                    prefix, (r.persistent ? persistentLabel : normalLabel),
15392                    i, r.toString()));
15393            if (r.persistent) {
15394                numPers++;
15395            }
15396        }
15397        return numPers;
15398    }
15399
15400    private static final boolean dumpProcessOomList(PrintWriter pw,
15401            ActivityManagerService service, List<ProcessRecord> origList,
15402            String prefix, String normalLabel, String persistentLabel,
15403            boolean inclDetails, String dumpPackage) {
15404
15405        ArrayList<Pair<ProcessRecord, Integer>> list
15406                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15407        for (int i=0; i<origList.size(); i++) {
15408            ProcessRecord r = origList.get(i);
15409            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15410                continue;
15411            }
15412            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15413        }
15414
15415        if (list.size() <= 0) {
15416            return false;
15417        }
15418
15419        Comparator<Pair<ProcessRecord, Integer>> comparator
15420                = new Comparator<Pair<ProcessRecord, Integer>>() {
15421            @Override
15422            public int compare(Pair<ProcessRecord, Integer> object1,
15423                    Pair<ProcessRecord, Integer> object2) {
15424                if (object1.first.setAdj != object2.first.setAdj) {
15425                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15426                }
15427                if (object1.first.setProcState != object2.first.setProcState) {
15428                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15429                }
15430                if (object1.second.intValue() != object2.second.intValue()) {
15431                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15432                }
15433                return 0;
15434            }
15435        };
15436
15437        Collections.sort(list, comparator);
15438
15439        final long curRealtime = SystemClock.elapsedRealtime();
15440        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15441        final long curUptime = SystemClock.uptimeMillis();
15442        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15443
15444        for (int i=list.size()-1; i>=0; i--) {
15445            ProcessRecord r = list.get(i).first;
15446            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15447            char schedGroup;
15448            switch (r.setSchedGroup) {
15449                case ProcessList.SCHED_GROUP_BACKGROUND:
15450                    schedGroup = 'B';
15451                    break;
15452                case ProcessList.SCHED_GROUP_DEFAULT:
15453                    schedGroup = 'F';
15454                    break;
15455                case ProcessList.SCHED_GROUP_TOP_APP:
15456                    schedGroup = 'T';
15457                    break;
15458                default:
15459                    schedGroup = '?';
15460                    break;
15461            }
15462            char foreground;
15463            if (r.foregroundActivities) {
15464                foreground = 'A';
15465            } else if (r.foregroundServices) {
15466                foreground = 'S';
15467            } else {
15468                foreground = ' ';
15469            }
15470            String procState = ProcessList.makeProcStateString(r.curProcState);
15471            pw.print(prefix);
15472            pw.print(r.persistent ? persistentLabel : normalLabel);
15473            pw.print(" #");
15474            int num = (origList.size()-1)-list.get(i).second;
15475            if (num < 10) pw.print(' ');
15476            pw.print(num);
15477            pw.print(": ");
15478            pw.print(oomAdj);
15479            pw.print(' ');
15480            pw.print(schedGroup);
15481            pw.print('/');
15482            pw.print(foreground);
15483            pw.print('/');
15484            pw.print(procState);
15485            pw.print(" trm:");
15486            if (r.trimMemoryLevel < 10) pw.print(' ');
15487            pw.print(r.trimMemoryLevel);
15488            pw.print(' ');
15489            pw.print(r.toShortString());
15490            pw.print(" (");
15491            pw.print(r.adjType);
15492            pw.println(')');
15493            if (r.adjSource != null || r.adjTarget != null) {
15494                pw.print(prefix);
15495                pw.print("    ");
15496                if (r.adjTarget instanceof ComponentName) {
15497                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15498                } else if (r.adjTarget != null) {
15499                    pw.print(r.adjTarget.toString());
15500                } else {
15501                    pw.print("{null}");
15502                }
15503                pw.print("<=");
15504                if (r.adjSource instanceof ProcessRecord) {
15505                    pw.print("Proc{");
15506                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15507                    pw.println("}");
15508                } else if (r.adjSource != null) {
15509                    pw.println(r.adjSource.toString());
15510                } else {
15511                    pw.println("{null}");
15512                }
15513            }
15514            if (inclDetails) {
15515                pw.print(prefix);
15516                pw.print("    ");
15517                pw.print("oom: max="); pw.print(r.maxAdj);
15518                pw.print(" curRaw="); pw.print(r.curRawAdj);
15519                pw.print(" setRaw="); pw.print(r.setRawAdj);
15520                pw.print(" cur="); pw.print(r.curAdj);
15521                pw.print(" set="); pw.println(r.setAdj);
15522                pw.print(prefix);
15523                pw.print("    ");
15524                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15525                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15526                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15527                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15528                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15529                pw.println();
15530                pw.print(prefix);
15531                pw.print("    ");
15532                pw.print("cached="); pw.print(r.cached);
15533                pw.print(" empty="); pw.print(r.empty);
15534                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15535
15536                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15537                    if (r.lastWakeTime != 0) {
15538                        long wtime;
15539                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15540                        synchronized (stats) {
15541                            wtime = stats.getProcessWakeTime(r.info.uid,
15542                                    r.pid, curRealtime);
15543                        }
15544                        long timeUsed = wtime - r.lastWakeTime;
15545                        pw.print(prefix);
15546                        pw.print("    ");
15547                        pw.print("keep awake over ");
15548                        TimeUtils.formatDuration(realtimeSince, pw);
15549                        pw.print(" used ");
15550                        TimeUtils.formatDuration(timeUsed, pw);
15551                        pw.print(" (");
15552                        pw.print((timeUsed*100)/realtimeSince);
15553                        pw.println("%)");
15554                    }
15555                    if (r.lastCpuTime != 0) {
15556                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15557                        pw.print(prefix);
15558                        pw.print("    ");
15559                        pw.print("run cpu over ");
15560                        TimeUtils.formatDuration(uptimeSince, pw);
15561                        pw.print(" used ");
15562                        TimeUtils.formatDuration(timeUsed, pw);
15563                        pw.print(" (");
15564                        pw.print((timeUsed*100)/uptimeSince);
15565                        pw.println("%)");
15566                    }
15567                }
15568            }
15569        }
15570        return true;
15571    }
15572
15573    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15574            String[] args) {
15575        ArrayList<ProcessRecord> procs;
15576        synchronized (this) {
15577            if (args != null && args.length > start
15578                    && args[start].charAt(0) != '-') {
15579                procs = new ArrayList<ProcessRecord>();
15580                int pid = -1;
15581                try {
15582                    pid = Integer.parseInt(args[start]);
15583                } catch (NumberFormatException e) {
15584                }
15585                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15586                    ProcessRecord proc = mLruProcesses.get(i);
15587                    if (proc.pid == pid) {
15588                        procs.add(proc);
15589                    } else if (allPkgs && proc.pkgList != null
15590                            && proc.pkgList.containsKey(args[start])) {
15591                        procs.add(proc);
15592                    } else if (proc.processName.equals(args[start])) {
15593                        procs.add(proc);
15594                    }
15595                }
15596                if (procs.size() <= 0) {
15597                    return null;
15598                }
15599            } else {
15600                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15601            }
15602        }
15603        return procs;
15604    }
15605
15606    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15607            PrintWriter pw, String[] args) {
15608        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15609        if (procs == null) {
15610            pw.println("No process found for: " + args[0]);
15611            return;
15612        }
15613
15614        long uptime = SystemClock.uptimeMillis();
15615        long realtime = SystemClock.elapsedRealtime();
15616        pw.println("Applications Graphics Acceleration Info:");
15617        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15618
15619        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15620            ProcessRecord r = procs.get(i);
15621            if (r.thread != null) {
15622                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15623                pw.flush();
15624                try {
15625                    TransferPipe tp = new TransferPipe();
15626                    try {
15627                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15628                        tp.go(fd);
15629                    } finally {
15630                        tp.kill();
15631                    }
15632                } catch (IOException e) {
15633                    pw.println("Failure while dumping the app: " + r);
15634                    pw.flush();
15635                } catch (RemoteException e) {
15636                    pw.println("Got a RemoteException while dumping the app " + r);
15637                    pw.flush();
15638                }
15639            }
15640        }
15641    }
15642
15643    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15644        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15645        if (procs == null) {
15646            pw.println("No process found for: " + args[0]);
15647            return;
15648        }
15649
15650        pw.println("Applications Database Info:");
15651
15652        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15653            ProcessRecord r = procs.get(i);
15654            if (r.thread != null) {
15655                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15656                pw.flush();
15657                try {
15658                    TransferPipe tp = new TransferPipe();
15659                    try {
15660                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15661                        tp.go(fd);
15662                    } finally {
15663                        tp.kill();
15664                    }
15665                } catch (IOException e) {
15666                    pw.println("Failure while dumping the app: " + r);
15667                    pw.flush();
15668                } catch (RemoteException e) {
15669                    pw.println("Got a RemoteException while dumping the app " + r);
15670                    pw.flush();
15671                }
15672            }
15673        }
15674    }
15675
15676    final static class MemItem {
15677        final boolean isProc;
15678        final String label;
15679        final String shortLabel;
15680        final long pss;
15681        final long swapPss;
15682        final int id;
15683        final boolean hasActivities;
15684        ArrayList<MemItem> subitems;
15685
15686        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15687                boolean _hasActivities) {
15688            isProc = true;
15689            label = _label;
15690            shortLabel = _shortLabel;
15691            pss = _pss;
15692            swapPss = _swapPss;
15693            id = _id;
15694            hasActivities = _hasActivities;
15695        }
15696
15697        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15698            isProc = false;
15699            label = _label;
15700            shortLabel = _shortLabel;
15701            pss = _pss;
15702            swapPss = _swapPss;
15703            id = _id;
15704            hasActivities = false;
15705        }
15706    }
15707
15708    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15709            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15710        if (sort && !isCompact) {
15711            Collections.sort(items, new Comparator<MemItem>() {
15712                @Override
15713                public int compare(MemItem lhs, MemItem rhs) {
15714                    if (lhs.pss < rhs.pss) {
15715                        return 1;
15716                    } else if (lhs.pss > rhs.pss) {
15717                        return -1;
15718                    }
15719                    return 0;
15720                }
15721            });
15722        }
15723
15724        for (int i=0; i<items.size(); i++) {
15725            MemItem mi = items.get(i);
15726            if (!isCompact) {
15727                if (dumpSwapPss) {
15728                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15729                            mi.label, stringifyKBSize(mi.swapPss));
15730                } else {
15731                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15732                }
15733            } else if (mi.isProc) {
15734                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15735                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15736                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15737                pw.println(mi.hasActivities ? ",a" : ",e");
15738            } else {
15739                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15740                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15741            }
15742            if (mi.subitems != null) {
15743                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15744                        true, isCompact, dumpSwapPss);
15745            }
15746        }
15747    }
15748
15749    // These are in KB.
15750    static final long[] DUMP_MEM_BUCKETS = new long[] {
15751        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15752        120*1024, 160*1024, 200*1024,
15753        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15754        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15755    };
15756
15757    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15758            boolean stackLike) {
15759        int start = label.lastIndexOf('.');
15760        if (start >= 0) start++;
15761        else start = 0;
15762        int end = label.length();
15763        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15764            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15765                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15766                out.append(bucket);
15767                out.append(stackLike ? "MB." : "MB ");
15768                out.append(label, start, end);
15769                return;
15770            }
15771        }
15772        out.append(memKB/1024);
15773        out.append(stackLike ? "MB." : "MB ");
15774        out.append(label, start, end);
15775    }
15776
15777    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15778            ProcessList.NATIVE_ADJ,
15779            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15780            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15781            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15782            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15783            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15784            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15785    };
15786    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15787            "Native",
15788            "System", "Persistent", "Persistent Service", "Foreground",
15789            "Visible", "Perceptible",
15790            "Heavy Weight", "Backup",
15791            "A Services", "Home",
15792            "Previous", "B Services", "Cached"
15793    };
15794    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15795            "native",
15796            "sys", "pers", "persvc", "fore",
15797            "vis", "percept",
15798            "heavy", "backup",
15799            "servicea", "home",
15800            "prev", "serviceb", "cached"
15801    };
15802
15803    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15804            long realtime, boolean isCheckinRequest, boolean isCompact) {
15805        if (isCompact) {
15806            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15807        }
15808        if (isCheckinRequest || isCompact) {
15809            // short checkin version
15810            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15811        } else {
15812            pw.println("Applications Memory Usage (in Kilobytes):");
15813            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15814        }
15815    }
15816
15817    private static final int KSM_SHARED = 0;
15818    private static final int KSM_SHARING = 1;
15819    private static final int KSM_UNSHARED = 2;
15820    private static final int KSM_VOLATILE = 3;
15821
15822    private final long[] getKsmInfo() {
15823        long[] longOut = new long[4];
15824        final int[] SINGLE_LONG_FORMAT = new int[] {
15825            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15826        };
15827        long[] longTmp = new long[1];
15828        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15829                SINGLE_LONG_FORMAT, null, longTmp, null);
15830        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15831        longTmp[0] = 0;
15832        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15833                SINGLE_LONG_FORMAT, null, longTmp, null);
15834        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15835        longTmp[0] = 0;
15836        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15837                SINGLE_LONG_FORMAT, null, longTmp, null);
15838        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15839        longTmp[0] = 0;
15840        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15841                SINGLE_LONG_FORMAT, null, longTmp, null);
15842        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15843        return longOut;
15844    }
15845
15846    private static String stringifySize(long size, int order) {
15847        Locale locale = Locale.US;
15848        switch (order) {
15849            case 1:
15850                return String.format(locale, "%,13d", size);
15851            case 1024:
15852                return String.format(locale, "%,9dK", size / 1024);
15853            case 1024 * 1024:
15854                return String.format(locale, "%,5dM", size / 1024 / 1024);
15855            case 1024 * 1024 * 1024:
15856                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15857            default:
15858                throw new IllegalArgumentException("Invalid size order");
15859        }
15860    }
15861
15862    private static String stringifyKBSize(long size) {
15863        return stringifySize(size * 1024, 1024);
15864    }
15865
15866    // Update this version number in case you change the 'compact' format
15867    private static final int MEMINFO_COMPACT_VERSION = 1;
15868
15869    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15870            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15871        boolean dumpDetails = false;
15872        boolean dumpFullDetails = false;
15873        boolean dumpDalvik = false;
15874        boolean dumpSummaryOnly = false;
15875        boolean dumpUnreachable = false;
15876        boolean oomOnly = false;
15877        boolean isCompact = false;
15878        boolean localOnly = false;
15879        boolean packages = false;
15880        boolean isCheckinRequest = false;
15881        boolean dumpSwapPss = false;
15882
15883        int opti = 0;
15884        while (opti < args.length) {
15885            String opt = args[opti];
15886            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15887                break;
15888            }
15889            opti++;
15890            if ("-a".equals(opt)) {
15891                dumpDetails = true;
15892                dumpFullDetails = true;
15893                dumpDalvik = true;
15894                dumpSwapPss = true;
15895            } else if ("-d".equals(opt)) {
15896                dumpDalvik = true;
15897            } else if ("-c".equals(opt)) {
15898                isCompact = true;
15899            } else if ("-s".equals(opt)) {
15900                dumpDetails = true;
15901                dumpSummaryOnly = true;
15902            } else if ("-S".equals(opt)) {
15903                dumpSwapPss = true;
15904            } else if ("--unreachable".equals(opt)) {
15905                dumpUnreachable = true;
15906            } else if ("--oom".equals(opt)) {
15907                oomOnly = true;
15908            } else if ("--local".equals(opt)) {
15909                localOnly = true;
15910            } else if ("--package".equals(opt)) {
15911                packages = true;
15912            } else if ("--checkin".equals(opt)) {
15913                isCheckinRequest = true;
15914
15915            } else if ("-h".equals(opt)) {
15916                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15917                pw.println("  -a: include all available information for each process.");
15918                pw.println("  -d: include dalvik details.");
15919                pw.println("  -c: dump in a compact machine-parseable representation.");
15920                pw.println("  -s: dump only summary of application memory usage.");
15921                pw.println("  -S: dump also SwapPss.");
15922                pw.println("  --oom: only show processes organized by oom adj.");
15923                pw.println("  --local: only collect details locally, don't call process.");
15924                pw.println("  --package: interpret process arg as package, dumping all");
15925                pw.println("             processes that have loaded that package.");
15926                pw.println("  --checkin: dump data for a checkin");
15927                pw.println("If [process] is specified it can be the name or ");
15928                pw.println("pid of a specific process to dump.");
15929                return;
15930            } else {
15931                pw.println("Unknown argument: " + opt + "; use -h for help");
15932            }
15933        }
15934
15935        long uptime = SystemClock.uptimeMillis();
15936        long realtime = SystemClock.elapsedRealtime();
15937        final long[] tmpLong = new long[1];
15938
15939        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15940        if (procs == null) {
15941            // No Java processes.  Maybe they want to print a native process.
15942            if (args != null && args.length > opti
15943                    && args[opti].charAt(0) != '-') {
15944                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15945                        = new ArrayList<ProcessCpuTracker.Stats>();
15946                updateCpuStatsNow();
15947                int findPid = -1;
15948                try {
15949                    findPid = Integer.parseInt(args[opti]);
15950                } catch (NumberFormatException e) {
15951                }
15952                synchronized (mProcessCpuTracker) {
15953                    final int N = mProcessCpuTracker.countStats();
15954                    for (int i=0; i<N; i++) {
15955                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15956                        if (st.pid == findPid || (st.baseName != null
15957                                && st.baseName.equals(args[opti]))) {
15958                            nativeProcs.add(st);
15959                        }
15960                    }
15961                }
15962                if (nativeProcs.size() > 0) {
15963                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15964                            isCompact);
15965                    Debug.MemoryInfo mi = null;
15966                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15967                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15968                        final int pid = r.pid;
15969                        if (!isCheckinRequest && dumpDetails) {
15970                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15971                        }
15972                        if (mi == null) {
15973                            mi = new Debug.MemoryInfo();
15974                        }
15975                        if (dumpDetails || (!brief && !oomOnly)) {
15976                            Debug.getMemoryInfo(pid, mi);
15977                        } else {
15978                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15979                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15980                        }
15981                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15982                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15983                        if (isCheckinRequest) {
15984                            pw.println();
15985                        }
15986                    }
15987                    return;
15988                }
15989            }
15990            pw.println("No process found for: " + args[opti]);
15991            return;
15992        }
15993
15994        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15995            dumpDetails = true;
15996        }
15997
15998        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15999
16000        String[] innerArgs = new String[args.length-opti];
16001        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16002
16003        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16004        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16005        long nativePss = 0;
16006        long nativeSwapPss = 0;
16007        long dalvikPss = 0;
16008        long dalvikSwapPss = 0;
16009        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16010                EmptyArray.LONG;
16011        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16012                EmptyArray.LONG;
16013        long otherPss = 0;
16014        long otherSwapPss = 0;
16015        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16016        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16017
16018        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16019        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16020        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16021                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16022
16023        long totalPss = 0;
16024        long totalSwapPss = 0;
16025        long cachedPss = 0;
16026        long cachedSwapPss = 0;
16027        boolean hasSwapPss = false;
16028
16029        Debug.MemoryInfo mi = null;
16030        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16031            final ProcessRecord r = procs.get(i);
16032            final IApplicationThread thread;
16033            final int pid;
16034            final int oomAdj;
16035            final boolean hasActivities;
16036            synchronized (this) {
16037                thread = r.thread;
16038                pid = r.pid;
16039                oomAdj = r.getSetAdjWithServices();
16040                hasActivities = r.activities.size() > 0;
16041            }
16042            if (thread != null) {
16043                if (!isCheckinRequest && dumpDetails) {
16044                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16045                }
16046                if (mi == null) {
16047                    mi = new Debug.MemoryInfo();
16048                }
16049                if (dumpDetails || (!brief && !oomOnly)) {
16050                    Debug.getMemoryInfo(pid, mi);
16051                    hasSwapPss = mi.hasSwappedOutPss;
16052                } else {
16053                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16054                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16055                }
16056                if (dumpDetails) {
16057                    if (localOnly) {
16058                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16059                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16060                        if (isCheckinRequest) {
16061                            pw.println();
16062                        }
16063                    } else {
16064                        try {
16065                            pw.flush();
16066                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16067                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16068                        } catch (RemoteException e) {
16069                            if (!isCheckinRequest) {
16070                                pw.println("Got RemoteException!");
16071                                pw.flush();
16072                            }
16073                        }
16074                    }
16075                }
16076
16077                final long myTotalPss = mi.getTotalPss();
16078                final long myTotalUss = mi.getTotalUss();
16079                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16080
16081                synchronized (this) {
16082                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16083                        // Record this for posterity if the process has been stable.
16084                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16085                    }
16086                }
16087
16088                if (!isCheckinRequest && mi != null) {
16089                    totalPss += myTotalPss;
16090                    totalSwapPss += myTotalSwapPss;
16091                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16092                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16093                            myTotalSwapPss, pid, hasActivities);
16094                    procMems.add(pssItem);
16095                    procMemsMap.put(pid, pssItem);
16096
16097                    nativePss += mi.nativePss;
16098                    nativeSwapPss += mi.nativeSwappedOutPss;
16099                    dalvikPss += mi.dalvikPss;
16100                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16101                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16102                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16103                        dalvikSubitemSwapPss[j] +=
16104                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16105                    }
16106                    otherPss += mi.otherPss;
16107                    otherSwapPss += mi.otherSwappedOutPss;
16108                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16109                        long mem = mi.getOtherPss(j);
16110                        miscPss[j] += mem;
16111                        otherPss -= mem;
16112                        mem = mi.getOtherSwappedOutPss(j);
16113                        miscSwapPss[j] += mem;
16114                        otherSwapPss -= mem;
16115                    }
16116
16117                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16118                        cachedPss += myTotalPss;
16119                        cachedSwapPss += myTotalSwapPss;
16120                    }
16121
16122                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16123                        if (oomIndex == (oomPss.length - 1)
16124                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16125                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16126                            oomPss[oomIndex] += myTotalPss;
16127                            oomSwapPss[oomIndex] += myTotalSwapPss;
16128                            if (oomProcs[oomIndex] == null) {
16129                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16130                            }
16131                            oomProcs[oomIndex].add(pssItem);
16132                            break;
16133                        }
16134                    }
16135                }
16136            }
16137        }
16138
16139        long nativeProcTotalPss = 0;
16140
16141        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16142            // If we are showing aggregations, also look for native processes to
16143            // include so that our aggregations are more accurate.
16144            updateCpuStatsNow();
16145            mi = null;
16146            synchronized (mProcessCpuTracker) {
16147                final int N = mProcessCpuTracker.countStats();
16148                for (int i=0; i<N; i++) {
16149                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16150                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16151                        if (mi == null) {
16152                            mi = new Debug.MemoryInfo();
16153                        }
16154                        if (!brief && !oomOnly) {
16155                            Debug.getMemoryInfo(st.pid, mi);
16156                        } else {
16157                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16158                            mi.nativePrivateDirty = (int)tmpLong[0];
16159                        }
16160
16161                        final long myTotalPss = mi.getTotalPss();
16162                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16163                        totalPss += myTotalPss;
16164                        nativeProcTotalPss += myTotalPss;
16165
16166                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16167                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16168                        procMems.add(pssItem);
16169
16170                        nativePss += mi.nativePss;
16171                        nativeSwapPss += mi.nativeSwappedOutPss;
16172                        dalvikPss += mi.dalvikPss;
16173                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16174                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16175                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16176                            dalvikSubitemSwapPss[j] +=
16177                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16178                        }
16179                        otherPss += mi.otherPss;
16180                        otherSwapPss += mi.otherSwappedOutPss;
16181                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16182                            long mem = mi.getOtherPss(j);
16183                            miscPss[j] += mem;
16184                            otherPss -= mem;
16185                            mem = mi.getOtherSwappedOutPss(j);
16186                            miscSwapPss[j] += mem;
16187                            otherSwapPss -= mem;
16188                        }
16189                        oomPss[0] += myTotalPss;
16190                        oomSwapPss[0] += myTotalSwapPss;
16191                        if (oomProcs[0] == null) {
16192                            oomProcs[0] = new ArrayList<MemItem>();
16193                        }
16194                        oomProcs[0].add(pssItem);
16195                    }
16196                }
16197            }
16198
16199            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16200
16201            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16202            final MemItem dalvikItem =
16203                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16204            if (dalvikSubitemPss.length > 0) {
16205                dalvikItem.subitems = new ArrayList<MemItem>();
16206                for (int j=0; j<dalvikSubitemPss.length; j++) {
16207                    final String name = Debug.MemoryInfo.getOtherLabel(
16208                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16209                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16210                                    dalvikSubitemSwapPss[j], j));
16211                }
16212            }
16213            catMems.add(dalvikItem);
16214            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16215            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16216                String label = Debug.MemoryInfo.getOtherLabel(j);
16217                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16218            }
16219
16220            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16221            for (int j=0; j<oomPss.length; j++) {
16222                if (oomPss[j] != 0) {
16223                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16224                            : DUMP_MEM_OOM_LABEL[j];
16225                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16226                            DUMP_MEM_OOM_ADJ[j]);
16227                    item.subitems = oomProcs[j];
16228                    oomMems.add(item);
16229                }
16230            }
16231
16232            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16233            if (!brief && !oomOnly && !isCompact) {
16234                pw.println();
16235                pw.println("Total PSS by process:");
16236                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16237                pw.println();
16238            }
16239            if (!isCompact) {
16240                pw.println("Total PSS by OOM adjustment:");
16241            }
16242            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16243            if (!brief && !oomOnly) {
16244                PrintWriter out = categoryPw != null ? categoryPw : pw;
16245                if (!isCompact) {
16246                    out.println();
16247                    out.println("Total PSS by category:");
16248                }
16249                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16250            }
16251            if (!isCompact) {
16252                pw.println();
16253            }
16254            MemInfoReader memInfo = new MemInfoReader();
16255            memInfo.readMemInfo();
16256            if (nativeProcTotalPss > 0) {
16257                synchronized (this) {
16258                    final long cachedKb = memInfo.getCachedSizeKb();
16259                    final long freeKb = memInfo.getFreeSizeKb();
16260                    final long zramKb = memInfo.getZramTotalSizeKb();
16261                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16262                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16263                            kernelKb*1024, nativeProcTotalPss*1024);
16264                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16265                            nativeProcTotalPss);
16266                }
16267            }
16268            if (!brief) {
16269                if (!isCompact) {
16270                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16271                    pw.print(" (status ");
16272                    switch (mLastMemoryLevel) {
16273                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16274                            pw.println("normal)");
16275                            break;
16276                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16277                            pw.println("moderate)");
16278                            break;
16279                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16280                            pw.println("low)");
16281                            break;
16282                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16283                            pw.println("critical)");
16284                            break;
16285                        default:
16286                            pw.print(mLastMemoryLevel);
16287                            pw.println(")");
16288                            break;
16289                    }
16290                    pw.print(" Free RAM: ");
16291                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16292                            + memInfo.getFreeSizeKb()));
16293                    pw.print(" (");
16294                    pw.print(stringifyKBSize(cachedPss));
16295                    pw.print(" cached pss + ");
16296                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16297                    pw.print(" cached kernel + ");
16298                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16299                    pw.println(" free)");
16300                } else {
16301                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16302                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16303                            + memInfo.getFreeSizeKb()); pw.print(",");
16304                    pw.println(totalPss - cachedPss);
16305                }
16306            }
16307            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16308                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16309                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16310            if (!isCompact) {
16311                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16312                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16313                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16314                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16315                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16316            } else {
16317                pw.print("lostram,"); pw.println(lostRAM);
16318            }
16319            if (!brief) {
16320                if (memInfo.getZramTotalSizeKb() != 0) {
16321                    if (!isCompact) {
16322                        pw.print("     ZRAM: ");
16323                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16324                                pw.print(" physical used for ");
16325                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16326                                        - memInfo.getSwapFreeSizeKb()));
16327                                pw.print(" in swap (");
16328                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16329                                pw.println(" total swap)");
16330                    } else {
16331                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16332                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16333                                pw.println(memInfo.getSwapFreeSizeKb());
16334                    }
16335                }
16336                final long[] ksm = getKsmInfo();
16337                if (!isCompact) {
16338                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16339                            || ksm[KSM_VOLATILE] != 0) {
16340                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16341                                pw.print(" saved from shared ");
16342                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16343                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16344                                pw.print(" unshared; ");
16345                                pw.print(stringifyKBSize(
16346                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16347                    }
16348                    pw.print("   Tuning: ");
16349                    pw.print(ActivityManager.staticGetMemoryClass());
16350                    pw.print(" (large ");
16351                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16352                    pw.print("), oom ");
16353                    pw.print(stringifySize(
16354                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16355                    pw.print(", restore limit ");
16356                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16357                    if (ActivityManager.isLowRamDeviceStatic()) {
16358                        pw.print(" (low-ram)");
16359                    }
16360                    if (ActivityManager.isHighEndGfx()) {
16361                        pw.print(" (high-end-gfx)");
16362                    }
16363                    pw.println();
16364                } else {
16365                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16366                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16367                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16368                    pw.print("tuning,");
16369                    pw.print(ActivityManager.staticGetMemoryClass());
16370                    pw.print(',');
16371                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16372                    pw.print(',');
16373                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16374                    if (ActivityManager.isLowRamDeviceStatic()) {
16375                        pw.print(",low-ram");
16376                    }
16377                    if (ActivityManager.isHighEndGfx()) {
16378                        pw.print(",high-end-gfx");
16379                    }
16380                    pw.println();
16381                }
16382            }
16383        }
16384    }
16385
16386    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16387            long memtrack, String name) {
16388        sb.append("  ");
16389        sb.append(ProcessList.makeOomAdjString(oomAdj));
16390        sb.append(' ');
16391        sb.append(ProcessList.makeProcStateString(procState));
16392        sb.append(' ');
16393        ProcessList.appendRamKb(sb, pss);
16394        sb.append(": ");
16395        sb.append(name);
16396        if (memtrack > 0) {
16397            sb.append(" (");
16398            sb.append(stringifyKBSize(memtrack));
16399            sb.append(" memtrack)");
16400        }
16401    }
16402
16403    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16404        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16405        sb.append(" (pid ");
16406        sb.append(mi.pid);
16407        sb.append(") ");
16408        sb.append(mi.adjType);
16409        sb.append('\n');
16410        if (mi.adjReason != null) {
16411            sb.append("                      ");
16412            sb.append(mi.adjReason);
16413            sb.append('\n');
16414        }
16415    }
16416
16417    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16418        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16419        for (int i=0, N=memInfos.size(); i<N; i++) {
16420            ProcessMemInfo mi = memInfos.get(i);
16421            infoMap.put(mi.pid, mi);
16422        }
16423        updateCpuStatsNow();
16424        long[] memtrackTmp = new long[1];
16425        synchronized (mProcessCpuTracker) {
16426            final int N = mProcessCpuTracker.countStats();
16427            for (int i=0; i<N; i++) {
16428                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16429                if (st.vsize > 0) {
16430                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16431                    if (pss > 0) {
16432                        if (infoMap.indexOfKey(st.pid) < 0) {
16433                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16434                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16435                            mi.pss = pss;
16436                            mi.memtrack = memtrackTmp[0];
16437                            memInfos.add(mi);
16438                        }
16439                    }
16440                }
16441            }
16442        }
16443
16444        long totalPss = 0;
16445        long totalMemtrack = 0;
16446        for (int i=0, N=memInfos.size(); i<N; i++) {
16447            ProcessMemInfo mi = memInfos.get(i);
16448            if (mi.pss == 0) {
16449                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16450                mi.memtrack = memtrackTmp[0];
16451            }
16452            totalPss += mi.pss;
16453            totalMemtrack += mi.memtrack;
16454        }
16455        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16456            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16457                if (lhs.oomAdj != rhs.oomAdj) {
16458                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16459                }
16460                if (lhs.pss != rhs.pss) {
16461                    return lhs.pss < rhs.pss ? 1 : -1;
16462                }
16463                return 0;
16464            }
16465        });
16466
16467        StringBuilder tag = new StringBuilder(128);
16468        StringBuilder stack = new StringBuilder(128);
16469        tag.append("Low on memory -- ");
16470        appendMemBucket(tag, totalPss, "total", false);
16471        appendMemBucket(stack, totalPss, "total", true);
16472
16473        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16474        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16475        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16476
16477        boolean firstLine = true;
16478        int lastOomAdj = Integer.MIN_VALUE;
16479        long extraNativeRam = 0;
16480        long extraNativeMemtrack = 0;
16481        long cachedPss = 0;
16482        for (int i=0, N=memInfos.size(); i<N; i++) {
16483            ProcessMemInfo mi = memInfos.get(i);
16484
16485            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16486                cachedPss += mi.pss;
16487            }
16488
16489            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16490                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16491                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16492                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16493                if (lastOomAdj != mi.oomAdj) {
16494                    lastOomAdj = mi.oomAdj;
16495                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16496                        tag.append(" / ");
16497                    }
16498                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16499                        if (firstLine) {
16500                            stack.append(":");
16501                            firstLine = false;
16502                        }
16503                        stack.append("\n\t at ");
16504                    } else {
16505                        stack.append("$");
16506                    }
16507                } else {
16508                    tag.append(" ");
16509                    stack.append("$");
16510                }
16511                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16512                    appendMemBucket(tag, mi.pss, mi.name, false);
16513                }
16514                appendMemBucket(stack, mi.pss, mi.name, true);
16515                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16516                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16517                    stack.append("(");
16518                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16519                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16520                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16521                            stack.append(":");
16522                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16523                        }
16524                    }
16525                    stack.append(")");
16526                }
16527            }
16528
16529            appendMemInfo(fullNativeBuilder, mi);
16530            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16531                // The short form only has native processes that are >= 512K.
16532                if (mi.pss >= 512) {
16533                    appendMemInfo(shortNativeBuilder, mi);
16534                } else {
16535                    extraNativeRam += mi.pss;
16536                    extraNativeMemtrack += mi.memtrack;
16537                }
16538            } else {
16539                // Short form has all other details, but if we have collected RAM
16540                // from smaller native processes let's dump a summary of that.
16541                if (extraNativeRam > 0) {
16542                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16543                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16544                    shortNativeBuilder.append('\n');
16545                    extraNativeRam = 0;
16546                }
16547                appendMemInfo(fullJavaBuilder, mi);
16548            }
16549        }
16550
16551        fullJavaBuilder.append("           ");
16552        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16553        fullJavaBuilder.append(": TOTAL");
16554        if (totalMemtrack > 0) {
16555            fullJavaBuilder.append(" (");
16556            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16557            fullJavaBuilder.append(" memtrack)");
16558        } else {
16559        }
16560        fullJavaBuilder.append("\n");
16561
16562        MemInfoReader memInfo = new MemInfoReader();
16563        memInfo.readMemInfo();
16564        final long[] infos = memInfo.getRawInfo();
16565
16566        StringBuilder memInfoBuilder = new StringBuilder(1024);
16567        Debug.getMemInfo(infos);
16568        memInfoBuilder.append("  MemInfo: ");
16569        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16570        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16571        memInfoBuilder.append(stringifyKBSize(
16572                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16573        memInfoBuilder.append(stringifyKBSize(
16574                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16575        memInfoBuilder.append(stringifyKBSize(
16576                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16577        memInfoBuilder.append("           ");
16578        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16579        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16580        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16581        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16582        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16583            memInfoBuilder.append("  ZRAM: ");
16584            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16585            memInfoBuilder.append(" RAM, ");
16586            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16587            memInfoBuilder.append(" swap total, ");
16588            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16589            memInfoBuilder.append(" swap free\n");
16590        }
16591        final long[] ksm = getKsmInfo();
16592        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16593                || ksm[KSM_VOLATILE] != 0) {
16594            memInfoBuilder.append("  KSM: ");
16595            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16596            memInfoBuilder.append(" saved from shared ");
16597            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16598            memInfoBuilder.append("\n       ");
16599            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16600            memInfoBuilder.append(" unshared; ");
16601            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16602            memInfoBuilder.append(" volatile\n");
16603        }
16604        memInfoBuilder.append("  Free RAM: ");
16605        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16606                + memInfo.getFreeSizeKb()));
16607        memInfoBuilder.append("\n");
16608        memInfoBuilder.append("  Used RAM: ");
16609        memInfoBuilder.append(stringifyKBSize(
16610                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16611        memInfoBuilder.append("\n");
16612        memInfoBuilder.append("  Lost RAM: ");
16613        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16614                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16615                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16616        memInfoBuilder.append("\n");
16617        Slog.i(TAG, "Low on memory:");
16618        Slog.i(TAG, shortNativeBuilder.toString());
16619        Slog.i(TAG, fullJavaBuilder.toString());
16620        Slog.i(TAG, memInfoBuilder.toString());
16621
16622        StringBuilder dropBuilder = new StringBuilder(1024);
16623        /*
16624        StringWriter oomSw = new StringWriter();
16625        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16626        StringWriter catSw = new StringWriter();
16627        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16628        String[] emptyArgs = new String[] { };
16629        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16630        oomPw.flush();
16631        String oomString = oomSw.toString();
16632        */
16633        dropBuilder.append("Low on memory:");
16634        dropBuilder.append(stack);
16635        dropBuilder.append('\n');
16636        dropBuilder.append(fullNativeBuilder);
16637        dropBuilder.append(fullJavaBuilder);
16638        dropBuilder.append('\n');
16639        dropBuilder.append(memInfoBuilder);
16640        dropBuilder.append('\n');
16641        /*
16642        dropBuilder.append(oomString);
16643        dropBuilder.append('\n');
16644        */
16645        StringWriter catSw = new StringWriter();
16646        synchronized (ActivityManagerService.this) {
16647            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16648            String[] emptyArgs = new String[] { };
16649            catPw.println();
16650            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16651            catPw.println();
16652            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16653                    false, null).dumpLocked();
16654            catPw.println();
16655            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16656            catPw.flush();
16657        }
16658        dropBuilder.append(catSw.toString());
16659        addErrorToDropBox("lowmem", null, "system_server", null,
16660                null, tag.toString(), dropBuilder.toString(), null, null);
16661        //Slog.i(TAG, "Sent to dropbox:");
16662        //Slog.i(TAG, dropBuilder.toString());
16663        synchronized (ActivityManagerService.this) {
16664            long now = SystemClock.uptimeMillis();
16665            if (mLastMemUsageReportTime < now) {
16666                mLastMemUsageReportTime = now;
16667            }
16668        }
16669    }
16670
16671    /**
16672     * Searches array of arguments for the specified string
16673     * @param args array of argument strings
16674     * @param value value to search for
16675     * @return true if the value is contained in the array
16676     */
16677    private static boolean scanArgs(String[] args, String value) {
16678        if (args != null) {
16679            for (String arg : args) {
16680                if (value.equals(arg)) {
16681                    return true;
16682                }
16683            }
16684        }
16685        return false;
16686    }
16687
16688    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16689            ContentProviderRecord cpr, boolean always) {
16690        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16691
16692        if (!inLaunching || always) {
16693            synchronized (cpr) {
16694                cpr.launchingApp = null;
16695                cpr.notifyAll();
16696            }
16697            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16698            String names[] = cpr.info.authority.split(";");
16699            for (int j = 0; j < names.length; j++) {
16700                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16701            }
16702        }
16703
16704        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16705            ContentProviderConnection conn = cpr.connections.get(i);
16706            if (conn.waiting) {
16707                // If this connection is waiting for the provider, then we don't
16708                // need to mess with its process unless we are always removing
16709                // or for some reason the provider is not currently launching.
16710                if (inLaunching && !always) {
16711                    continue;
16712                }
16713            }
16714            ProcessRecord capp = conn.client;
16715            conn.dead = true;
16716            if (conn.stableCount > 0) {
16717                if (!capp.persistent && capp.thread != null
16718                        && capp.pid != 0
16719                        && capp.pid != MY_PID) {
16720                    capp.kill("depends on provider "
16721                            + cpr.name.flattenToShortString()
16722                            + " in dying proc " + (proc != null ? proc.processName : "??")
16723                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16724                }
16725            } else if (capp.thread != null && conn.provider.provider != null) {
16726                try {
16727                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16728                } catch (RemoteException e) {
16729                }
16730                // In the protocol here, we don't expect the client to correctly
16731                // clean up this connection, we'll just remove it.
16732                cpr.connections.remove(i);
16733                if (conn.client.conProviders.remove(conn)) {
16734                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16735                }
16736            }
16737        }
16738
16739        if (inLaunching && always) {
16740            mLaunchingProviders.remove(cpr);
16741        }
16742        return inLaunching;
16743    }
16744
16745    /**
16746     * Main code for cleaning up a process when it has gone away.  This is
16747     * called both as a result of the process dying, or directly when stopping
16748     * a process when running in single process mode.
16749     *
16750     * @return Returns true if the given process has been restarted, so the
16751     * app that was passed in must remain on the process lists.
16752     */
16753    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16754            boolean restarting, boolean allowRestart, int index) {
16755        if (index >= 0) {
16756            removeLruProcessLocked(app);
16757            ProcessList.remove(app.pid);
16758        }
16759
16760        mProcessesToGc.remove(app);
16761        mPendingPssProcesses.remove(app);
16762
16763        // Dismiss any open dialogs.
16764        if (app.crashDialog != null && !app.forceCrashReport) {
16765            app.crashDialog.dismiss();
16766            app.crashDialog = null;
16767        }
16768        if (app.anrDialog != null) {
16769            app.anrDialog.dismiss();
16770            app.anrDialog = null;
16771        }
16772        if (app.waitDialog != null) {
16773            app.waitDialog.dismiss();
16774            app.waitDialog = null;
16775        }
16776
16777        app.crashing = false;
16778        app.notResponding = false;
16779
16780        app.resetPackageList(mProcessStats);
16781        app.unlinkDeathRecipient();
16782        app.makeInactive(mProcessStats);
16783        app.waitingToKill = null;
16784        app.forcingToForeground = null;
16785        updateProcessForegroundLocked(app, false, false);
16786        app.foregroundActivities = false;
16787        app.hasShownUi = false;
16788        app.treatLikeActivity = false;
16789        app.hasAboveClient = false;
16790        app.hasClientActivities = false;
16791
16792        mServices.killServicesLocked(app, allowRestart);
16793
16794        boolean restart = false;
16795
16796        // Remove published content providers.
16797        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16798            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16799            final boolean always = app.bad || !allowRestart;
16800            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16801            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16802                // We left the provider in the launching list, need to
16803                // restart it.
16804                restart = true;
16805            }
16806
16807            cpr.provider = null;
16808            cpr.proc = null;
16809        }
16810        app.pubProviders.clear();
16811
16812        // Take care of any launching providers waiting for this process.
16813        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16814            restart = true;
16815        }
16816
16817        // Unregister from connected content providers.
16818        if (!app.conProviders.isEmpty()) {
16819            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16820                ContentProviderConnection conn = app.conProviders.get(i);
16821                conn.provider.connections.remove(conn);
16822                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16823                        conn.provider.name);
16824            }
16825            app.conProviders.clear();
16826        }
16827
16828        // At this point there may be remaining entries in mLaunchingProviders
16829        // where we were the only one waiting, so they are no longer of use.
16830        // Look for these and clean up if found.
16831        // XXX Commented out for now.  Trying to figure out a way to reproduce
16832        // the actual situation to identify what is actually going on.
16833        if (false) {
16834            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16835                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16836                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16837                    synchronized (cpr) {
16838                        cpr.launchingApp = null;
16839                        cpr.notifyAll();
16840                    }
16841                }
16842            }
16843        }
16844
16845        skipCurrentReceiverLocked(app);
16846
16847        // Unregister any receivers.
16848        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16849            removeReceiverLocked(app.receivers.valueAt(i));
16850        }
16851        app.receivers.clear();
16852
16853        // If the app is undergoing backup, tell the backup manager about it
16854        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16855            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16856                    + mBackupTarget.appInfo + " died during backup");
16857            try {
16858                IBackupManager bm = IBackupManager.Stub.asInterface(
16859                        ServiceManager.getService(Context.BACKUP_SERVICE));
16860                bm.agentDisconnected(app.info.packageName);
16861            } catch (RemoteException e) {
16862                // can't happen; backup manager is local
16863            }
16864        }
16865
16866        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16867            ProcessChangeItem item = mPendingProcessChanges.get(i);
16868            if (item.pid == app.pid) {
16869                mPendingProcessChanges.remove(i);
16870                mAvailProcessChanges.add(item);
16871            }
16872        }
16873        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16874                null).sendToTarget();
16875
16876        // If the caller is restarting this app, then leave it in its
16877        // current lists and let the caller take care of it.
16878        if (restarting) {
16879            return false;
16880        }
16881
16882        if (!app.persistent || app.isolated) {
16883            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16884                    "Removing non-persistent process during cleanup: " + app);
16885            removeProcessNameLocked(app.processName, app.uid);
16886            if (mHeavyWeightProcess == app) {
16887                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16888                        mHeavyWeightProcess.userId, 0));
16889                mHeavyWeightProcess = null;
16890            }
16891        } else if (!app.removed) {
16892            // This app is persistent, so we need to keep its record around.
16893            // If it is not already on the pending app list, add it there
16894            // and start a new process for it.
16895            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16896                mPersistentStartingProcesses.add(app);
16897                restart = true;
16898            }
16899        }
16900        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16901                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16902        mProcessesOnHold.remove(app);
16903
16904        if (app == mHomeProcess) {
16905            mHomeProcess = null;
16906        }
16907        if (app == mPreviousProcess) {
16908            mPreviousProcess = null;
16909        }
16910
16911        if (restart && !app.isolated) {
16912            // We have components that still need to be running in the
16913            // process, so re-launch it.
16914            if (index < 0) {
16915                ProcessList.remove(app.pid);
16916            }
16917            addProcessNameLocked(app);
16918            startProcessLocked(app, "restart", app.processName);
16919            return true;
16920        } else if (app.pid > 0 && app.pid != MY_PID) {
16921            // Goodbye!
16922            boolean removed;
16923            synchronized (mPidsSelfLocked) {
16924                mPidsSelfLocked.remove(app.pid);
16925                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16926            }
16927            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16928            if (app.isolated) {
16929                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16930            }
16931            app.setPid(0);
16932        }
16933        return false;
16934    }
16935
16936    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16937        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16938            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16939            if (cpr.launchingApp == app) {
16940                return true;
16941            }
16942        }
16943        return false;
16944    }
16945
16946    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16947        // Look through the content providers we are waiting to have launched,
16948        // and if any run in this process then either schedule a restart of
16949        // the process or kill the client waiting for it if this process has
16950        // gone bad.
16951        boolean restart = false;
16952        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16953            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16954            if (cpr.launchingApp == app) {
16955                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16956                    restart = true;
16957                } else {
16958                    removeDyingProviderLocked(app, cpr, true);
16959                }
16960            }
16961        }
16962        return restart;
16963    }
16964
16965    // =========================================================
16966    // SERVICES
16967    // =========================================================
16968
16969    @Override
16970    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16971            int flags) {
16972        enforceNotIsolatedCaller("getServices");
16973        synchronized (this) {
16974            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16975        }
16976    }
16977
16978    @Override
16979    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16980        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16981        synchronized (this) {
16982            return mServices.getRunningServiceControlPanelLocked(name);
16983        }
16984    }
16985
16986    @Override
16987    public ComponentName startService(IApplicationThread caller, Intent service,
16988            String resolvedType, String callingPackage, int userId)
16989            throws TransactionTooLargeException {
16990        enforceNotIsolatedCaller("startService");
16991        // Refuse possible leaked file descriptors
16992        if (service != null && service.hasFileDescriptors() == true) {
16993            throw new IllegalArgumentException("File descriptors passed in Intent");
16994        }
16995
16996        if (callingPackage == null) {
16997            throw new IllegalArgumentException("callingPackage cannot be null");
16998        }
16999
17000        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17001                "startService: " + service + " type=" + resolvedType);
17002        synchronized(this) {
17003            final int callingPid = Binder.getCallingPid();
17004            final int callingUid = Binder.getCallingUid();
17005            final long origId = Binder.clearCallingIdentity();
17006            ComponentName res = mServices.startServiceLocked(caller, service,
17007                    resolvedType, callingPid, callingUid, callingPackage, userId);
17008            Binder.restoreCallingIdentity(origId);
17009            return res;
17010        }
17011    }
17012
17013    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17014            String callingPackage, int userId)
17015            throws TransactionTooLargeException {
17016        synchronized(this) {
17017            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17018                    "startServiceInPackage: " + service + " type=" + resolvedType);
17019            final long origId = Binder.clearCallingIdentity();
17020            ComponentName res = mServices.startServiceLocked(null, service,
17021                    resolvedType, -1, uid, callingPackage, userId);
17022            Binder.restoreCallingIdentity(origId);
17023            return res;
17024        }
17025    }
17026
17027    @Override
17028    public int stopService(IApplicationThread caller, Intent service,
17029            String resolvedType, int userId) {
17030        enforceNotIsolatedCaller("stopService");
17031        // Refuse possible leaked file descriptors
17032        if (service != null && service.hasFileDescriptors() == true) {
17033            throw new IllegalArgumentException("File descriptors passed in Intent");
17034        }
17035
17036        synchronized(this) {
17037            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17038        }
17039    }
17040
17041    @Override
17042    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17043        enforceNotIsolatedCaller("peekService");
17044        // Refuse possible leaked file descriptors
17045        if (service != null && service.hasFileDescriptors() == true) {
17046            throw new IllegalArgumentException("File descriptors passed in Intent");
17047        }
17048
17049        if (callingPackage == null) {
17050            throw new IllegalArgumentException("callingPackage cannot be null");
17051        }
17052
17053        synchronized(this) {
17054            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17055        }
17056    }
17057
17058    @Override
17059    public boolean stopServiceToken(ComponentName className, IBinder token,
17060            int startId) {
17061        synchronized(this) {
17062            return mServices.stopServiceTokenLocked(className, token, startId);
17063        }
17064    }
17065
17066    @Override
17067    public void setServiceForeground(ComponentName className, IBinder token,
17068            int id, Notification notification, int flags) {
17069        synchronized(this) {
17070            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17071        }
17072    }
17073
17074    @Override
17075    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17076            boolean requireFull, String name, String callerPackage) {
17077        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17078                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17079    }
17080
17081    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17082            String className, int flags) {
17083        boolean result = false;
17084        // For apps that don't have pre-defined UIDs, check for permission
17085        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17086            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17087                if (ActivityManager.checkUidPermission(
17088                        INTERACT_ACROSS_USERS,
17089                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17090                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17091                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17092                            + " requests FLAG_SINGLE_USER, but app does not hold "
17093                            + INTERACT_ACROSS_USERS;
17094                    Slog.w(TAG, msg);
17095                    throw new SecurityException(msg);
17096                }
17097                // Permission passed
17098                result = true;
17099            }
17100        } else if ("system".equals(componentProcessName)) {
17101            result = true;
17102        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17103            // Phone app and persistent apps are allowed to export singleuser providers.
17104            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17105                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17106        }
17107        if (DEBUG_MU) Slog.v(TAG_MU,
17108                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17109                + Integer.toHexString(flags) + ") = " + result);
17110        return result;
17111    }
17112
17113    /**
17114     * Checks to see if the caller is in the same app as the singleton
17115     * component, or the component is in a special app. It allows special apps
17116     * to export singleton components but prevents exporting singleton
17117     * components for regular apps.
17118     */
17119    boolean isValidSingletonCall(int callingUid, int componentUid) {
17120        int componentAppId = UserHandle.getAppId(componentUid);
17121        return UserHandle.isSameApp(callingUid, componentUid)
17122                || componentAppId == Process.SYSTEM_UID
17123                || componentAppId == Process.PHONE_UID
17124                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17125                        == PackageManager.PERMISSION_GRANTED;
17126    }
17127
17128    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17129            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17130            int userId) throws TransactionTooLargeException {
17131        enforceNotIsolatedCaller("bindService");
17132
17133        // Refuse possible leaked file descriptors
17134        if (service != null && service.hasFileDescriptors() == true) {
17135            throw new IllegalArgumentException("File descriptors passed in Intent");
17136        }
17137
17138        if (callingPackage == null) {
17139            throw new IllegalArgumentException("callingPackage cannot be null");
17140        }
17141
17142        synchronized(this) {
17143            return mServices.bindServiceLocked(caller, token, service,
17144                    resolvedType, connection, flags, callingPackage, userId);
17145        }
17146    }
17147
17148    public boolean unbindService(IServiceConnection connection) {
17149        synchronized (this) {
17150            return mServices.unbindServiceLocked(connection);
17151        }
17152    }
17153
17154    public void publishService(IBinder token, Intent intent, IBinder service) {
17155        // Refuse possible leaked file descriptors
17156        if (intent != null && intent.hasFileDescriptors() == true) {
17157            throw new IllegalArgumentException("File descriptors passed in Intent");
17158        }
17159
17160        synchronized(this) {
17161            if (!(token instanceof ServiceRecord)) {
17162                throw new IllegalArgumentException("Invalid service token");
17163            }
17164            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17165        }
17166    }
17167
17168    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17169        // Refuse possible leaked file descriptors
17170        if (intent != null && intent.hasFileDescriptors() == true) {
17171            throw new IllegalArgumentException("File descriptors passed in Intent");
17172        }
17173
17174        synchronized(this) {
17175            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17176        }
17177    }
17178
17179    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17180        synchronized(this) {
17181            if (!(token instanceof ServiceRecord)) {
17182                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17183                throw new IllegalArgumentException("Invalid service token");
17184            }
17185            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17186        }
17187    }
17188
17189    // =========================================================
17190    // BACKUP AND RESTORE
17191    // =========================================================
17192
17193    // Cause the target app to be launched if necessary and its backup agent
17194    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17195    // activity manager to announce its creation.
17196    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17197        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17198        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17199
17200        IPackageManager pm = AppGlobals.getPackageManager();
17201        ApplicationInfo app = null;
17202        try {
17203            app = pm.getApplicationInfo(packageName, 0, userId);
17204        } catch (RemoteException e) {
17205            // can't happen; package manager is process-local
17206        }
17207        if (app == null) {
17208            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17209            return false;
17210        }
17211
17212        synchronized(this) {
17213            // !!! TODO: currently no check here that we're already bound
17214            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17215            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17216            synchronized (stats) {
17217                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17218            }
17219
17220            // Backup agent is now in use, its package can't be stopped.
17221            try {
17222                AppGlobals.getPackageManager().setPackageStoppedState(
17223                        app.packageName, false, UserHandle.getUserId(app.uid));
17224            } catch (RemoteException e) {
17225            } catch (IllegalArgumentException e) {
17226                Slog.w(TAG, "Failed trying to unstop package "
17227                        + app.packageName + ": " + e);
17228            }
17229
17230            BackupRecord r = new BackupRecord(ss, app, backupMode);
17231            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17232                    ? new ComponentName(app.packageName, app.backupAgentName)
17233                    : new ComponentName("android", "FullBackupAgent");
17234            // startProcessLocked() returns existing proc's record if it's already running
17235            ProcessRecord proc = startProcessLocked(app.processName, app,
17236                    false, 0, "backup", hostingName, false, false, false);
17237            if (proc == null) {
17238                Slog.e(TAG, "Unable to start backup agent process " + r);
17239                return false;
17240            }
17241
17242            // If the app is a regular app (uid >= 10000) and not the system server or phone
17243            // process, etc, then mark it as being in full backup so that certain calls to the
17244            // process can be blocked. This is not reset to false anywhere because we kill the
17245            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17246            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17247                proc.inFullBackup = true;
17248            }
17249            r.app = proc;
17250            mBackupTarget = r;
17251            mBackupAppName = app.packageName;
17252
17253            // Try not to kill the process during backup
17254            updateOomAdjLocked(proc);
17255
17256            // If the process is already attached, schedule the creation of the backup agent now.
17257            // If it is not yet live, this will be done when it attaches to the framework.
17258            if (proc.thread != null) {
17259                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17260                try {
17261                    proc.thread.scheduleCreateBackupAgent(app,
17262                            compatibilityInfoForPackageLocked(app), backupMode);
17263                } catch (RemoteException e) {
17264                    // Will time out on the backup manager side
17265                }
17266            } else {
17267                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17268            }
17269            // Invariants: at this point, the target app process exists and the application
17270            // is either already running or in the process of coming up.  mBackupTarget and
17271            // mBackupAppName describe the app, so that when it binds back to the AM we
17272            // know that it's scheduled for a backup-agent operation.
17273        }
17274
17275        return true;
17276    }
17277
17278    @Override
17279    public void clearPendingBackup() {
17280        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17281        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17282
17283        synchronized (this) {
17284            mBackupTarget = null;
17285            mBackupAppName = null;
17286        }
17287    }
17288
17289    // A backup agent has just come up
17290    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17291        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17292                + " = " + agent);
17293
17294        synchronized(this) {
17295            if (!agentPackageName.equals(mBackupAppName)) {
17296                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17297                return;
17298            }
17299        }
17300
17301        long oldIdent = Binder.clearCallingIdentity();
17302        try {
17303            IBackupManager bm = IBackupManager.Stub.asInterface(
17304                    ServiceManager.getService(Context.BACKUP_SERVICE));
17305            bm.agentConnected(agentPackageName, agent);
17306        } catch (RemoteException e) {
17307            // can't happen; the backup manager service is local
17308        } catch (Exception e) {
17309            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17310            e.printStackTrace();
17311        } finally {
17312            Binder.restoreCallingIdentity(oldIdent);
17313        }
17314    }
17315
17316    // done with this agent
17317    public void unbindBackupAgent(ApplicationInfo appInfo) {
17318        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17319        if (appInfo == null) {
17320            Slog.w(TAG, "unbind backup agent for null app");
17321            return;
17322        }
17323
17324        synchronized(this) {
17325            try {
17326                if (mBackupAppName == null) {
17327                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17328                    return;
17329                }
17330
17331                if (!mBackupAppName.equals(appInfo.packageName)) {
17332                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17333                    return;
17334                }
17335
17336                // Not backing this app up any more; reset its OOM adjustment
17337                final ProcessRecord proc = mBackupTarget.app;
17338                updateOomAdjLocked(proc);
17339
17340                // If the app crashed during backup, 'thread' will be null here
17341                if (proc.thread != null) {
17342                    try {
17343                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17344                                compatibilityInfoForPackageLocked(appInfo));
17345                    } catch (Exception e) {
17346                        Slog.e(TAG, "Exception when unbinding backup agent:");
17347                        e.printStackTrace();
17348                    }
17349                }
17350            } finally {
17351                mBackupTarget = null;
17352                mBackupAppName = null;
17353            }
17354        }
17355    }
17356    // =========================================================
17357    // BROADCASTS
17358    // =========================================================
17359
17360    boolean isPendingBroadcastProcessLocked(int pid) {
17361        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17362                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17363    }
17364
17365    void skipPendingBroadcastLocked(int pid) {
17366            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17367            for (BroadcastQueue queue : mBroadcastQueues) {
17368                queue.skipPendingBroadcastLocked(pid);
17369            }
17370    }
17371
17372    // The app just attached; send any pending broadcasts that it should receive
17373    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17374        boolean didSomething = false;
17375        for (BroadcastQueue queue : mBroadcastQueues) {
17376            didSomething |= queue.sendPendingBroadcastsLocked(app);
17377        }
17378        return didSomething;
17379    }
17380
17381    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17382            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17383        enforceNotIsolatedCaller("registerReceiver");
17384        ArrayList<Intent> stickyIntents = null;
17385        ProcessRecord callerApp = null;
17386        int callingUid;
17387        int callingPid;
17388        synchronized(this) {
17389            if (caller != null) {
17390                callerApp = getRecordForAppLocked(caller);
17391                if (callerApp == null) {
17392                    throw new SecurityException(
17393                            "Unable to find app for caller " + caller
17394                            + " (pid=" + Binder.getCallingPid()
17395                            + ") when registering receiver " + receiver);
17396                }
17397                if (callerApp.info.uid != Process.SYSTEM_UID &&
17398                        !callerApp.pkgList.containsKey(callerPackage) &&
17399                        !"android".equals(callerPackage)) {
17400                    throw new SecurityException("Given caller package " + callerPackage
17401                            + " is not running in process " + callerApp);
17402                }
17403                callingUid = callerApp.info.uid;
17404                callingPid = callerApp.pid;
17405            } else {
17406                callerPackage = null;
17407                callingUid = Binder.getCallingUid();
17408                callingPid = Binder.getCallingPid();
17409            }
17410
17411            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17412                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17413
17414            Iterator<String> actions = filter.actionsIterator();
17415            if (actions == null) {
17416                ArrayList<String> noAction = new ArrayList<String>(1);
17417                noAction.add(null);
17418                actions = noAction.iterator();
17419            }
17420
17421            // Collect stickies of users
17422            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17423            while (actions.hasNext()) {
17424                String action = actions.next();
17425                for (int id : userIds) {
17426                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17427                    if (stickies != null) {
17428                        ArrayList<Intent> intents = stickies.get(action);
17429                        if (intents != null) {
17430                            if (stickyIntents == null) {
17431                                stickyIntents = new ArrayList<Intent>();
17432                            }
17433                            stickyIntents.addAll(intents);
17434                        }
17435                    }
17436                }
17437            }
17438        }
17439
17440        ArrayList<Intent> allSticky = null;
17441        if (stickyIntents != null) {
17442            final ContentResolver resolver = mContext.getContentResolver();
17443            // Look for any matching sticky broadcasts...
17444            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17445                Intent intent = stickyIntents.get(i);
17446                // If intent has scheme "content", it will need to acccess
17447                // provider that needs to lock mProviderMap in ActivityThread
17448                // and also it may need to wait application response, so we
17449                // cannot lock ActivityManagerService here.
17450                if (filter.match(resolver, intent, true, TAG) >= 0) {
17451                    if (allSticky == null) {
17452                        allSticky = new ArrayList<Intent>();
17453                    }
17454                    allSticky.add(intent);
17455                }
17456            }
17457        }
17458
17459        // The first sticky in the list is returned directly back to the client.
17460        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17461        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17462        if (receiver == null) {
17463            return sticky;
17464        }
17465
17466        synchronized (this) {
17467            if (callerApp != null && (callerApp.thread == null
17468                    || callerApp.thread.asBinder() != caller.asBinder())) {
17469                // Original caller already died
17470                return null;
17471            }
17472            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17473            if (rl == null) {
17474                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17475                        userId, receiver);
17476                if (rl.app != null) {
17477                    rl.app.receivers.add(rl);
17478                } else {
17479                    try {
17480                        receiver.asBinder().linkToDeath(rl, 0);
17481                    } catch (RemoteException e) {
17482                        return sticky;
17483                    }
17484                    rl.linkedToDeath = true;
17485                }
17486                mRegisteredReceivers.put(receiver.asBinder(), rl);
17487            } else if (rl.uid != callingUid) {
17488                throw new IllegalArgumentException(
17489                        "Receiver requested to register for uid " + callingUid
17490                        + " was previously registered for uid " + rl.uid);
17491            } else if (rl.pid != callingPid) {
17492                throw new IllegalArgumentException(
17493                        "Receiver requested to register for pid " + callingPid
17494                        + " was previously registered for pid " + rl.pid);
17495            } else if (rl.userId != userId) {
17496                throw new IllegalArgumentException(
17497                        "Receiver requested to register for user " + userId
17498                        + " was previously registered for user " + rl.userId);
17499            }
17500            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17501                    permission, callingUid, userId);
17502            rl.add(bf);
17503            if (!bf.debugCheck()) {
17504                Slog.w(TAG, "==> For Dynamic broadcast");
17505            }
17506            mReceiverResolver.addFilter(bf);
17507
17508            // Enqueue broadcasts for all existing stickies that match
17509            // this filter.
17510            if (allSticky != null) {
17511                ArrayList receivers = new ArrayList();
17512                receivers.add(bf);
17513
17514                final int stickyCount = allSticky.size();
17515                for (int i = 0; i < stickyCount; i++) {
17516                    Intent intent = allSticky.get(i);
17517                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17518                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17519                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17520                            null, 0, null, null, false, true, true, -1);
17521                    queue.enqueueParallelBroadcastLocked(r);
17522                    queue.scheduleBroadcastsLocked();
17523                }
17524            }
17525
17526            return sticky;
17527        }
17528    }
17529
17530    public void unregisterReceiver(IIntentReceiver receiver) {
17531        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17532
17533        final long origId = Binder.clearCallingIdentity();
17534        try {
17535            boolean doTrim = false;
17536
17537            synchronized(this) {
17538                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17539                if (rl != null) {
17540                    final BroadcastRecord r = rl.curBroadcast;
17541                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17542                        final boolean doNext = r.queue.finishReceiverLocked(
17543                                r, r.resultCode, r.resultData, r.resultExtras,
17544                                r.resultAbort, false);
17545                        if (doNext) {
17546                            doTrim = true;
17547                            r.queue.processNextBroadcast(false);
17548                        }
17549                    }
17550
17551                    if (rl.app != null) {
17552                        rl.app.receivers.remove(rl);
17553                    }
17554                    removeReceiverLocked(rl);
17555                    if (rl.linkedToDeath) {
17556                        rl.linkedToDeath = false;
17557                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17558                    }
17559                }
17560            }
17561
17562            // If we actually concluded any broadcasts, we might now be able
17563            // to trim the recipients' apps from our working set
17564            if (doTrim) {
17565                trimApplications();
17566                return;
17567            }
17568
17569        } finally {
17570            Binder.restoreCallingIdentity(origId);
17571        }
17572    }
17573
17574    void removeReceiverLocked(ReceiverList rl) {
17575        mRegisteredReceivers.remove(rl.receiver.asBinder());
17576        for (int i = rl.size() - 1; i >= 0; i--) {
17577            mReceiverResolver.removeFilter(rl.get(i));
17578        }
17579    }
17580
17581    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17582        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17583            ProcessRecord r = mLruProcesses.get(i);
17584            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17585                try {
17586                    r.thread.dispatchPackageBroadcast(cmd, packages);
17587                } catch (RemoteException ex) {
17588                }
17589            }
17590        }
17591    }
17592
17593    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17594            int callingUid, int[] users) {
17595        // TODO: come back and remove this assumption to triage all broadcasts
17596        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17597
17598        List<ResolveInfo> receivers = null;
17599        try {
17600            HashSet<ComponentName> singleUserReceivers = null;
17601            boolean scannedFirstReceivers = false;
17602            for (int user : users) {
17603                // Skip users that have Shell restrictions, with exception of always permitted
17604                // Shell broadcasts
17605                if (callingUid == Process.SHELL_UID
17606                        && mUserController.hasUserRestriction(
17607                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17608                        && !isPermittedShellBroadcast(intent)) {
17609                    continue;
17610                }
17611                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17612                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17613                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17614                    // If this is not the system user, we need to check for
17615                    // any receivers that should be filtered out.
17616                    for (int i=0; i<newReceivers.size(); i++) {
17617                        ResolveInfo ri = newReceivers.get(i);
17618                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17619                            newReceivers.remove(i);
17620                            i--;
17621                        }
17622                    }
17623                }
17624                if (newReceivers != null && newReceivers.size() == 0) {
17625                    newReceivers = null;
17626                }
17627                if (receivers == null) {
17628                    receivers = newReceivers;
17629                } else if (newReceivers != null) {
17630                    // We need to concatenate the additional receivers
17631                    // found with what we have do far.  This would be easy,
17632                    // but we also need to de-dup any receivers that are
17633                    // singleUser.
17634                    if (!scannedFirstReceivers) {
17635                        // Collect any single user receivers we had already retrieved.
17636                        scannedFirstReceivers = true;
17637                        for (int i=0; i<receivers.size(); i++) {
17638                            ResolveInfo ri = receivers.get(i);
17639                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17640                                ComponentName cn = new ComponentName(
17641                                        ri.activityInfo.packageName, ri.activityInfo.name);
17642                                if (singleUserReceivers == null) {
17643                                    singleUserReceivers = new HashSet<ComponentName>();
17644                                }
17645                                singleUserReceivers.add(cn);
17646                            }
17647                        }
17648                    }
17649                    // Add the new results to the existing results, tracking
17650                    // and de-dupping single user receivers.
17651                    for (int i=0; i<newReceivers.size(); i++) {
17652                        ResolveInfo ri = newReceivers.get(i);
17653                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17654                            ComponentName cn = new ComponentName(
17655                                    ri.activityInfo.packageName, ri.activityInfo.name);
17656                            if (singleUserReceivers == null) {
17657                                singleUserReceivers = new HashSet<ComponentName>();
17658                            }
17659                            if (!singleUserReceivers.contains(cn)) {
17660                                singleUserReceivers.add(cn);
17661                                receivers.add(ri);
17662                            }
17663                        } else {
17664                            receivers.add(ri);
17665                        }
17666                    }
17667                }
17668            }
17669        } catch (RemoteException ex) {
17670            // pm is in same process, this will never happen.
17671        }
17672        return receivers;
17673    }
17674
17675    private boolean isPermittedShellBroadcast(Intent intent) {
17676        // remote bugreport should always be allowed to be taken
17677        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17678    }
17679
17680    final int broadcastIntentLocked(ProcessRecord callerApp,
17681            String callerPackage, Intent intent, String resolvedType,
17682            IIntentReceiver resultTo, int resultCode, String resultData,
17683            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17684            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17685        intent = new Intent(intent);
17686
17687        // By default broadcasts do not go to stopped apps.
17688        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17689
17690        // If we have not finished booting, don't allow this to launch new processes.
17691        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17692            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17693        }
17694
17695        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17696                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17697                + " ordered=" + ordered + " userid=" + userId);
17698        if ((resultTo != null) && !ordered) {
17699            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17700        }
17701
17702        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17703                ALLOW_NON_FULL, "broadcast", callerPackage);
17704
17705        // Make sure that the user who is receiving this broadcast is running.
17706        // If not, we will just skip it. Make an exception for shutdown broadcasts
17707        // and upgrade steps.
17708
17709        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17710            if ((callingUid != Process.SYSTEM_UID
17711                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17712                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17713                Slog.w(TAG, "Skipping broadcast of " + intent
17714                        + ": user " + userId + " is stopped");
17715                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17716            }
17717        }
17718
17719        BroadcastOptions brOptions = null;
17720        if (bOptions != null) {
17721            brOptions = new BroadcastOptions(bOptions);
17722            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17723                // See if the caller is allowed to do this.  Note we are checking against
17724                // the actual real caller (not whoever provided the operation as say a
17725                // PendingIntent), because that who is actually supplied the arguments.
17726                if (checkComponentPermission(
17727                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17728                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17729                        != PackageManager.PERMISSION_GRANTED) {
17730                    String msg = "Permission Denial: " + intent.getAction()
17731                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17732                            + ", uid=" + callingUid + ")"
17733                            + " requires "
17734                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17735                    Slog.w(TAG, msg);
17736                    throw new SecurityException(msg);
17737                }
17738            }
17739        }
17740
17741        // Verify that protected broadcasts are only being sent by system code,
17742        // and that system code is only sending protected broadcasts.
17743        final String action = intent.getAction();
17744        final boolean isProtectedBroadcast;
17745        try {
17746            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17747        } catch (RemoteException e) {
17748            Slog.w(TAG, "Remote exception", e);
17749            return ActivityManager.BROADCAST_SUCCESS;
17750        }
17751
17752        final boolean isCallerSystem;
17753        switch (UserHandle.getAppId(callingUid)) {
17754            case Process.ROOT_UID:
17755            case Process.SYSTEM_UID:
17756            case Process.PHONE_UID:
17757            case Process.BLUETOOTH_UID:
17758            case Process.NFC_UID:
17759                isCallerSystem = true;
17760                break;
17761            default:
17762                isCallerSystem = (callerApp != null) && callerApp.persistent;
17763                break;
17764        }
17765
17766        if (isCallerSystem) {
17767            if (isProtectedBroadcast
17768                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17769                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17770                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17771                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17772                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17773                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17774                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17775                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17776                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17777                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17778                // Broadcast is either protected, or it's a public action that
17779                // we've relaxed, so it's fine for system internals to send.
17780            } else {
17781                // The vast majority of broadcasts sent from system internals
17782                // should be protected to avoid security holes, so yell loudly
17783                // to ensure we examine these cases.
17784                if (callerApp != null) {
17785                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17786                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17787                            new Throwable());
17788                } else {
17789                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17790                            + " from system uid " + UserHandle.formatUid(callingUid)
17791                            + " pkg " + callerPackage,
17792                            new Throwable());
17793                }
17794            }
17795
17796        } else {
17797            if (isProtectedBroadcast) {
17798                String msg = "Permission Denial: not allowed to send broadcast "
17799                        + action + " from pid="
17800                        + callingPid + ", uid=" + callingUid;
17801                Slog.w(TAG, msg);
17802                throw new SecurityException(msg);
17803
17804            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17805                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17806                // Special case for compatibility: we don't want apps to send this,
17807                // but historically it has not been protected and apps may be using it
17808                // to poke their own app widget.  So, instead of making it protected,
17809                // just limit it to the caller.
17810                if (callerPackage == null) {
17811                    String msg = "Permission Denial: not allowed to send broadcast "
17812                            + action + " from unknown caller.";
17813                    Slog.w(TAG, msg);
17814                    throw new SecurityException(msg);
17815                } else if (intent.getComponent() != null) {
17816                    // They are good enough to send to an explicit component...  verify
17817                    // it is being sent to the calling app.
17818                    if (!intent.getComponent().getPackageName().equals(
17819                            callerPackage)) {
17820                        String msg = "Permission Denial: not allowed to send broadcast "
17821                                + action + " to "
17822                                + intent.getComponent().getPackageName() + " from "
17823                                + callerPackage;
17824                        Slog.w(TAG, msg);
17825                        throw new SecurityException(msg);
17826                    }
17827                } else {
17828                    // Limit broadcast to their own package.
17829                    intent.setPackage(callerPackage);
17830                }
17831            }
17832        }
17833
17834        if (action != null) {
17835            switch (action) {
17836                case Intent.ACTION_UID_REMOVED:
17837                case Intent.ACTION_PACKAGE_REMOVED:
17838                case Intent.ACTION_PACKAGE_CHANGED:
17839                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17840                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17841                case Intent.ACTION_PACKAGES_SUSPENDED:
17842                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17843                    // Handle special intents: if this broadcast is from the package
17844                    // manager about a package being removed, we need to remove all of
17845                    // its activities from the history stack.
17846                    if (checkComponentPermission(
17847                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17848                            callingPid, callingUid, -1, true)
17849                            != PackageManager.PERMISSION_GRANTED) {
17850                        String msg = "Permission Denial: " + intent.getAction()
17851                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17852                                + ", uid=" + callingUid + ")"
17853                                + " requires "
17854                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17855                        Slog.w(TAG, msg);
17856                        throw new SecurityException(msg);
17857                    }
17858                    switch (action) {
17859                        case Intent.ACTION_UID_REMOVED:
17860                            final Bundle intentExtras = intent.getExtras();
17861                            final int uid = intentExtras != null
17862                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17863                            if (uid >= 0) {
17864                                mBatteryStatsService.removeUid(uid);
17865                                mAppOpsService.uidRemoved(uid);
17866                            }
17867                            break;
17868                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17869                            // If resources are unavailable just force stop all those packages
17870                            // and flush the attribute cache as well.
17871                            String list[] =
17872                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17873                            if (list != null && list.length > 0) {
17874                                for (int i = 0; i < list.length; i++) {
17875                                    forceStopPackageLocked(list[i], -1, false, true, true,
17876                                            false, false, userId, "storage unmount");
17877                                }
17878                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17879                                sendPackageBroadcastLocked(
17880                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17881                                        userId);
17882                            }
17883                            break;
17884                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17885                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17886                            break;
17887                        case Intent.ACTION_PACKAGE_REMOVED:
17888                        case Intent.ACTION_PACKAGE_CHANGED:
17889                            Uri data = intent.getData();
17890                            String ssp;
17891                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17892                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17893                                final boolean replacing =
17894                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17895                                final boolean killProcess =
17896                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17897                                final boolean fullUninstall = removed && !replacing;
17898                                if (removed) {
17899                                    if (killProcess) {
17900                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17901                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17902                                                false, true, true, false, fullUninstall, userId,
17903                                                removed ? "pkg removed" : "pkg changed");
17904                                    }
17905                                    final int cmd = killProcess
17906                                            ? IApplicationThread.PACKAGE_REMOVED
17907                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17908                                    sendPackageBroadcastLocked(cmd,
17909                                            new String[] {ssp}, userId);
17910                                    if (fullUninstall) {
17911                                        mAppOpsService.packageRemoved(
17912                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17913
17914                                        // Remove all permissions granted from/to this package
17915                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17916
17917                                        removeTasksByPackageNameLocked(ssp, userId);
17918
17919                                        // Hide the "unsupported display" dialog if necessary.
17920                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17921                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17922                                            mUnsupportedDisplaySizeDialog.dismiss();
17923                                            mUnsupportedDisplaySizeDialog = null;
17924                                        }
17925                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17926                                        mBatteryStatsService.notePackageUninstalled(ssp);
17927                                    }
17928                                } else {
17929                                    if (killProcess) {
17930                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17931                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17932                                                userId, ProcessList.INVALID_ADJ,
17933                                                false, true, true, false, "change " + ssp);
17934                                    }
17935                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17936                                            intent.getStringArrayExtra(
17937                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17938                                }
17939                            }
17940                            break;
17941                        case Intent.ACTION_PACKAGES_SUSPENDED:
17942                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17943                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17944                                    intent.getAction());
17945                            final String[] packageNames = intent.getStringArrayExtra(
17946                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17947                            final int userHandle = intent.getIntExtra(
17948                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17949
17950                            synchronized(ActivityManagerService.this) {
17951                                mRecentTasks.onPackagesSuspendedChanged(
17952                                        packageNames, suspended, userHandle);
17953                            }
17954                            break;
17955                    }
17956                    break;
17957                case Intent.ACTION_PACKAGE_REPLACED:
17958                {
17959                    final Uri data = intent.getData();
17960                    final String ssp;
17961                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17962                        final ApplicationInfo aInfo =
17963                                getPackageManagerInternalLocked().getApplicationInfo(
17964                                        ssp,
17965                                        userId);
17966                        if (aInfo == null) {
17967                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17968                                    + " ssp=" + ssp + " data=" + data);
17969                            return ActivityManager.BROADCAST_SUCCESS;
17970                        }
17971                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17972                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17973                                new String[] {ssp}, userId);
17974                    }
17975                    break;
17976                }
17977                case Intent.ACTION_PACKAGE_ADDED:
17978                {
17979                    // Special case for adding a package: by default turn on compatibility mode.
17980                    Uri data = intent.getData();
17981                    String ssp;
17982                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17983                        final boolean replacing =
17984                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17985                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17986
17987                        try {
17988                            ApplicationInfo ai = AppGlobals.getPackageManager().
17989                                    getApplicationInfo(ssp, 0, 0);
17990                            mBatteryStatsService.notePackageInstalled(ssp,
17991                                    ai != null ? ai.versionCode : 0);
17992                        } catch (RemoteException e) {
17993                        }
17994                    }
17995                    break;
17996                }
17997                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17998                {
17999                    Uri data = intent.getData();
18000                    String ssp;
18001                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18002                        // Hide the "unsupported display" dialog if necessary.
18003                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18004                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18005                            mUnsupportedDisplaySizeDialog.dismiss();
18006                            mUnsupportedDisplaySizeDialog = null;
18007                        }
18008                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18009                    }
18010                    break;
18011                }
18012                case Intent.ACTION_TIMEZONE_CHANGED:
18013                    // If this is the time zone changed action, queue up a message that will reset
18014                    // the timezone of all currently running processes. This message will get
18015                    // queued up before the broadcast happens.
18016                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18017                    break;
18018                case Intent.ACTION_TIME_CHANGED:
18019                    // If the user set the time, let all running processes know.
18020                    final int is24Hour =
18021                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18022                                    : 0;
18023                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18024                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18025                    synchronized (stats) {
18026                        stats.noteCurrentTimeChangedLocked();
18027                    }
18028                    break;
18029                case Intent.ACTION_CLEAR_DNS_CACHE:
18030                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18031                    break;
18032                case Proxy.PROXY_CHANGE_ACTION:
18033                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18034                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18035                    break;
18036                case android.hardware.Camera.ACTION_NEW_PICTURE:
18037                case android.hardware.Camera.ACTION_NEW_VIDEO:
18038                    // These broadcasts are no longer allowed by the system, since they can
18039                    // cause significant thrashing at a crictical point (using the camera).
18040                    // Apps should use JobScehduler to monitor for media provider changes.
18041                    Slog.w(TAG, action + " no longer allowed; dropping from "
18042                            + UserHandle.formatUid(callingUid));
18043                    if (resultTo != null) {
18044                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18045                        try {
18046                            queue.performReceiveLocked(callerApp, resultTo, intent,
18047                                    Activity.RESULT_CANCELED, null, null,
18048                                    false, false, userId);
18049                        } catch (RemoteException e) {
18050                            Slog.w(TAG, "Failure ["
18051                                    + queue.mQueueName + "] sending broadcast result of "
18052                                    + intent, e);
18053
18054                        }
18055                    }
18056                    // Lie; we don't want to crash the app.
18057                    return ActivityManager.BROADCAST_SUCCESS;
18058            }
18059        }
18060
18061        // Add to the sticky list if requested.
18062        if (sticky) {
18063            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18064                    callingPid, callingUid)
18065                    != PackageManager.PERMISSION_GRANTED) {
18066                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18067                        + callingPid + ", uid=" + callingUid
18068                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18069                Slog.w(TAG, msg);
18070                throw new SecurityException(msg);
18071            }
18072            if (requiredPermissions != null && requiredPermissions.length > 0) {
18073                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18074                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18075                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18076            }
18077            if (intent.getComponent() != null) {
18078                throw new SecurityException(
18079                        "Sticky broadcasts can't target a specific component");
18080            }
18081            // We use userId directly here, since the "all" target is maintained
18082            // as a separate set of sticky broadcasts.
18083            if (userId != UserHandle.USER_ALL) {
18084                // But first, if this is not a broadcast to all users, then
18085                // make sure it doesn't conflict with an existing broadcast to
18086                // all users.
18087                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18088                        UserHandle.USER_ALL);
18089                if (stickies != null) {
18090                    ArrayList<Intent> list = stickies.get(intent.getAction());
18091                    if (list != null) {
18092                        int N = list.size();
18093                        int i;
18094                        for (i=0; i<N; i++) {
18095                            if (intent.filterEquals(list.get(i))) {
18096                                throw new IllegalArgumentException(
18097                                        "Sticky broadcast " + intent + " for user "
18098                                        + userId + " conflicts with existing global broadcast");
18099                            }
18100                        }
18101                    }
18102                }
18103            }
18104            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18105            if (stickies == null) {
18106                stickies = new ArrayMap<>();
18107                mStickyBroadcasts.put(userId, stickies);
18108            }
18109            ArrayList<Intent> list = stickies.get(intent.getAction());
18110            if (list == null) {
18111                list = new ArrayList<>();
18112                stickies.put(intent.getAction(), list);
18113            }
18114            final int stickiesCount = list.size();
18115            int i;
18116            for (i = 0; i < stickiesCount; i++) {
18117                if (intent.filterEquals(list.get(i))) {
18118                    // This sticky already exists, replace it.
18119                    list.set(i, new Intent(intent));
18120                    break;
18121                }
18122            }
18123            if (i >= stickiesCount) {
18124                list.add(new Intent(intent));
18125            }
18126        }
18127
18128        int[] users;
18129        if (userId == UserHandle.USER_ALL) {
18130            // Caller wants broadcast to go to all started users.
18131            users = mUserController.getStartedUserArrayLocked();
18132        } else {
18133            // Caller wants broadcast to go to one specific user.
18134            users = new int[] {userId};
18135        }
18136
18137        // Figure out who all will receive this broadcast.
18138        List receivers = null;
18139        List<BroadcastFilter> registeredReceivers = null;
18140        // Need to resolve the intent to interested receivers...
18141        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18142                 == 0) {
18143            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18144        }
18145        if (intent.getComponent() == null) {
18146            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18147                // Query one target user at a time, excluding shell-restricted users
18148                for (int i = 0; i < users.length; i++) {
18149                    if (mUserController.hasUserRestriction(
18150                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18151                        continue;
18152                    }
18153                    List<BroadcastFilter> registeredReceiversForUser =
18154                            mReceiverResolver.queryIntent(intent,
18155                                    resolvedType, false, users[i]);
18156                    if (registeredReceivers == null) {
18157                        registeredReceivers = registeredReceiversForUser;
18158                    } else if (registeredReceiversForUser != null) {
18159                        registeredReceivers.addAll(registeredReceiversForUser);
18160                    }
18161                }
18162            } else {
18163                registeredReceivers = mReceiverResolver.queryIntent(intent,
18164                        resolvedType, false, userId);
18165            }
18166        }
18167
18168        final boolean replacePending =
18169                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18170
18171        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18172                + " replacePending=" + replacePending);
18173
18174        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18175        if (!ordered && NR > 0) {
18176            // If we are not serializing this broadcast, then send the
18177            // registered receivers separately so they don't wait for the
18178            // components to be launched.
18179            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18180            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18181                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18182                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18183                    resultExtras, ordered, sticky, false, userId);
18184            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18185            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18186            if (!replaced) {
18187                queue.enqueueParallelBroadcastLocked(r);
18188                queue.scheduleBroadcastsLocked();
18189            }
18190            registeredReceivers = null;
18191            NR = 0;
18192        }
18193
18194        // Merge into one list.
18195        int ir = 0;
18196        if (receivers != null) {
18197            // A special case for PACKAGE_ADDED: do not allow the package
18198            // being added to see this broadcast.  This prevents them from
18199            // using this as a back door to get run as soon as they are
18200            // installed.  Maybe in the future we want to have a special install
18201            // broadcast or such for apps, but we'd like to deliberately make
18202            // this decision.
18203            String skipPackages[] = null;
18204            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18205                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18206                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18207                Uri data = intent.getData();
18208                if (data != null) {
18209                    String pkgName = data.getSchemeSpecificPart();
18210                    if (pkgName != null) {
18211                        skipPackages = new String[] { pkgName };
18212                    }
18213                }
18214            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18215                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18216            }
18217            if (skipPackages != null && (skipPackages.length > 0)) {
18218                for (String skipPackage : skipPackages) {
18219                    if (skipPackage != null) {
18220                        int NT = receivers.size();
18221                        for (int it=0; it<NT; it++) {
18222                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18223                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18224                                receivers.remove(it);
18225                                it--;
18226                                NT--;
18227                            }
18228                        }
18229                    }
18230                }
18231            }
18232
18233            int NT = receivers != null ? receivers.size() : 0;
18234            int it = 0;
18235            ResolveInfo curt = null;
18236            BroadcastFilter curr = null;
18237            while (it < NT && ir < NR) {
18238                if (curt == null) {
18239                    curt = (ResolveInfo)receivers.get(it);
18240                }
18241                if (curr == null) {
18242                    curr = registeredReceivers.get(ir);
18243                }
18244                if (curr.getPriority() >= curt.priority) {
18245                    // Insert this broadcast record into the final list.
18246                    receivers.add(it, curr);
18247                    ir++;
18248                    curr = null;
18249                    it++;
18250                    NT++;
18251                } else {
18252                    // Skip to the next ResolveInfo in the final list.
18253                    it++;
18254                    curt = null;
18255                }
18256            }
18257        }
18258        while (ir < NR) {
18259            if (receivers == null) {
18260                receivers = new ArrayList();
18261            }
18262            receivers.add(registeredReceivers.get(ir));
18263            ir++;
18264        }
18265
18266        if ((receivers != null && receivers.size() > 0)
18267                || resultTo != null) {
18268            BroadcastQueue queue = broadcastQueueForIntent(intent);
18269            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18270                    callerPackage, callingPid, callingUid, resolvedType,
18271                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18272                    resultData, resultExtras, ordered, sticky, false, userId);
18273
18274            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18275                    + ": prev had " + queue.mOrderedBroadcasts.size());
18276            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18277                    "Enqueueing broadcast " + r.intent.getAction());
18278
18279            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18280            if (!replaced) {
18281                queue.enqueueOrderedBroadcastLocked(r);
18282                queue.scheduleBroadcastsLocked();
18283            }
18284        } else {
18285            // There was nobody interested in the broadcast, but we still want to record
18286            // that it happened.
18287            if (intent.getComponent() == null && intent.getPackage() == null
18288                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18289                // This was an implicit broadcast... let's record it for posterity.
18290                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18291            }
18292        }
18293
18294        return ActivityManager.BROADCAST_SUCCESS;
18295    }
18296
18297    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18298            int skipCount, long dispatchTime) {
18299        final long now = SystemClock.elapsedRealtime();
18300        if (mCurBroadcastStats == null ||
18301                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18302            mLastBroadcastStats = mCurBroadcastStats;
18303            if (mLastBroadcastStats != null) {
18304                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18305                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18306            }
18307            mCurBroadcastStats = new BroadcastStats();
18308        }
18309        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18310    }
18311
18312    final Intent verifyBroadcastLocked(Intent intent) {
18313        // Refuse possible leaked file descriptors
18314        if (intent != null && intent.hasFileDescriptors() == true) {
18315            throw new IllegalArgumentException("File descriptors passed in Intent");
18316        }
18317
18318        int flags = intent.getFlags();
18319
18320        if (!mProcessesReady) {
18321            // if the caller really truly claims to know what they're doing, go
18322            // ahead and allow the broadcast without launching any receivers
18323            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18324                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18325            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18326                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18327                        + " before boot completion");
18328                throw new IllegalStateException("Cannot broadcast before boot completed");
18329            }
18330        }
18331
18332        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18333            throw new IllegalArgumentException(
18334                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18335        }
18336
18337        return intent;
18338    }
18339
18340    public final int broadcastIntent(IApplicationThread caller,
18341            Intent intent, String resolvedType, IIntentReceiver resultTo,
18342            int resultCode, String resultData, Bundle resultExtras,
18343            String[] requiredPermissions, int appOp, Bundle bOptions,
18344            boolean serialized, boolean sticky, int userId) {
18345        enforceNotIsolatedCaller("broadcastIntent");
18346        synchronized(this) {
18347            intent = verifyBroadcastLocked(intent);
18348
18349            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18350            final int callingPid = Binder.getCallingPid();
18351            final int callingUid = Binder.getCallingUid();
18352            final long origId = Binder.clearCallingIdentity();
18353            int res = broadcastIntentLocked(callerApp,
18354                    callerApp != null ? callerApp.info.packageName : null,
18355                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18356                    requiredPermissions, appOp, bOptions, serialized, sticky,
18357                    callingPid, callingUid, userId);
18358            Binder.restoreCallingIdentity(origId);
18359            return res;
18360        }
18361    }
18362
18363
18364    int broadcastIntentInPackage(String packageName, int uid,
18365            Intent intent, String resolvedType, IIntentReceiver resultTo,
18366            int resultCode, String resultData, Bundle resultExtras,
18367            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18368            int userId) {
18369        synchronized(this) {
18370            intent = verifyBroadcastLocked(intent);
18371
18372            final long origId = Binder.clearCallingIdentity();
18373            String[] requiredPermissions = requiredPermission == null ? null
18374                    : new String[] {requiredPermission};
18375            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18376                    resultTo, resultCode, resultData, resultExtras,
18377                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18378                    sticky, -1, uid, userId);
18379            Binder.restoreCallingIdentity(origId);
18380            return res;
18381        }
18382    }
18383
18384    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18385        // Refuse possible leaked file descriptors
18386        if (intent != null && intent.hasFileDescriptors() == true) {
18387            throw new IllegalArgumentException("File descriptors passed in Intent");
18388        }
18389
18390        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18391                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18392
18393        synchronized(this) {
18394            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18395                    != PackageManager.PERMISSION_GRANTED) {
18396                String msg = "Permission Denial: unbroadcastIntent() from pid="
18397                        + Binder.getCallingPid()
18398                        + ", uid=" + Binder.getCallingUid()
18399                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18400                Slog.w(TAG, msg);
18401                throw new SecurityException(msg);
18402            }
18403            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18404            if (stickies != null) {
18405                ArrayList<Intent> list = stickies.get(intent.getAction());
18406                if (list != null) {
18407                    int N = list.size();
18408                    int i;
18409                    for (i=0; i<N; i++) {
18410                        if (intent.filterEquals(list.get(i))) {
18411                            list.remove(i);
18412                            break;
18413                        }
18414                    }
18415                    if (list.size() <= 0) {
18416                        stickies.remove(intent.getAction());
18417                    }
18418                }
18419                if (stickies.size() <= 0) {
18420                    mStickyBroadcasts.remove(userId);
18421                }
18422            }
18423        }
18424    }
18425
18426    void backgroundServicesFinishedLocked(int userId) {
18427        for (BroadcastQueue queue : mBroadcastQueues) {
18428            queue.backgroundServicesFinishedLocked(userId);
18429        }
18430    }
18431
18432    public void finishReceiver(IBinder who, int resultCode, String resultData,
18433            Bundle resultExtras, boolean resultAbort, int flags) {
18434        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18435
18436        // Refuse possible leaked file descriptors
18437        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18438            throw new IllegalArgumentException("File descriptors passed in Bundle");
18439        }
18440
18441        final long origId = Binder.clearCallingIdentity();
18442        try {
18443            boolean doNext = false;
18444            BroadcastRecord r;
18445
18446            synchronized(this) {
18447                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18448                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18449                r = queue.getMatchingOrderedReceiver(who);
18450                if (r != null) {
18451                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18452                        resultData, resultExtras, resultAbort, true);
18453                }
18454            }
18455
18456            if (doNext) {
18457                r.queue.processNextBroadcast(false);
18458            }
18459            trimApplications();
18460        } finally {
18461            Binder.restoreCallingIdentity(origId);
18462        }
18463    }
18464
18465    // =========================================================
18466    // INSTRUMENTATION
18467    // =========================================================
18468
18469    public boolean startInstrumentation(ComponentName className,
18470            String profileFile, int flags, Bundle arguments,
18471            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18472            int userId, String abiOverride) {
18473        enforceNotIsolatedCaller("startInstrumentation");
18474        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18475                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18476        // Refuse possible leaked file descriptors
18477        if (arguments != null && arguments.hasFileDescriptors()) {
18478            throw new IllegalArgumentException("File descriptors passed in Bundle");
18479        }
18480
18481        synchronized(this) {
18482            InstrumentationInfo ii = null;
18483            ApplicationInfo ai = null;
18484            try {
18485                ii = mContext.getPackageManager().getInstrumentationInfo(
18486                    className, STOCK_PM_FLAGS);
18487                ai = AppGlobals.getPackageManager().getApplicationInfo(
18488                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18489            } catch (PackageManager.NameNotFoundException e) {
18490            } catch (RemoteException e) {
18491            }
18492            if (ii == null) {
18493                reportStartInstrumentationFailureLocked(watcher, className,
18494                        "Unable to find instrumentation info for: " + className);
18495                return false;
18496            }
18497            if (ai == null) {
18498                reportStartInstrumentationFailureLocked(watcher, className,
18499                        "Unable to find instrumentation target package: " + ii.targetPackage);
18500                return false;
18501            }
18502            if (!ai.hasCode()) {
18503                reportStartInstrumentationFailureLocked(watcher, className,
18504                        "Instrumentation target has no code: " + ii.targetPackage);
18505                return false;
18506            }
18507
18508            int match = mContext.getPackageManager().checkSignatures(
18509                    ii.targetPackage, ii.packageName);
18510            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18511                String msg = "Permission Denial: starting instrumentation "
18512                        + className + " from pid="
18513                        + Binder.getCallingPid()
18514                        + ", uid=" + Binder.getCallingPid()
18515                        + " not allowed because package " + ii.packageName
18516                        + " does not have a signature matching the target "
18517                        + ii.targetPackage;
18518                reportStartInstrumentationFailureLocked(watcher, className, msg);
18519                throw new SecurityException(msg);
18520            }
18521
18522            final long origId = Binder.clearCallingIdentity();
18523            // Instrumentation can kill and relaunch even persistent processes
18524            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18525                    "start instr");
18526            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18527            app.instrumentationClass = className;
18528            app.instrumentationInfo = ai;
18529            app.instrumentationProfileFile = profileFile;
18530            app.instrumentationArguments = arguments;
18531            app.instrumentationWatcher = watcher;
18532            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18533            app.instrumentationResultClass = className;
18534            Binder.restoreCallingIdentity(origId);
18535        }
18536
18537        return true;
18538    }
18539
18540    /**
18541     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18542     * error to the logs, but if somebody is watching, send the report there too.  This enables
18543     * the "am" command to report errors with more information.
18544     *
18545     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18546     * @param cn The component name of the instrumentation.
18547     * @param report The error report.
18548     */
18549    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18550            ComponentName cn, String report) {
18551        Slog.w(TAG, report);
18552        if (watcher != null) {
18553            Bundle results = new Bundle();
18554            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18555            results.putString("Error", report);
18556            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18557        }
18558    }
18559
18560    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18561        if (app.instrumentationWatcher != null) {
18562            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18563                    app.instrumentationClass, resultCode, results);
18564        }
18565
18566        // Can't call out of the system process with a lock held, so post a message.
18567        if (app.instrumentationUiAutomationConnection != null) {
18568            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18569                    app.instrumentationUiAutomationConnection).sendToTarget();
18570        }
18571
18572        app.instrumentationWatcher = null;
18573        app.instrumentationUiAutomationConnection = null;
18574        app.instrumentationClass = null;
18575        app.instrumentationInfo = null;
18576        app.instrumentationProfileFile = null;
18577        app.instrumentationArguments = null;
18578
18579        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18580                "finished inst");
18581    }
18582
18583    public void finishInstrumentation(IApplicationThread target,
18584            int resultCode, Bundle results) {
18585        int userId = UserHandle.getCallingUserId();
18586        // Refuse possible leaked file descriptors
18587        if (results != null && results.hasFileDescriptors()) {
18588            throw new IllegalArgumentException("File descriptors passed in Intent");
18589        }
18590
18591        synchronized(this) {
18592            ProcessRecord app = getRecordForAppLocked(target);
18593            if (app == null) {
18594                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18595                return;
18596            }
18597            final long origId = Binder.clearCallingIdentity();
18598            finishInstrumentationLocked(app, resultCode, results);
18599            Binder.restoreCallingIdentity(origId);
18600        }
18601    }
18602
18603    // =========================================================
18604    // CONFIGURATION
18605    // =========================================================
18606
18607    public ConfigurationInfo getDeviceConfigurationInfo() {
18608        ConfigurationInfo config = new ConfigurationInfo();
18609        synchronized (this) {
18610            config.reqTouchScreen = mConfiguration.touchscreen;
18611            config.reqKeyboardType = mConfiguration.keyboard;
18612            config.reqNavigation = mConfiguration.navigation;
18613            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18614                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18615                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18616            }
18617            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18618                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18619                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18620            }
18621            config.reqGlEsVersion = GL_ES_VERSION;
18622        }
18623        return config;
18624    }
18625
18626    ActivityStack getFocusedStack() {
18627        return mStackSupervisor.getFocusedStack();
18628    }
18629
18630    @Override
18631    public int getFocusedStackId() throws RemoteException {
18632        ActivityStack focusedStack = getFocusedStack();
18633        if (focusedStack != null) {
18634            return focusedStack.getStackId();
18635        }
18636        return -1;
18637    }
18638
18639    public Configuration getConfiguration() {
18640        Configuration ci;
18641        synchronized(this) {
18642            ci = new Configuration(mConfiguration);
18643            ci.userSetLocale = false;
18644        }
18645        return ci;
18646    }
18647
18648    @Override
18649    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18650        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18651        synchronized (this) {
18652            mSuppressResizeConfigChanges = suppress;
18653        }
18654    }
18655
18656    @Override
18657    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18658        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18659        if (fromStackId == HOME_STACK_ID) {
18660            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18661        }
18662        synchronized (this) {
18663            final long origId = Binder.clearCallingIdentity();
18664            try {
18665                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18666            } finally {
18667                Binder.restoreCallingIdentity(origId);
18668            }
18669        }
18670    }
18671
18672    @Override
18673    public void updatePersistentConfiguration(Configuration values) {
18674        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18675                "updateConfiguration()");
18676        enforceWriteSettingsPermission("updateConfiguration()");
18677        if (values == null) {
18678            throw new NullPointerException("Configuration must not be null");
18679        }
18680
18681        int userId = UserHandle.getCallingUserId();
18682
18683        synchronized(this) {
18684            updatePersistentConfigurationLocked(values, userId);
18685        }
18686    }
18687
18688    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18689        final long origId = Binder.clearCallingIdentity();
18690        try {
18691            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18692        } finally {
18693            Binder.restoreCallingIdentity(origId);
18694        }
18695    }
18696
18697    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18698        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18699                FONT_SCALE, 1.0f, userId);
18700        if (mConfiguration.fontScale != scaleFactor) {
18701            final Configuration configuration = mWindowManager.computeNewConfiguration();
18702            configuration.fontScale = scaleFactor;
18703            synchronized (this) {
18704                updatePersistentConfigurationLocked(configuration, userId);
18705            }
18706        }
18707    }
18708
18709    private void enforceWriteSettingsPermission(String func) {
18710        int uid = Binder.getCallingUid();
18711        if (uid == Process.ROOT_UID) {
18712            return;
18713        }
18714
18715        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18716                Settings.getPackageNameForUid(mContext, uid), false)) {
18717            return;
18718        }
18719
18720        String msg = "Permission Denial: " + func + " from pid="
18721                + Binder.getCallingPid()
18722                + ", uid=" + uid
18723                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18724        Slog.w(TAG, msg);
18725        throw new SecurityException(msg);
18726    }
18727
18728    public void updateConfiguration(Configuration values) {
18729        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18730                "updateConfiguration()");
18731
18732        synchronized(this) {
18733            if (values == null && mWindowManager != null) {
18734                // sentinel: fetch the current configuration from the window manager
18735                values = mWindowManager.computeNewConfiguration();
18736            }
18737
18738            if (mWindowManager != null) {
18739                mProcessList.applyDisplaySize(mWindowManager);
18740            }
18741
18742            final long origId = Binder.clearCallingIdentity();
18743            if (values != null) {
18744                Settings.System.clearConfiguration(values);
18745            }
18746            updateConfigurationLocked(values, null, false);
18747            Binder.restoreCallingIdentity(origId);
18748        }
18749    }
18750
18751    void updateUserConfigurationLocked() {
18752        Configuration configuration = new Configuration(mConfiguration);
18753        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18754                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18755        updateConfigurationLocked(configuration, null, false);
18756    }
18757
18758    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18759            boolean initLocale) {
18760        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18761    }
18762
18763    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18764            boolean initLocale, boolean deferResume) {
18765        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18766        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18767                UserHandle.USER_NULL, deferResume);
18768    }
18769
18770    // To cache the list of supported system locales
18771    private String[] mSupportedSystemLocales = null;
18772
18773    /**
18774     * Do either or both things: (1) change the current configuration, and (2)
18775     * make sure the given activity is running with the (now) current
18776     * configuration.  Returns true if the activity has been left running, or
18777     * false if <var>starting</var> is being destroyed to match the new
18778     * configuration.
18779     *
18780     * @param userId is only used when persistent parameter is set to true to persist configuration
18781     *               for that particular user
18782     */
18783    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18784            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18785        int changes = 0;
18786
18787        if (mWindowManager != null) {
18788            mWindowManager.deferSurfaceLayout();
18789        }
18790        if (values != null) {
18791            Configuration newConfig = new Configuration(mConfiguration);
18792            changes = newConfig.updateFrom(values);
18793            if (changes != 0) {
18794                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18795                        "Updating configuration to: " + values);
18796
18797                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18798
18799                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18800                    final LocaleList locales = values.getLocales();
18801                    int bestLocaleIndex = 0;
18802                    if (locales.size() > 1) {
18803                        if (mSupportedSystemLocales == null) {
18804                            mSupportedSystemLocales =
18805                                    Resources.getSystem().getAssets().getLocales();
18806                        }
18807                        bestLocaleIndex = Math.max(0,
18808                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18809                    }
18810                    SystemProperties.set("persist.sys.locale",
18811                            locales.get(bestLocaleIndex).toLanguageTag());
18812                    LocaleList.setDefault(locales, bestLocaleIndex);
18813                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18814                            locales.get(bestLocaleIndex)));
18815                }
18816
18817                mConfigurationSeq++;
18818                if (mConfigurationSeq <= 0) {
18819                    mConfigurationSeq = 1;
18820                }
18821                newConfig.seq = mConfigurationSeq;
18822                mConfiguration = newConfig;
18823                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18824                mUsageStatsService.reportConfigurationChange(newConfig,
18825                        mUserController.getCurrentUserIdLocked());
18826                //mUsageStatsService.noteStartConfig(newConfig);
18827
18828                final Configuration configCopy = new Configuration(mConfiguration);
18829
18830                // TODO: If our config changes, should we auto dismiss any currently
18831                // showing dialogs?
18832                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18833
18834                AttributeCache ac = AttributeCache.instance();
18835                if (ac != null) {
18836                    ac.updateConfiguration(configCopy);
18837                }
18838
18839                // Make sure all resources in our process are updated
18840                // right now, so that anyone who is going to retrieve
18841                // resource values after we return will be sure to get
18842                // the new ones.  This is especially important during
18843                // boot, where the first config change needs to guarantee
18844                // all resources have that config before following boot
18845                // code is executed.
18846                mSystemThread.applyConfigurationToResources(configCopy);
18847
18848                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18849                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18850                    msg.obj = new Configuration(configCopy);
18851                    msg.arg1 = userId;
18852                    mHandler.sendMessage(msg);
18853                }
18854
18855                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18856                if (isDensityChange) {
18857                    // Reset the unsupported display size dialog.
18858                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18859
18860                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18861                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18862                }
18863
18864                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18865                    ProcessRecord app = mLruProcesses.get(i);
18866                    try {
18867                        if (app.thread != null) {
18868                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18869                                    + app.processName + " new config " + mConfiguration);
18870                            app.thread.scheduleConfigurationChanged(configCopy);
18871                        }
18872                    } catch (Exception e) {
18873                    }
18874                }
18875                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18876                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18877                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18878                        | Intent.FLAG_RECEIVER_FOREGROUND);
18879                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18880                        null, AppOpsManager.OP_NONE, null, false, false,
18881                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18882                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18883                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18884                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18885                    if (!mProcessesReady) {
18886                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18887                    }
18888                    broadcastIntentLocked(null, null, intent,
18889                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18890                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18891                }
18892            }
18893            // Update the configuration with WM first and check if any of the stacks need to be
18894            // resized due to the configuration change. If so, resize the stacks now and do any
18895            // relaunches if necessary. This way we don't need to relaunch again below in
18896            // ensureActivityConfigurationLocked().
18897            if (mWindowManager != null) {
18898                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18899                if (resizedStacks != null) {
18900                    for (int stackId : resizedStacks) {
18901                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18902                        mStackSupervisor.resizeStackLocked(
18903                                stackId, newBounds, null, null, false, false, deferResume);
18904                    }
18905                }
18906            }
18907        }
18908
18909        boolean kept = true;
18910        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18911        // mainStack is null during startup.
18912        if (mainStack != null) {
18913            if (changes != 0 && starting == null) {
18914                // If the configuration changed, and the caller is not already
18915                // in the process of starting an activity, then find the top
18916                // activity to check if its configuration needs to change.
18917                starting = mainStack.topRunningActivityLocked();
18918            }
18919
18920            if (starting != null) {
18921                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18922                // And we need to make sure at this point that all other activities
18923                // are made visible with the correct configuration.
18924                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18925                        !PRESERVE_WINDOWS);
18926            }
18927        }
18928        if (mWindowManager != null) {
18929            mWindowManager.continueSurfaceLayout();
18930        }
18931        return kept;
18932    }
18933
18934    /**
18935     * Decide based on the configuration whether we should shouw the ANR,
18936     * crash, etc dialogs.  The idea is that if there is no affordence to
18937     * press the on-screen buttons, or the user experience would be more
18938     * greatly impacted than the crash itself, we shouldn't show the dialog.
18939     *
18940     * A thought: SystemUI might also want to get told about this, the Power
18941     * dialog / global actions also might want different behaviors.
18942     */
18943    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18944        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18945                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18946                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18947        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18948        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18949                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18950        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18951    }
18952
18953    @Override
18954    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18955        synchronized (this) {
18956            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18957            if (srec != null) {
18958                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18959            }
18960        }
18961        return false;
18962    }
18963
18964    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18965            Intent resultData) {
18966
18967        synchronized (this) {
18968            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18969            if (r != null) {
18970                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18971            }
18972            return false;
18973        }
18974    }
18975
18976    public int getLaunchedFromUid(IBinder activityToken) {
18977        ActivityRecord srec;
18978        synchronized (this) {
18979            srec = ActivityRecord.forTokenLocked(activityToken);
18980        }
18981        if (srec == null) {
18982            return -1;
18983        }
18984        return srec.launchedFromUid;
18985    }
18986
18987    public String getLaunchedFromPackage(IBinder activityToken) {
18988        ActivityRecord srec;
18989        synchronized (this) {
18990            srec = ActivityRecord.forTokenLocked(activityToken);
18991        }
18992        if (srec == null) {
18993            return null;
18994        }
18995        return srec.launchedFromPackage;
18996    }
18997
18998    // =========================================================
18999    // LIFETIME MANAGEMENT
19000    // =========================================================
19001
19002    // Returns which broadcast queue the app is the current [or imminent] receiver
19003    // on, or 'null' if the app is not an active broadcast recipient.
19004    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19005        BroadcastRecord r = app.curReceiver;
19006        if (r != null) {
19007            return r.queue;
19008        }
19009
19010        // It's not the current receiver, but it might be starting up to become one
19011        synchronized (this) {
19012            for (BroadcastQueue queue : mBroadcastQueues) {
19013                r = queue.mPendingBroadcast;
19014                if (r != null && r.curApp == app) {
19015                    // found it; report which queue it's in
19016                    return queue;
19017                }
19018            }
19019        }
19020
19021        return null;
19022    }
19023
19024    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19025            int targetUid, ComponentName targetComponent, String targetProcess) {
19026        if (!mTrackingAssociations) {
19027            return null;
19028        }
19029        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19030                = mAssociations.get(targetUid);
19031        if (components == null) {
19032            components = new ArrayMap<>();
19033            mAssociations.put(targetUid, components);
19034        }
19035        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19036        if (sourceUids == null) {
19037            sourceUids = new SparseArray<>();
19038            components.put(targetComponent, sourceUids);
19039        }
19040        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19041        if (sourceProcesses == null) {
19042            sourceProcesses = new ArrayMap<>();
19043            sourceUids.put(sourceUid, sourceProcesses);
19044        }
19045        Association ass = sourceProcesses.get(sourceProcess);
19046        if (ass == null) {
19047            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19048                    targetProcess);
19049            sourceProcesses.put(sourceProcess, ass);
19050        }
19051        ass.mCount++;
19052        ass.mNesting++;
19053        if (ass.mNesting == 1) {
19054            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19055            ass.mLastState = sourceState;
19056        }
19057        return ass;
19058    }
19059
19060    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19061            ComponentName targetComponent) {
19062        if (!mTrackingAssociations) {
19063            return;
19064        }
19065        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19066                = mAssociations.get(targetUid);
19067        if (components == null) {
19068            return;
19069        }
19070        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19071        if (sourceUids == null) {
19072            return;
19073        }
19074        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19075        if (sourceProcesses == null) {
19076            return;
19077        }
19078        Association ass = sourceProcesses.get(sourceProcess);
19079        if (ass == null || ass.mNesting <= 0) {
19080            return;
19081        }
19082        ass.mNesting--;
19083        if (ass.mNesting == 0) {
19084            long uptime = SystemClock.uptimeMillis();
19085            ass.mTime += uptime - ass.mStartTime;
19086            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19087                    += uptime - ass.mLastStateUptime;
19088            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19089        }
19090    }
19091
19092    private void noteUidProcessState(final int uid, final int state) {
19093        mBatteryStatsService.noteUidProcessState(uid, state);
19094        if (mTrackingAssociations) {
19095            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19096                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19097                        = mAssociations.valueAt(i1);
19098                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19099                    SparseArray<ArrayMap<String, Association>> sourceUids
19100                            = targetComponents.valueAt(i2);
19101                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19102                    if (sourceProcesses != null) {
19103                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19104                            Association ass = sourceProcesses.valueAt(i4);
19105                            if (ass.mNesting >= 1) {
19106                                // currently associated
19107                                long uptime = SystemClock.uptimeMillis();
19108                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19109                                        += uptime - ass.mLastStateUptime;
19110                                ass.mLastState = state;
19111                                ass.mLastStateUptime = uptime;
19112                            }
19113                        }
19114                    }
19115                }
19116            }
19117        }
19118    }
19119
19120    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19121            boolean doingAll, long now) {
19122        if (mAdjSeq == app.adjSeq) {
19123            // This adjustment has already been computed.
19124            return app.curRawAdj;
19125        }
19126
19127        if (app.thread == null) {
19128            app.adjSeq = mAdjSeq;
19129            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19130            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19131            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19132        }
19133
19134        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19135        app.adjSource = null;
19136        app.adjTarget = null;
19137        app.empty = false;
19138        app.cached = false;
19139
19140        final int activitiesSize = app.activities.size();
19141
19142        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19143            // The max adjustment doesn't allow this app to be anything
19144            // below foreground, so it is not worth doing work for it.
19145            app.adjType = "fixed";
19146            app.adjSeq = mAdjSeq;
19147            app.curRawAdj = app.maxAdj;
19148            app.foregroundActivities = false;
19149            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19150            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19151            // System processes can do UI, and when they do we want to have
19152            // them trim their memory after the user leaves the UI.  To
19153            // facilitate this, here we need to determine whether or not it
19154            // is currently showing UI.
19155            app.systemNoUi = true;
19156            if (app == TOP_APP) {
19157                app.systemNoUi = false;
19158                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19159                app.adjType = "pers-top-activity";
19160            } else if (activitiesSize > 0) {
19161                for (int j = 0; j < activitiesSize; j++) {
19162                    final ActivityRecord r = app.activities.get(j);
19163                    if (r.visible) {
19164                        app.systemNoUi = false;
19165                    }
19166                }
19167            }
19168            if (!app.systemNoUi) {
19169                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19170            }
19171            return (app.curAdj=app.maxAdj);
19172        }
19173
19174        app.systemNoUi = false;
19175
19176        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19177
19178        // Determine the importance of the process, starting with most
19179        // important to least, and assign an appropriate OOM adjustment.
19180        int adj;
19181        int schedGroup;
19182        int procState;
19183        boolean foregroundActivities = false;
19184        BroadcastQueue queue;
19185        if (app == TOP_APP) {
19186            // The last app on the list is the foreground app.
19187            adj = ProcessList.FOREGROUND_APP_ADJ;
19188            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19189            app.adjType = "top-activity";
19190            foregroundActivities = true;
19191            procState = PROCESS_STATE_CUR_TOP;
19192        } else if (app.instrumentationClass != null) {
19193            // Don't want to kill running instrumentation.
19194            adj = ProcessList.FOREGROUND_APP_ADJ;
19195            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19196            app.adjType = "instrumentation";
19197            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19198        } else if ((queue = isReceivingBroadcast(app)) != null) {
19199            // An app that is currently receiving a broadcast also
19200            // counts as being in the foreground for OOM killer purposes.
19201            // It's placed in a sched group based on the nature of the
19202            // broadcast as reflected by which queue it's active in.
19203            adj = ProcessList.FOREGROUND_APP_ADJ;
19204            schedGroup = (queue == mFgBroadcastQueue)
19205                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19206            app.adjType = "broadcast";
19207            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19208        } else if (app.executingServices.size() > 0) {
19209            // An app that is currently executing a service callback also
19210            // counts as being in the foreground.
19211            adj = ProcessList.FOREGROUND_APP_ADJ;
19212            schedGroup = app.execServicesFg ?
19213                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19214            app.adjType = "exec-service";
19215            procState = ActivityManager.PROCESS_STATE_SERVICE;
19216            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19217        } else {
19218            // As far as we know the process is empty.  We may change our mind later.
19219            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19220            // At this point we don't actually know the adjustment.  Use the cached adj
19221            // value that the caller wants us to.
19222            adj = cachedAdj;
19223            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19224            app.cached = true;
19225            app.empty = true;
19226            app.adjType = "cch-empty";
19227        }
19228
19229        // Examine all activities if not already foreground.
19230        if (!foregroundActivities && activitiesSize > 0) {
19231            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19232            for (int j = 0; j < activitiesSize; j++) {
19233                final ActivityRecord r = app.activities.get(j);
19234                if (r.app != app) {
19235                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19236                            + " instead of expected " + app);
19237                    if (r.app == null || (r.app.uid == app.uid)) {
19238                        // Only fix things up when they look sane
19239                        r.app = app;
19240                    } else {
19241                        continue;
19242                    }
19243                }
19244                if (r.visible) {
19245                    // App has a visible activity; only upgrade adjustment.
19246                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19247                        adj = ProcessList.VISIBLE_APP_ADJ;
19248                        app.adjType = "visible";
19249                    }
19250                    if (procState > PROCESS_STATE_CUR_TOP) {
19251                        procState = PROCESS_STATE_CUR_TOP;
19252                    }
19253                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19254                    app.cached = false;
19255                    app.empty = false;
19256                    foregroundActivities = true;
19257                    if (r.task != null && minLayer > 0) {
19258                        final int layer = r.task.mLayerRank;
19259                        if (layer >= 0 && minLayer > layer) {
19260                            minLayer = layer;
19261                        }
19262                    }
19263                    break;
19264                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19265                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19266                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19267                        app.adjType = "pausing";
19268                    }
19269                    if (procState > PROCESS_STATE_CUR_TOP) {
19270                        procState = PROCESS_STATE_CUR_TOP;
19271                    }
19272                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19273                    app.cached = false;
19274                    app.empty = false;
19275                    foregroundActivities = true;
19276                } else if (r.state == ActivityState.STOPPING) {
19277                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19278                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19279                        app.adjType = "stopping";
19280                    }
19281                    // For the process state, we will at this point consider the
19282                    // process to be cached.  It will be cached either as an activity
19283                    // or empty depending on whether the activity is finishing.  We do
19284                    // this so that we can treat the process as cached for purposes of
19285                    // memory trimming (determing current memory level, trim command to
19286                    // send to process) since there can be an arbitrary number of stopping
19287                    // processes and they should soon all go into the cached state.
19288                    if (!r.finishing) {
19289                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19290                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19291                        }
19292                    }
19293                    app.cached = false;
19294                    app.empty = false;
19295                    foregroundActivities = true;
19296                } else {
19297                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19298                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19299                        app.adjType = "cch-act";
19300                    }
19301                }
19302            }
19303            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19304                adj += minLayer;
19305            }
19306        }
19307
19308        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19309                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19310            if (app.foregroundServices) {
19311                // The user is aware of this app, so make it visible.
19312                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19313                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19314                app.cached = false;
19315                app.adjType = "fg-service";
19316                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19317            } else if (app.forcingToForeground != null) {
19318                // The user is aware of this app, so make it visible.
19319                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19320                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19321                app.cached = false;
19322                app.adjType = "force-fg";
19323                app.adjSource = app.forcingToForeground;
19324                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19325            }
19326        }
19327
19328        if (app == mHeavyWeightProcess) {
19329            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19330                // We don't want to kill the current heavy-weight process.
19331                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19332                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19333                app.cached = false;
19334                app.adjType = "heavy";
19335            }
19336            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19337                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19338            }
19339        }
19340
19341        if (app == mHomeProcess) {
19342            if (adj > ProcessList.HOME_APP_ADJ) {
19343                // This process is hosting what we currently consider to be the
19344                // home app, so we don't want to let it go into the background.
19345                adj = ProcessList.HOME_APP_ADJ;
19346                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19347                app.cached = false;
19348                app.adjType = "home";
19349            }
19350            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19351                procState = ActivityManager.PROCESS_STATE_HOME;
19352            }
19353        }
19354
19355        if (app == mPreviousProcess && app.activities.size() > 0) {
19356            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19357                // This was the previous process that showed UI to the user.
19358                // We want to try to keep it around more aggressively, to give
19359                // a good experience around switching between two apps.
19360                adj = ProcessList.PREVIOUS_APP_ADJ;
19361                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19362                app.cached = false;
19363                app.adjType = "previous";
19364            }
19365            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19366                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19367            }
19368        }
19369
19370        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19371                + " reason=" + app.adjType);
19372
19373        // By default, we use the computed adjustment.  It may be changed if
19374        // there are applications dependent on our services or providers, but
19375        // this gives us a baseline and makes sure we don't get into an
19376        // infinite recursion.
19377        app.adjSeq = mAdjSeq;
19378        app.curRawAdj = adj;
19379        app.hasStartedServices = false;
19380
19381        if (mBackupTarget != null && app == mBackupTarget.app) {
19382            // If possible we want to avoid killing apps while they're being backed up
19383            if (adj > ProcessList.BACKUP_APP_ADJ) {
19384                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19385                adj = ProcessList.BACKUP_APP_ADJ;
19386                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19387                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19388                }
19389                app.adjType = "backup";
19390                app.cached = false;
19391            }
19392            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19393                procState = ActivityManager.PROCESS_STATE_BACKUP;
19394            }
19395        }
19396
19397        boolean mayBeTop = false;
19398
19399        for (int is = app.services.size()-1;
19400                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19401                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19402                        || procState > ActivityManager.PROCESS_STATE_TOP);
19403                is--) {
19404            ServiceRecord s = app.services.valueAt(is);
19405            if (s.startRequested) {
19406                app.hasStartedServices = true;
19407                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19408                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19409                }
19410                if (app.hasShownUi && app != mHomeProcess) {
19411                    // If this process has shown some UI, let it immediately
19412                    // go to the LRU list because it may be pretty heavy with
19413                    // UI stuff.  We'll tag it with a label just to help
19414                    // debug and understand what is going on.
19415                    if (adj > ProcessList.SERVICE_ADJ) {
19416                        app.adjType = "cch-started-ui-services";
19417                    }
19418                } else {
19419                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19420                        // This service has seen some activity within
19421                        // recent memory, so we will keep its process ahead
19422                        // of the background processes.
19423                        if (adj > ProcessList.SERVICE_ADJ) {
19424                            adj = ProcessList.SERVICE_ADJ;
19425                            app.adjType = "started-services";
19426                            app.cached = false;
19427                        }
19428                    }
19429                    // If we have let the service slide into the background
19430                    // state, still have some text describing what it is doing
19431                    // even though the service no longer has an impact.
19432                    if (adj > ProcessList.SERVICE_ADJ) {
19433                        app.adjType = "cch-started-services";
19434                    }
19435                }
19436            }
19437
19438            for (int conni = s.connections.size()-1;
19439                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19440                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19441                            || procState > ActivityManager.PROCESS_STATE_TOP);
19442                    conni--) {
19443                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19444                for (int i = 0;
19445                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19446                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19447                                || procState > ActivityManager.PROCESS_STATE_TOP);
19448                        i++) {
19449                    // XXX should compute this based on the max of
19450                    // all connected clients.
19451                    ConnectionRecord cr = clist.get(i);
19452                    if (cr.binding.client == app) {
19453                        // Binding to ourself is not interesting.
19454                        continue;
19455                    }
19456
19457                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19458                        ProcessRecord client = cr.binding.client;
19459                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19460                                TOP_APP, doingAll, now);
19461                        int clientProcState = client.curProcState;
19462                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19463                            // If the other app is cached for any reason, for purposes here
19464                            // we are going to consider it empty.  The specific cached state
19465                            // doesn't propagate except under certain conditions.
19466                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19467                        }
19468                        String adjType = null;
19469                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19470                            // Not doing bind OOM management, so treat
19471                            // this guy more like a started service.
19472                            if (app.hasShownUi && app != mHomeProcess) {
19473                                // If this process has shown some UI, let it immediately
19474                                // go to the LRU list because it may be pretty heavy with
19475                                // UI stuff.  We'll tag it with a label just to help
19476                                // debug and understand what is going on.
19477                                if (adj > clientAdj) {
19478                                    adjType = "cch-bound-ui-services";
19479                                }
19480                                app.cached = false;
19481                                clientAdj = adj;
19482                                clientProcState = procState;
19483                            } else {
19484                                if (now >= (s.lastActivity
19485                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19486                                    // This service has not seen activity within
19487                                    // recent memory, so allow it to drop to the
19488                                    // LRU list if there is no other reason to keep
19489                                    // it around.  We'll also tag it with a label just
19490                                    // to help debug and undertand what is going on.
19491                                    if (adj > clientAdj) {
19492                                        adjType = "cch-bound-services";
19493                                    }
19494                                    clientAdj = adj;
19495                                }
19496                            }
19497                        }
19498                        if (adj > clientAdj) {
19499                            // If this process has recently shown UI, and
19500                            // the process that is binding to it is less
19501                            // important than being visible, then we don't
19502                            // care about the binding as much as we care
19503                            // about letting this process get into the LRU
19504                            // list to be killed and restarted if needed for
19505                            // memory.
19506                            if (app.hasShownUi && app != mHomeProcess
19507                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19508                                adjType = "cch-bound-ui-services";
19509                            } else {
19510                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19511                                        |Context.BIND_IMPORTANT)) != 0) {
19512                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19513                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19514                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19515                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19516                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19517                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19518                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19519                                    adj = clientAdj;
19520                                } else {
19521                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19522                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19523                                    }
19524                                }
19525                                if (!client.cached) {
19526                                    app.cached = false;
19527                                }
19528                                adjType = "service";
19529                            }
19530                        }
19531                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19532                            // This will treat important bound services identically to
19533                            // the top app, which may behave differently than generic
19534                            // foreground work.
19535                            if (client.curSchedGroup > schedGroup) {
19536                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19537                                    schedGroup = client.curSchedGroup;
19538                                } else {
19539                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19540                                }
19541                            }
19542                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19543                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19544                                    // Special handling of clients who are in the top state.
19545                                    // We *may* want to consider this process to be in the
19546                                    // top state as well, but only if there is not another
19547                                    // reason for it to be running.  Being on the top is a
19548                                    // special state, meaning you are specifically running
19549                                    // for the current top app.  If the process is already
19550                                    // running in the background for some other reason, it
19551                                    // is more important to continue considering it to be
19552                                    // in the background state.
19553                                    mayBeTop = true;
19554                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19555                                } else {
19556                                    // Special handling for above-top states (persistent
19557                                    // processes).  These should not bring the current process
19558                                    // into the top state, since they are not on top.  Instead
19559                                    // give them the best state after that.
19560                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19561                                        clientProcState =
19562                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19563                                    } else if (mWakefulness
19564                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19565                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19566                                                    != 0) {
19567                                        clientProcState =
19568                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19569                                    } else {
19570                                        clientProcState =
19571                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19572                                    }
19573                                }
19574                            }
19575                        } else {
19576                            if (clientProcState <
19577                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19578                                clientProcState =
19579                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19580                            }
19581                        }
19582                        if (procState > clientProcState) {
19583                            procState = clientProcState;
19584                        }
19585                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19586                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19587                            app.pendingUiClean = true;
19588                        }
19589                        if (adjType != null) {
19590                            app.adjType = adjType;
19591                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19592                                    .REASON_SERVICE_IN_USE;
19593                            app.adjSource = cr.binding.client;
19594                            app.adjSourceProcState = clientProcState;
19595                            app.adjTarget = s.name;
19596                        }
19597                    }
19598                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19599                        app.treatLikeActivity = true;
19600                    }
19601                    final ActivityRecord a = cr.activity;
19602                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19603                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19604                            (a.visible || a.state == ActivityState.RESUMED ||
19605                             a.state == ActivityState.PAUSING)) {
19606                            adj = ProcessList.FOREGROUND_APP_ADJ;
19607                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19608                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19609                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19610                                } else {
19611                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19612                                }
19613                            }
19614                            app.cached = false;
19615                            app.adjType = "service";
19616                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19617                                    .REASON_SERVICE_IN_USE;
19618                            app.adjSource = a;
19619                            app.adjSourceProcState = procState;
19620                            app.adjTarget = s.name;
19621                        }
19622                    }
19623                }
19624            }
19625        }
19626
19627        for (int provi = app.pubProviders.size()-1;
19628                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19629                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19630                        || procState > ActivityManager.PROCESS_STATE_TOP);
19631                provi--) {
19632            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19633            for (int i = cpr.connections.size()-1;
19634                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19635                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19636                            || procState > ActivityManager.PROCESS_STATE_TOP);
19637                    i--) {
19638                ContentProviderConnection conn = cpr.connections.get(i);
19639                ProcessRecord client = conn.client;
19640                if (client == app) {
19641                    // Being our own client is not interesting.
19642                    continue;
19643                }
19644                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19645                int clientProcState = client.curProcState;
19646                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19647                    // If the other app is cached for any reason, for purposes here
19648                    // we are going to consider it empty.
19649                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19650                }
19651                if (adj > clientAdj) {
19652                    if (app.hasShownUi && app != mHomeProcess
19653                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19654                        app.adjType = "cch-ui-provider";
19655                    } else {
19656                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19657                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19658                        app.adjType = "provider";
19659                    }
19660                    app.cached &= client.cached;
19661                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19662                            .REASON_PROVIDER_IN_USE;
19663                    app.adjSource = client;
19664                    app.adjSourceProcState = clientProcState;
19665                    app.adjTarget = cpr.name;
19666                }
19667                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19668                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19669                        // Special handling of clients who are in the top state.
19670                        // We *may* want to consider this process to be in the
19671                        // top state as well, but only if there is not another
19672                        // reason for it to be running.  Being on the top is a
19673                        // special state, meaning you are specifically running
19674                        // for the current top app.  If the process is already
19675                        // running in the background for some other reason, it
19676                        // is more important to continue considering it to be
19677                        // in the background state.
19678                        mayBeTop = true;
19679                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19680                    } else {
19681                        // Special handling for above-top states (persistent
19682                        // processes).  These should not bring the current process
19683                        // into the top state, since they are not on top.  Instead
19684                        // give them the best state after that.
19685                        clientProcState =
19686                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19687                    }
19688                }
19689                if (procState > clientProcState) {
19690                    procState = clientProcState;
19691                }
19692                if (client.curSchedGroup > schedGroup) {
19693                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19694                }
19695            }
19696            // If the provider has external (non-framework) process
19697            // dependencies, ensure that its adjustment is at least
19698            // FOREGROUND_APP_ADJ.
19699            if (cpr.hasExternalProcessHandles()) {
19700                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19701                    adj = ProcessList.FOREGROUND_APP_ADJ;
19702                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19703                    app.cached = false;
19704                    app.adjType = "provider";
19705                    app.adjTarget = cpr.name;
19706                }
19707                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19708                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19709                }
19710            }
19711        }
19712
19713        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19714            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19715                adj = ProcessList.PREVIOUS_APP_ADJ;
19716                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19717                app.cached = false;
19718                app.adjType = "provider";
19719            }
19720            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19721                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19722            }
19723        }
19724
19725        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19726            // A client of one of our services or providers is in the top state.  We
19727            // *may* want to be in the top state, but not if we are already running in
19728            // the background for some other reason.  For the decision here, we are going
19729            // to pick out a few specific states that we want to remain in when a client
19730            // is top (states that tend to be longer-term) and otherwise allow it to go
19731            // to the top state.
19732            switch (procState) {
19733                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19734                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19735                case ActivityManager.PROCESS_STATE_SERVICE:
19736                    // These all are longer-term states, so pull them up to the top
19737                    // of the background states, but not all the way to the top state.
19738                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19739                    break;
19740                default:
19741                    // Otherwise, top is a better choice, so take it.
19742                    procState = ActivityManager.PROCESS_STATE_TOP;
19743                    break;
19744            }
19745        }
19746
19747        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19748            if (app.hasClientActivities) {
19749                // This is a cached process, but with client activities.  Mark it so.
19750                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19751                app.adjType = "cch-client-act";
19752            } else if (app.treatLikeActivity) {
19753                // This is a cached process, but somebody wants us to treat it like it has
19754                // an activity, okay!
19755                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19756                app.adjType = "cch-as-act";
19757            }
19758        }
19759
19760        if (adj == ProcessList.SERVICE_ADJ) {
19761            if (doingAll) {
19762                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19763                mNewNumServiceProcs++;
19764                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19765                if (!app.serviceb) {
19766                    // This service isn't far enough down on the LRU list to
19767                    // normally be a B service, but if we are low on RAM and it
19768                    // is large we want to force it down since we would prefer to
19769                    // keep launcher over it.
19770                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19771                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19772                        app.serviceHighRam = true;
19773                        app.serviceb = true;
19774                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19775                    } else {
19776                        mNewNumAServiceProcs++;
19777                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19778                    }
19779                } else {
19780                    app.serviceHighRam = false;
19781                }
19782            }
19783            if (app.serviceb) {
19784                adj = ProcessList.SERVICE_B_ADJ;
19785            }
19786        }
19787
19788        app.curRawAdj = adj;
19789
19790        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19791        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19792        if (adj > app.maxAdj) {
19793            adj = app.maxAdj;
19794            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19795                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19796            }
19797        }
19798
19799        // Do final modification to adj.  Everything we do between here and applying
19800        // the final setAdj must be done in this function, because we will also use
19801        // it when computing the final cached adj later.  Note that we don't need to
19802        // worry about this for max adj above, since max adj will always be used to
19803        // keep it out of the cached vaues.
19804        app.curAdj = app.modifyRawOomAdj(adj);
19805        app.curSchedGroup = schedGroup;
19806        app.curProcState = procState;
19807        app.foregroundActivities = foregroundActivities;
19808
19809        return app.curRawAdj;
19810    }
19811
19812    /**
19813     * Record new PSS sample for a process.
19814     */
19815    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19816            long now) {
19817        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19818                swapPss * 1024);
19819        proc.lastPssTime = now;
19820        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19821        if (DEBUG_PSS) Slog.d(TAG_PSS,
19822                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19823                + " state=" + ProcessList.makeProcStateString(procState));
19824        if (proc.initialIdlePss == 0) {
19825            proc.initialIdlePss = pss;
19826        }
19827        proc.lastPss = pss;
19828        proc.lastSwapPss = swapPss;
19829        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19830            proc.lastCachedPss = pss;
19831            proc.lastCachedSwapPss = swapPss;
19832        }
19833
19834        final SparseArray<Pair<Long, String>> watchUids
19835                = mMemWatchProcesses.getMap().get(proc.processName);
19836        Long check = null;
19837        if (watchUids != null) {
19838            Pair<Long, String> val = watchUids.get(proc.uid);
19839            if (val == null) {
19840                val = watchUids.get(0);
19841            }
19842            if (val != null) {
19843                check = val.first;
19844            }
19845        }
19846        if (check != null) {
19847            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19848                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19849                if (!isDebuggable) {
19850                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19851                        isDebuggable = true;
19852                    }
19853                }
19854                if (isDebuggable) {
19855                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19856                    final ProcessRecord myProc = proc;
19857                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19858                    mMemWatchDumpProcName = proc.processName;
19859                    mMemWatchDumpFile = heapdumpFile.toString();
19860                    mMemWatchDumpPid = proc.pid;
19861                    mMemWatchDumpUid = proc.uid;
19862                    BackgroundThread.getHandler().post(new Runnable() {
19863                        @Override
19864                        public void run() {
19865                            revokeUriPermission(ActivityThread.currentActivityThread()
19866                                            .getApplicationThread(),
19867                                    DumpHeapActivity.JAVA_URI,
19868                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19869                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19870                                    UserHandle.myUserId());
19871                            ParcelFileDescriptor fd = null;
19872                            try {
19873                                heapdumpFile.delete();
19874                                fd = ParcelFileDescriptor.open(heapdumpFile,
19875                                        ParcelFileDescriptor.MODE_CREATE |
19876                                                ParcelFileDescriptor.MODE_TRUNCATE |
19877                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19878                                                ParcelFileDescriptor.MODE_APPEND);
19879                                IApplicationThread thread = myProc.thread;
19880                                if (thread != null) {
19881                                    try {
19882                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19883                                                "Requesting dump heap from "
19884                                                + myProc + " to " + heapdumpFile);
19885                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19886                                    } catch (RemoteException e) {
19887                                    }
19888                                }
19889                            } catch (FileNotFoundException e) {
19890                                e.printStackTrace();
19891                            } finally {
19892                                if (fd != null) {
19893                                    try {
19894                                        fd.close();
19895                                    } catch (IOException e) {
19896                                    }
19897                                }
19898                            }
19899                        }
19900                    });
19901                } else {
19902                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19903                            + ", but debugging not enabled");
19904                }
19905            }
19906        }
19907    }
19908
19909    /**
19910     * Schedule PSS collection of a process.
19911     */
19912    void requestPssLocked(ProcessRecord proc, int procState) {
19913        if (mPendingPssProcesses.contains(proc)) {
19914            return;
19915        }
19916        if (mPendingPssProcesses.size() == 0) {
19917            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19918        }
19919        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19920        proc.pssProcState = procState;
19921        mPendingPssProcesses.add(proc);
19922    }
19923
19924    /**
19925     * Schedule PSS collection of all processes.
19926     */
19927    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19928        if (!always) {
19929            if (now < (mLastFullPssTime +
19930                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19931                return;
19932            }
19933        }
19934        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19935        mLastFullPssTime = now;
19936        mFullPssPending = true;
19937        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19938        mPendingPssProcesses.clear();
19939        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19940            ProcessRecord app = mLruProcesses.get(i);
19941            if (app.thread == null
19942                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19943                continue;
19944            }
19945            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19946                app.pssProcState = app.setProcState;
19947                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19948                        mTestPssMode, isSleepingLocked(), now);
19949                mPendingPssProcesses.add(app);
19950            }
19951        }
19952        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19953    }
19954
19955    public void setTestPssMode(boolean enabled) {
19956        synchronized (this) {
19957            mTestPssMode = enabled;
19958            if (enabled) {
19959                // Whenever we enable the mode, we want to take a snapshot all of current
19960                // process mem use.
19961                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19962            }
19963        }
19964    }
19965
19966    /**
19967     * Ask a given process to GC right now.
19968     */
19969    final void performAppGcLocked(ProcessRecord app) {
19970        try {
19971            app.lastRequestedGc = SystemClock.uptimeMillis();
19972            if (app.thread != null) {
19973                if (app.reportLowMemory) {
19974                    app.reportLowMemory = false;
19975                    app.thread.scheduleLowMemory();
19976                } else {
19977                    app.thread.processInBackground();
19978                }
19979            }
19980        } catch (Exception e) {
19981            // whatever.
19982        }
19983    }
19984
19985    /**
19986     * Returns true if things are idle enough to perform GCs.
19987     */
19988    private final boolean canGcNowLocked() {
19989        boolean processingBroadcasts = false;
19990        for (BroadcastQueue q : mBroadcastQueues) {
19991            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19992                processingBroadcasts = true;
19993            }
19994        }
19995        return !processingBroadcasts
19996                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19997    }
19998
19999    /**
20000     * Perform GCs on all processes that are waiting for it, but only
20001     * if things are idle.
20002     */
20003    final void performAppGcsLocked() {
20004        final int N = mProcessesToGc.size();
20005        if (N <= 0) {
20006            return;
20007        }
20008        if (canGcNowLocked()) {
20009            while (mProcessesToGc.size() > 0) {
20010                ProcessRecord proc = mProcessesToGc.remove(0);
20011                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20012                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20013                            <= SystemClock.uptimeMillis()) {
20014                        // To avoid spamming the system, we will GC processes one
20015                        // at a time, waiting a few seconds between each.
20016                        performAppGcLocked(proc);
20017                        scheduleAppGcsLocked();
20018                        return;
20019                    } else {
20020                        // It hasn't been long enough since we last GCed this
20021                        // process...  put it in the list to wait for its time.
20022                        addProcessToGcListLocked(proc);
20023                        break;
20024                    }
20025                }
20026            }
20027
20028            scheduleAppGcsLocked();
20029        }
20030    }
20031
20032    /**
20033     * If all looks good, perform GCs on all processes waiting for them.
20034     */
20035    final void performAppGcsIfAppropriateLocked() {
20036        if (canGcNowLocked()) {
20037            performAppGcsLocked();
20038            return;
20039        }
20040        // Still not idle, wait some more.
20041        scheduleAppGcsLocked();
20042    }
20043
20044    /**
20045     * Schedule the execution of all pending app GCs.
20046     */
20047    final void scheduleAppGcsLocked() {
20048        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20049
20050        if (mProcessesToGc.size() > 0) {
20051            // Schedule a GC for the time to the next process.
20052            ProcessRecord proc = mProcessesToGc.get(0);
20053            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20054
20055            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20056            long now = SystemClock.uptimeMillis();
20057            if (when < (now+GC_TIMEOUT)) {
20058                when = now + GC_TIMEOUT;
20059            }
20060            mHandler.sendMessageAtTime(msg, when);
20061        }
20062    }
20063
20064    /**
20065     * Add a process to the array of processes waiting to be GCed.  Keeps the
20066     * list in sorted order by the last GC time.  The process can't already be
20067     * on the list.
20068     */
20069    final void addProcessToGcListLocked(ProcessRecord proc) {
20070        boolean added = false;
20071        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20072            if (mProcessesToGc.get(i).lastRequestedGc <
20073                    proc.lastRequestedGc) {
20074                added = true;
20075                mProcessesToGc.add(i+1, proc);
20076                break;
20077            }
20078        }
20079        if (!added) {
20080            mProcessesToGc.add(0, proc);
20081        }
20082    }
20083
20084    /**
20085     * Set up to ask a process to GC itself.  This will either do it
20086     * immediately, or put it on the list of processes to gc the next
20087     * time things are idle.
20088     */
20089    final void scheduleAppGcLocked(ProcessRecord app) {
20090        long now = SystemClock.uptimeMillis();
20091        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20092            return;
20093        }
20094        if (!mProcessesToGc.contains(app)) {
20095            addProcessToGcListLocked(app);
20096            scheduleAppGcsLocked();
20097        }
20098    }
20099
20100    final void checkExcessivePowerUsageLocked(boolean doKills) {
20101        updateCpuStatsNow();
20102
20103        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20104        boolean doWakeKills = doKills;
20105        boolean doCpuKills = doKills;
20106        if (mLastPowerCheckRealtime == 0) {
20107            doWakeKills = false;
20108        }
20109        if (mLastPowerCheckUptime == 0) {
20110            doCpuKills = false;
20111        }
20112        if (stats.isScreenOn()) {
20113            doWakeKills = false;
20114        }
20115        final long curRealtime = SystemClock.elapsedRealtime();
20116        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20117        final long curUptime = SystemClock.uptimeMillis();
20118        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20119        mLastPowerCheckRealtime = curRealtime;
20120        mLastPowerCheckUptime = curUptime;
20121        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20122            doWakeKills = false;
20123        }
20124        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20125            doCpuKills = false;
20126        }
20127        int i = mLruProcesses.size();
20128        while (i > 0) {
20129            i--;
20130            ProcessRecord app = mLruProcesses.get(i);
20131            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20132                long wtime;
20133                synchronized (stats) {
20134                    wtime = stats.getProcessWakeTime(app.info.uid,
20135                            app.pid, curRealtime);
20136                }
20137                long wtimeUsed = wtime - app.lastWakeTime;
20138                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20139                if (DEBUG_POWER) {
20140                    StringBuilder sb = new StringBuilder(128);
20141                    sb.append("Wake for ");
20142                    app.toShortString(sb);
20143                    sb.append(": over ");
20144                    TimeUtils.formatDuration(realtimeSince, sb);
20145                    sb.append(" used ");
20146                    TimeUtils.formatDuration(wtimeUsed, sb);
20147                    sb.append(" (");
20148                    sb.append((wtimeUsed*100)/realtimeSince);
20149                    sb.append("%)");
20150                    Slog.i(TAG_POWER, sb.toString());
20151                    sb.setLength(0);
20152                    sb.append("CPU for ");
20153                    app.toShortString(sb);
20154                    sb.append(": over ");
20155                    TimeUtils.formatDuration(uptimeSince, sb);
20156                    sb.append(" used ");
20157                    TimeUtils.formatDuration(cputimeUsed, sb);
20158                    sb.append(" (");
20159                    sb.append((cputimeUsed*100)/uptimeSince);
20160                    sb.append("%)");
20161                    Slog.i(TAG_POWER, sb.toString());
20162                }
20163                // If a process has held a wake lock for more
20164                // than 50% of the time during this period,
20165                // that sounds bad.  Kill!
20166                if (doWakeKills && realtimeSince > 0
20167                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20168                    synchronized (stats) {
20169                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20170                                realtimeSince, wtimeUsed);
20171                    }
20172                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20173                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20174                } else if (doCpuKills && uptimeSince > 0
20175                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20176                    synchronized (stats) {
20177                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20178                                uptimeSince, cputimeUsed);
20179                    }
20180                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20181                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20182                } else {
20183                    app.lastWakeTime = wtime;
20184                    app.lastCpuTime = app.curCpuTime;
20185                }
20186            }
20187        }
20188    }
20189
20190    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20191            long nowElapsed) {
20192        boolean success = true;
20193
20194        if (app.curRawAdj != app.setRawAdj) {
20195            app.setRawAdj = app.curRawAdj;
20196        }
20197
20198        int changes = 0;
20199
20200        if (app.curAdj != app.setAdj) {
20201            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20202            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20203                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20204                    + app.adjType);
20205            app.setAdj = app.curAdj;
20206            app.verifiedAdj = ProcessList.INVALID_ADJ;
20207        }
20208
20209        if (app.setSchedGroup != app.curSchedGroup) {
20210            int oldSchedGroup = app.setSchedGroup;
20211            app.setSchedGroup = app.curSchedGroup;
20212            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20213                    "Setting sched group of " + app.processName
20214                    + " to " + app.curSchedGroup);
20215            if (app.waitingToKill != null && app.curReceiver == null
20216                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20217                app.kill(app.waitingToKill, true);
20218                success = false;
20219            } else {
20220                int processGroup;
20221                switch (app.curSchedGroup) {
20222                    case ProcessList.SCHED_GROUP_BACKGROUND:
20223                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20224                        break;
20225                    case ProcessList.SCHED_GROUP_TOP_APP:
20226                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20227                        processGroup = Process.THREAD_GROUP_TOP_APP;
20228                        break;
20229                    default:
20230                        processGroup = Process.THREAD_GROUP_DEFAULT;
20231                        break;
20232                }
20233                long oldId = Binder.clearCallingIdentity();
20234                try {
20235                    Process.setProcessGroup(app.pid, processGroup);
20236                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20237                        // do nothing if we already switched to RT
20238                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20239                            // Switch VR thread for app to SCHED_FIFO
20240                            if (mInVrMode && app.vrThreadTid != 0) {
20241                                Process.setThreadScheduler(app.vrThreadTid,
20242                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20243                            }
20244                            if (mUseFifoUiScheduling) {
20245                                // Switch UI pipeline for app to SCHED_FIFO
20246                                app.savedPriority = Process.getThreadPriority(app.pid);
20247                                Process.setThreadScheduler(app.pid,
20248                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20249                                if (app.renderThreadTid != 0) {
20250                                    Process.setThreadScheduler(app.renderThreadTid,
20251                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20252                                    if (DEBUG_OOM_ADJ) {
20253                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20254                                            app.renderThreadTid + ") to FIFO");
20255                                    }
20256                                } else {
20257                                    if (DEBUG_OOM_ADJ) {
20258                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20259                                    }
20260                                }
20261                            }
20262                        }
20263                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20264                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20265                        // Reset VR thread to SCHED_OTHER
20266                        // Safe to do even if we're not in VR mode
20267                        if (app.vrThreadTid != 0) {
20268                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20269                        }
20270                        if (mUseFifoUiScheduling) {
20271                            // Reset UI pipeline to SCHED_OTHER
20272                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20273                            Process.setThreadPriority(app.pid, app.savedPriority);
20274                            if (app.renderThreadTid != 0) {
20275                                Process.setThreadScheduler(app.renderThreadTid,
20276                                    Process.SCHED_OTHER, 0);
20277                                Process.setThreadPriority(app.renderThreadTid, -4);
20278                            }
20279                        }
20280                    }
20281                } catch (Exception e) {
20282                    Slog.w(TAG, "Failed setting process group of " + app.pid
20283                            + " to " + app.curSchedGroup);
20284                    e.printStackTrace();
20285                } finally {
20286                    Binder.restoreCallingIdentity(oldId);
20287                }
20288            }
20289        }
20290        if (app.repForegroundActivities != app.foregroundActivities) {
20291            app.repForegroundActivities = app.foregroundActivities;
20292            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20293        }
20294        if (app.repProcState != app.curProcState) {
20295            app.repProcState = app.curProcState;
20296            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20297            if (app.thread != null) {
20298                try {
20299                    if (false) {
20300                        //RuntimeException h = new RuntimeException("here");
20301                        Slog.i(TAG, "Sending new process state " + app.repProcState
20302                                + " to " + app /*, h*/);
20303                    }
20304                    app.thread.setProcessState(app.repProcState);
20305                } catch (RemoteException e) {
20306                }
20307            }
20308        }
20309        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20310                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20311            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20312                // Experimental code to more aggressively collect pss while
20313                // running test...  the problem is that this tends to collect
20314                // the data right when a process is transitioning between process
20315                // states, which well tend to give noisy data.
20316                long start = SystemClock.uptimeMillis();
20317                long pss = Debug.getPss(app.pid, mTmpLong, null);
20318                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20319                mPendingPssProcesses.remove(app);
20320                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20321                        + " to " + app.curProcState + ": "
20322                        + (SystemClock.uptimeMillis()-start) + "ms");
20323            }
20324            app.lastStateTime = now;
20325            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20326                    mTestPssMode, isSleepingLocked(), now);
20327            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20328                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20329                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20330                    + (app.nextPssTime-now) + ": " + app);
20331        } else {
20332            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20333                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20334                    mTestPssMode)))) {
20335                requestPssLocked(app, app.setProcState);
20336                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20337                        mTestPssMode, isSleepingLocked(), now);
20338            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20339                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20340        }
20341        if (app.setProcState != app.curProcState) {
20342            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20343                    "Proc state change of " + app.processName
20344                            + " to " + app.curProcState);
20345            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20346            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20347            if (setImportant && !curImportant) {
20348                // This app is no longer something we consider important enough to allow to
20349                // use arbitrary amounts of battery power.  Note
20350                // its current wake lock time to later know to kill it if
20351                // it is not behaving well.
20352                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20353                synchronized (stats) {
20354                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20355                            app.pid, nowElapsed);
20356                }
20357                app.lastCpuTime = app.curCpuTime;
20358
20359            }
20360            // Inform UsageStats of important process state change
20361            // Must be called before updating setProcState
20362            maybeUpdateUsageStatsLocked(app, nowElapsed);
20363
20364            app.setProcState = app.curProcState;
20365            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20366                app.notCachedSinceIdle = false;
20367            }
20368            if (!doingAll) {
20369                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20370            } else {
20371                app.procStateChanged = true;
20372            }
20373        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20374                > USAGE_STATS_INTERACTION_INTERVAL) {
20375            // For apps that sit around for a long time in the interactive state, we need
20376            // to report this at least once a day so they don't go idle.
20377            maybeUpdateUsageStatsLocked(app, nowElapsed);
20378        }
20379
20380        if (changes != 0) {
20381            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20382                    "Changes in " + app + ": " + changes);
20383            int i = mPendingProcessChanges.size()-1;
20384            ProcessChangeItem item = null;
20385            while (i >= 0) {
20386                item = mPendingProcessChanges.get(i);
20387                if (item.pid == app.pid) {
20388                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20389                            "Re-using existing item: " + item);
20390                    break;
20391                }
20392                i--;
20393            }
20394            if (i < 0) {
20395                // No existing item in pending changes; need a new one.
20396                final int NA = mAvailProcessChanges.size();
20397                if (NA > 0) {
20398                    item = mAvailProcessChanges.remove(NA-1);
20399                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20400                            "Retrieving available item: " + item);
20401                } else {
20402                    item = new ProcessChangeItem();
20403                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20404                            "Allocating new item: " + item);
20405                }
20406                item.changes = 0;
20407                item.pid = app.pid;
20408                item.uid = app.info.uid;
20409                if (mPendingProcessChanges.size() == 0) {
20410                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20411                            "*** Enqueueing dispatch processes changed!");
20412                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20413                }
20414                mPendingProcessChanges.add(item);
20415            }
20416            item.changes |= changes;
20417            item.processState = app.repProcState;
20418            item.foregroundActivities = app.repForegroundActivities;
20419            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20420                    "Item " + Integer.toHexString(System.identityHashCode(item))
20421                    + " " + app.toShortString() + ": changes=" + item.changes
20422                    + " procState=" + item.processState
20423                    + " foreground=" + item.foregroundActivities
20424                    + " type=" + app.adjType + " source=" + app.adjSource
20425                    + " target=" + app.adjTarget);
20426        }
20427
20428        return success;
20429    }
20430
20431    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20432        final UidRecord.ChangeItem pendingChange;
20433        if (uidRec == null || uidRec.pendingChange == null) {
20434            if (mPendingUidChanges.size() == 0) {
20435                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20436                        "*** Enqueueing dispatch uid changed!");
20437                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20438            }
20439            final int NA = mAvailUidChanges.size();
20440            if (NA > 0) {
20441                pendingChange = mAvailUidChanges.remove(NA-1);
20442                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20443                        "Retrieving available item: " + pendingChange);
20444            } else {
20445                pendingChange = new UidRecord.ChangeItem();
20446                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20447                        "Allocating new item: " + pendingChange);
20448            }
20449            if (uidRec != null) {
20450                uidRec.pendingChange = pendingChange;
20451                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20452                    // If this uid is going away, and we haven't yet reported it is gone,
20453                    // then do so now.
20454                    change = UidRecord.CHANGE_GONE_IDLE;
20455                }
20456            } else if (uid < 0) {
20457                throw new IllegalArgumentException("No UidRecord or uid");
20458            }
20459            pendingChange.uidRecord = uidRec;
20460            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20461            mPendingUidChanges.add(pendingChange);
20462        } else {
20463            pendingChange = uidRec.pendingChange;
20464            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20465                change = UidRecord.CHANGE_GONE_IDLE;
20466            }
20467        }
20468        pendingChange.change = change;
20469        pendingChange.processState = uidRec != null
20470                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20471    }
20472
20473    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20474            String authority) {
20475        if (app == null) return;
20476        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20477            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20478            if (userState == null) return;
20479            final long now = SystemClock.elapsedRealtime();
20480            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20481            if (lastReported == null || lastReported < now - 60 * 1000L) {
20482                mUsageStatsService.reportContentProviderUsage(
20483                        authority, providerPkgName, app.userId);
20484                userState.mProviderLastReportedFg.put(authority, now);
20485            }
20486        }
20487    }
20488
20489    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20490        if (DEBUG_USAGE_STATS) {
20491            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20492                    + "] state changes: old = " + app.setProcState + ", new = "
20493                    + app.curProcState);
20494        }
20495        if (mUsageStatsService == null) {
20496            return;
20497        }
20498        boolean isInteraction;
20499        // To avoid some abuse patterns, we are going to be careful about what we consider
20500        // to be an app interaction.  Being the top activity doesn't count while the display
20501        // is sleeping, nor do short foreground services.
20502        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20503            isInteraction = true;
20504            app.fgInteractionTime = 0;
20505        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20506            if (app.fgInteractionTime == 0) {
20507                app.fgInteractionTime = nowElapsed;
20508                isInteraction = false;
20509            } else {
20510                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20511            }
20512        } else {
20513            isInteraction = app.curProcState
20514                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20515            app.fgInteractionTime = 0;
20516        }
20517        if (isInteraction && (!app.reportedInteraction
20518                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20519            app.interactionEventTime = nowElapsed;
20520            String[] packages = app.getPackageList();
20521            if (packages != null) {
20522                for (int i = 0; i < packages.length; i++) {
20523                    mUsageStatsService.reportEvent(packages[i], app.userId,
20524                            UsageEvents.Event.SYSTEM_INTERACTION);
20525                }
20526            }
20527        }
20528        app.reportedInteraction = isInteraction;
20529        if (!isInteraction) {
20530            app.interactionEventTime = 0;
20531        }
20532    }
20533
20534    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20535        if (proc.thread != null) {
20536            if (proc.baseProcessTracker != null) {
20537                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20538            }
20539        }
20540    }
20541
20542    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20543            ProcessRecord TOP_APP, boolean doingAll, long now) {
20544        if (app.thread == null) {
20545            return false;
20546        }
20547
20548        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20549
20550        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20551    }
20552
20553    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20554            boolean oomAdj) {
20555        if (isForeground != proc.foregroundServices) {
20556            proc.foregroundServices = isForeground;
20557            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20558                    proc.info.uid);
20559            if (isForeground) {
20560                if (curProcs == null) {
20561                    curProcs = new ArrayList<ProcessRecord>();
20562                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20563                }
20564                if (!curProcs.contains(proc)) {
20565                    curProcs.add(proc);
20566                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20567                            proc.info.packageName, proc.info.uid);
20568                }
20569            } else {
20570                if (curProcs != null) {
20571                    if (curProcs.remove(proc)) {
20572                        mBatteryStatsService.noteEvent(
20573                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20574                                proc.info.packageName, proc.info.uid);
20575                        if (curProcs.size() <= 0) {
20576                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20577                        }
20578                    }
20579                }
20580            }
20581            if (oomAdj) {
20582                updateOomAdjLocked();
20583            }
20584        }
20585    }
20586
20587    private final ActivityRecord resumedAppLocked() {
20588        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20589        String pkg;
20590        int uid;
20591        if (act != null) {
20592            pkg = act.packageName;
20593            uid = act.info.applicationInfo.uid;
20594        } else {
20595            pkg = null;
20596            uid = -1;
20597        }
20598        // Has the UID or resumed package name changed?
20599        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20600                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20601            if (mCurResumedPackage != null) {
20602                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20603                        mCurResumedPackage, mCurResumedUid);
20604            }
20605            mCurResumedPackage = pkg;
20606            mCurResumedUid = uid;
20607            if (mCurResumedPackage != null) {
20608                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20609                        mCurResumedPackage, mCurResumedUid);
20610            }
20611        }
20612        return act;
20613    }
20614
20615    final boolean updateOomAdjLocked(ProcessRecord app) {
20616        final ActivityRecord TOP_ACT = resumedAppLocked();
20617        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20618        final boolean wasCached = app.cached;
20619
20620        mAdjSeq++;
20621
20622        // This is the desired cached adjusment we want to tell it to use.
20623        // If our app is currently cached, we know it, and that is it.  Otherwise,
20624        // we don't know it yet, and it needs to now be cached we will then
20625        // need to do a complete oom adj.
20626        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20627                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20628        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20629                SystemClock.uptimeMillis());
20630        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20631            // Changed to/from cached state, so apps after it in the LRU
20632            // list may also be changed.
20633            updateOomAdjLocked();
20634        }
20635        return success;
20636    }
20637
20638    final void updateOomAdjLocked() {
20639        final ActivityRecord TOP_ACT = resumedAppLocked();
20640        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20641        final long now = SystemClock.uptimeMillis();
20642        final long nowElapsed = SystemClock.elapsedRealtime();
20643        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20644        final int N = mLruProcesses.size();
20645
20646        if (false) {
20647            RuntimeException e = new RuntimeException();
20648            e.fillInStackTrace();
20649            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20650        }
20651
20652        // Reset state in all uid records.
20653        for (int i=mActiveUids.size()-1; i>=0; i--) {
20654            final UidRecord uidRec = mActiveUids.valueAt(i);
20655            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20656                    "Starting update of " + uidRec);
20657            uidRec.reset();
20658        }
20659
20660        mStackSupervisor.rankTaskLayersIfNeeded();
20661
20662        mAdjSeq++;
20663        mNewNumServiceProcs = 0;
20664        mNewNumAServiceProcs = 0;
20665
20666        final int emptyProcessLimit;
20667        final int cachedProcessLimit;
20668        if (mProcessLimit <= 0) {
20669            emptyProcessLimit = cachedProcessLimit = 0;
20670        } else if (mProcessLimit == 1) {
20671            emptyProcessLimit = 1;
20672            cachedProcessLimit = 0;
20673        } else {
20674            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20675            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20676        }
20677
20678        // Let's determine how many processes we have running vs.
20679        // how many slots we have for background processes; we may want
20680        // to put multiple processes in a slot of there are enough of
20681        // them.
20682        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20683                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20684        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20685        if (numEmptyProcs > cachedProcessLimit) {
20686            // If there are more empty processes than our limit on cached
20687            // processes, then use the cached process limit for the factor.
20688            // This ensures that the really old empty processes get pushed
20689            // down to the bottom, so if we are running low on memory we will
20690            // have a better chance at keeping around more cached processes
20691            // instead of a gazillion empty processes.
20692            numEmptyProcs = cachedProcessLimit;
20693        }
20694        int emptyFactor = numEmptyProcs/numSlots;
20695        if (emptyFactor < 1) emptyFactor = 1;
20696        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20697        if (cachedFactor < 1) cachedFactor = 1;
20698        int stepCached = 0;
20699        int stepEmpty = 0;
20700        int numCached = 0;
20701        int numEmpty = 0;
20702        int numTrimming = 0;
20703
20704        mNumNonCachedProcs = 0;
20705        mNumCachedHiddenProcs = 0;
20706
20707        // First update the OOM adjustment for each of the
20708        // application processes based on their current state.
20709        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20710        int nextCachedAdj = curCachedAdj+1;
20711        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20712        int nextEmptyAdj = curEmptyAdj+2;
20713        for (int i=N-1; i>=0; i--) {
20714            ProcessRecord app = mLruProcesses.get(i);
20715            if (!app.killedByAm && app.thread != null) {
20716                app.procStateChanged = false;
20717                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20718
20719                // If we haven't yet assigned the final cached adj
20720                // to the process, do that now.
20721                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20722                    switch (app.curProcState) {
20723                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20724                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20725                            // This process is a cached process holding activities...
20726                            // assign it the next cached value for that type, and then
20727                            // step that cached level.
20728                            app.curRawAdj = curCachedAdj;
20729                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20730                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20731                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20732                                    + ")");
20733                            if (curCachedAdj != nextCachedAdj) {
20734                                stepCached++;
20735                                if (stepCached >= cachedFactor) {
20736                                    stepCached = 0;
20737                                    curCachedAdj = nextCachedAdj;
20738                                    nextCachedAdj += 2;
20739                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20740                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20741                                    }
20742                                }
20743                            }
20744                            break;
20745                        default:
20746                            // For everything else, assign next empty cached process
20747                            // level and bump that up.  Note that this means that
20748                            // long-running services that have dropped down to the
20749                            // cached level will be treated as empty (since their process
20750                            // state is still as a service), which is what we want.
20751                            app.curRawAdj = curEmptyAdj;
20752                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20753                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20754                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20755                                    + ")");
20756                            if (curEmptyAdj != nextEmptyAdj) {
20757                                stepEmpty++;
20758                                if (stepEmpty >= emptyFactor) {
20759                                    stepEmpty = 0;
20760                                    curEmptyAdj = nextEmptyAdj;
20761                                    nextEmptyAdj += 2;
20762                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20763                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20764                                    }
20765                                }
20766                            }
20767                            break;
20768                    }
20769                }
20770
20771                applyOomAdjLocked(app, true, now, nowElapsed);
20772
20773                // Count the number of process types.
20774                switch (app.curProcState) {
20775                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20776                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20777                        mNumCachedHiddenProcs++;
20778                        numCached++;
20779                        if (numCached > cachedProcessLimit) {
20780                            app.kill("cached #" + numCached, true);
20781                        }
20782                        break;
20783                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20784                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20785                                && app.lastActivityTime < oldTime) {
20786                            app.kill("empty for "
20787                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20788                                    / 1000) + "s", true);
20789                        } else {
20790                            numEmpty++;
20791                            if (numEmpty > emptyProcessLimit) {
20792                                app.kill("empty #" + numEmpty, true);
20793                            }
20794                        }
20795                        break;
20796                    default:
20797                        mNumNonCachedProcs++;
20798                        break;
20799                }
20800
20801                if (app.isolated && app.services.size() <= 0) {
20802                    // If this is an isolated process, and there are no
20803                    // services running in it, then the process is no longer
20804                    // needed.  We agressively kill these because we can by
20805                    // definition not re-use the same process again, and it is
20806                    // good to avoid having whatever code was running in them
20807                    // left sitting around after no longer needed.
20808                    app.kill("isolated not needed", true);
20809                } else {
20810                    // Keeping this process, update its uid.
20811                    final UidRecord uidRec = app.uidRecord;
20812                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20813                        uidRec.curProcState = app.curProcState;
20814                    }
20815                }
20816
20817                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20818                        && !app.killedByAm) {
20819                    numTrimming++;
20820                }
20821            }
20822        }
20823
20824        mNumServiceProcs = mNewNumServiceProcs;
20825
20826        // Now determine the memory trimming level of background processes.
20827        // Unfortunately we need to start at the back of the list to do this
20828        // properly.  We only do this if the number of background apps we
20829        // are managing to keep around is less than half the maximum we desire;
20830        // if we are keeping a good number around, we'll let them use whatever
20831        // memory they want.
20832        final int numCachedAndEmpty = numCached + numEmpty;
20833        int memFactor;
20834        if (numCached <= ProcessList.TRIM_CACHED_APPS
20835                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20836            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20837                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20838            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20839                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20840            } else {
20841                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20842            }
20843        } else {
20844            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20845        }
20846        // We always allow the memory level to go up (better).  We only allow it to go
20847        // down if we are in a state where that is allowed, *and* the total number of processes
20848        // has gone down since last time.
20849        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20850                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20851                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20852        if (memFactor > mLastMemoryLevel) {
20853            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20854                memFactor = mLastMemoryLevel;
20855                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20856            }
20857        }
20858        if (memFactor != mLastMemoryLevel) {
20859            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20860        }
20861        mLastMemoryLevel = memFactor;
20862        mLastNumProcesses = mLruProcesses.size();
20863        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20864        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20865        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20866            if (mLowRamStartTime == 0) {
20867                mLowRamStartTime = now;
20868            }
20869            int step = 0;
20870            int fgTrimLevel;
20871            switch (memFactor) {
20872                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20873                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20874                    break;
20875                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20876                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20877                    break;
20878                default:
20879                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20880                    break;
20881            }
20882            int factor = numTrimming/3;
20883            int minFactor = 2;
20884            if (mHomeProcess != null) minFactor++;
20885            if (mPreviousProcess != null) minFactor++;
20886            if (factor < minFactor) factor = minFactor;
20887            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20888            for (int i=N-1; i>=0; i--) {
20889                ProcessRecord app = mLruProcesses.get(i);
20890                if (allChanged || app.procStateChanged) {
20891                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20892                    app.procStateChanged = false;
20893                }
20894                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20895                        && !app.killedByAm) {
20896                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20897                        try {
20898                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20899                                    "Trimming memory of " + app.processName + " to " + curLevel);
20900                            app.thread.scheduleTrimMemory(curLevel);
20901                        } catch (RemoteException e) {
20902                        }
20903                        if (false) {
20904                            // For now we won't do this; our memory trimming seems
20905                            // to be good enough at this point that destroying
20906                            // activities causes more harm than good.
20907                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20908                                    && app != mHomeProcess && app != mPreviousProcess) {
20909                                // Need to do this on its own message because the stack may not
20910                                // be in a consistent state at this point.
20911                                // For these apps we will also finish their activities
20912                                // to help them free memory.
20913                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20914                            }
20915                        }
20916                    }
20917                    app.trimMemoryLevel = curLevel;
20918                    step++;
20919                    if (step >= factor) {
20920                        step = 0;
20921                        switch (curLevel) {
20922                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20923                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20924                                break;
20925                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20926                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20927                                break;
20928                        }
20929                    }
20930                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20931                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20932                            && app.thread != null) {
20933                        try {
20934                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20935                                    "Trimming memory of heavy-weight " + app.processName
20936                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20937                            app.thread.scheduleTrimMemory(
20938                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20939                        } catch (RemoteException e) {
20940                        }
20941                    }
20942                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20943                } else {
20944                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20945                            || app.systemNoUi) && app.pendingUiClean) {
20946                        // If this application is now in the background and it
20947                        // had done UI, then give it the special trim level to
20948                        // have it free UI resources.
20949                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20950                        if (app.trimMemoryLevel < level && app.thread != null) {
20951                            try {
20952                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20953                                        "Trimming memory of bg-ui " + app.processName
20954                                        + " to " + level);
20955                                app.thread.scheduleTrimMemory(level);
20956                            } catch (RemoteException e) {
20957                            }
20958                        }
20959                        app.pendingUiClean = false;
20960                    }
20961                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20962                        try {
20963                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20964                                    "Trimming memory of fg " + app.processName
20965                                    + " to " + fgTrimLevel);
20966                            app.thread.scheduleTrimMemory(fgTrimLevel);
20967                        } catch (RemoteException e) {
20968                        }
20969                    }
20970                    app.trimMemoryLevel = fgTrimLevel;
20971                }
20972            }
20973        } else {
20974            if (mLowRamStartTime != 0) {
20975                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20976                mLowRamStartTime = 0;
20977            }
20978            for (int i=N-1; i>=0; i--) {
20979                ProcessRecord app = mLruProcesses.get(i);
20980                if (allChanged || app.procStateChanged) {
20981                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20982                    app.procStateChanged = false;
20983                }
20984                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20985                        || app.systemNoUi) && app.pendingUiClean) {
20986                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20987                            && app.thread != null) {
20988                        try {
20989                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20990                                    "Trimming memory of ui hidden " + app.processName
20991                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20992                            app.thread.scheduleTrimMemory(
20993                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20994                        } catch (RemoteException e) {
20995                        }
20996                    }
20997                    app.pendingUiClean = false;
20998                }
20999                app.trimMemoryLevel = 0;
21000            }
21001        }
21002
21003        if (mAlwaysFinishActivities) {
21004            // Need to do this on its own message because the stack may not
21005            // be in a consistent state at this point.
21006            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21007        }
21008
21009        if (allChanged) {
21010            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21011        }
21012
21013        // Update from any uid changes.
21014        for (int i=mActiveUids.size()-1; i>=0; i--) {
21015            final UidRecord uidRec = mActiveUids.valueAt(i);
21016            int uidChange = UidRecord.CHANGE_PROCSTATE;
21017            if (uidRec.setProcState != uidRec.curProcState) {
21018                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21019                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21020                        + " to " + uidRec.curProcState);
21021                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21022                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21023                        uidRec.lastBackgroundTime = nowElapsed;
21024                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21025                            // Note: the background settle time is in elapsed realtime, while
21026                            // the handler time base is uptime.  All this means is that we may
21027                            // stop background uids later than we had intended, but that only
21028                            // happens because the device was sleeping so we are okay anyway.
21029                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21030                        }
21031                    }
21032                } else {
21033                    if (uidRec.idle) {
21034                        uidChange = UidRecord.CHANGE_ACTIVE;
21035                        uidRec.idle = false;
21036                    }
21037                    uidRec.lastBackgroundTime = 0;
21038                }
21039                uidRec.setProcState = uidRec.curProcState;
21040                enqueueUidChangeLocked(uidRec, -1, uidChange);
21041                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21042            }
21043        }
21044
21045        if (mProcessStats.shouldWriteNowLocked(now)) {
21046            mHandler.post(new Runnable() {
21047                @Override public void run() {
21048                    synchronized (ActivityManagerService.this) {
21049                        mProcessStats.writeStateAsyncLocked();
21050                    }
21051                }
21052            });
21053        }
21054
21055        if (DEBUG_OOM_ADJ) {
21056            final long duration = SystemClock.uptimeMillis() - now;
21057            if (false) {
21058                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21059                        new RuntimeException("here").fillInStackTrace());
21060            } else {
21061                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21062            }
21063        }
21064    }
21065
21066    final void idleUids() {
21067        synchronized (this) {
21068            final long nowElapsed = SystemClock.elapsedRealtime();
21069            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21070            long nextTime = 0;
21071            for (int i=mActiveUids.size()-1; i>=0; i--) {
21072                final UidRecord uidRec = mActiveUids.valueAt(i);
21073                final long bgTime = uidRec.lastBackgroundTime;
21074                if (bgTime > 0 && !uidRec.idle) {
21075                    if (bgTime <= maxBgTime) {
21076                        uidRec.idle = true;
21077                        doStopUidLocked(uidRec.uid, uidRec);
21078                    } else {
21079                        if (nextTime == 0 || nextTime > bgTime) {
21080                            nextTime = bgTime;
21081                        }
21082                    }
21083                }
21084            }
21085            if (nextTime > 0) {
21086                mHandler.removeMessages(IDLE_UIDS_MSG);
21087                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21088                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21089            }
21090        }
21091    }
21092
21093    final void runInBackgroundDisabled(int uid) {
21094        synchronized (this) {
21095            UidRecord uidRec = mActiveUids.get(uid);
21096            if (uidRec != null) {
21097                // This uid is actually running...  should it be considered background now?
21098                if (uidRec.idle) {
21099                    doStopUidLocked(uidRec.uid, uidRec);
21100                }
21101            } else {
21102                // This uid isn't actually running...  still send a report about it being "stopped".
21103                doStopUidLocked(uid, null);
21104            }
21105        }
21106    }
21107
21108    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21109        mServices.stopInBackgroundLocked(uid);
21110        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21111    }
21112
21113    final void trimApplications() {
21114        synchronized (this) {
21115            int i;
21116
21117            // First remove any unused application processes whose package
21118            // has been removed.
21119            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21120                final ProcessRecord app = mRemovedProcesses.get(i);
21121                if (app.activities.size() == 0
21122                        && app.curReceiver == null && app.services.size() == 0) {
21123                    Slog.i(
21124                        TAG, "Exiting empty application process "
21125                        + app.toShortString() + " ("
21126                        + (app.thread != null ? app.thread.asBinder() : null)
21127                        + ")\n");
21128                    if (app.pid > 0 && app.pid != MY_PID) {
21129                        app.kill("empty", false);
21130                    } else {
21131                        try {
21132                            app.thread.scheduleExit();
21133                        } catch (Exception e) {
21134                            // Ignore exceptions.
21135                        }
21136                    }
21137                    cleanUpApplicationRecordLocked(app, false, true, -1);
21138                    mRemovedProcesses.remove(i);
21139
21140                    if (app.persistent) {
21141                        addAppLocked(app.info, false, null /* ABI override */);
21142                    }
21143                }
21144            }
21145
21146            // Now update the oom adj for all processes.
21147            updateOomAdjLocked();
21148        }
21149    }
21150
21151    /** This method sends the specified signal to each of the persistent apps */
21152    public void signalPersistentProcesses(int sig) throws RemoteException {
21153        if (sig != Process.SIGNAL_USR1) {
21154            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21155        }
21156
21157        synchronized (this) {
21158            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21159                    != PackageManager.PERMISSION_GRANTED) {
21160                throw new SecurityException("Requires permission "
21161                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21162            }
21163
21164            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21165                ProcessRecord r = mLruProcesses.get(i);
21166                if (r.thread != null && r.persistent) {
21167                    Process.sendSignal(r.pid, sig);
21168                }
21169            }
21170        }
21171    }
21172
21173    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21174        if (proc == null || proc == mProfileProc) {
21175            proc = mProfileProc;
21176            profileType = mProfileType;
21177            clearProfilerLocked();
21178        }
21179        if (proc == null) {
21180            return;
21181        }
21182        try {
21183            proc.thread.profilerControl(false, null, profileType);
21184        } catch (RemoteException e) {
21185            throw new IllegalStateException("Process disappeared");
21186        }
21187    }
21188
21189    private void clearProfilerLocked() {
21190        if (mProfileFd != null) {
21191            try {
21192                mProfileFd.close();
21193            } catch (IOException e) {
21194            }
21195        }
21196        mProfileApp = null;
21197        mProfileProc = null;
21198        mProfileFile = null;
21199        mProfileType = 0;
21200        mAutoStopProfiler = false;
21201        mSamplingInterval = 0;
21202    }
21203
21204    public boolean profileControl(String process, int userId, boolean start,
21205            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21206
21207        try {
21208            synchronized (this) {
21209                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21210                // its own permission.
21211                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21212                        != PackageManager.PERMISSION_GRANTED) {
21213                    throw new SecurityException("Requires permission "
21214                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21215                }
21216
21217                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21218                    throw new IllegalArgumentException("null profile info or fd");
21219                }
21220
21221                ProcessRecord proc = null;
21222                if (process != null) {
21223                    proc = findProcessLocked(process, userId, "profileControl");
21224                }
21225
21226                if (start && (proc == null || proc.thread == null)) {
21227                    throw new IllegalArgumentException("Unknown process: " + process);
21228                }
21229
21230                if (start) {
21231                    stopProfilerLocked(null, 0);
21232                    setProfileApp(proc.info, proc.processName, profilerInfo);
21233                    mProfileProc = proc;
21234                    mProfileType = profileType;
21235                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21236                    try {
21237                        fd = fd.dup();
21238                    } catch (IOException e) {
21239                        fd = null;
21240                    }
21241                    profilerInfo.profileFd = fd;
21242                    proc.thread.profilerControl(start, profilerInfo, profileType);
21243                    fd = null;
21244                    mProfileFd = null;
21245                } else {
21246                    stopProfilerLocked(proc, profileType);
21247                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21248                        try {
21249                            profilerInfo.profileFd.close();
21250                        } catch (IOException e) {
21251                        }
21252                    }
21253                }
21254
21255                return true;
21256            }
21257        } catch (RemoteException e) {
21258            throw new IllegalStateException("Process disappeared");
21259        } finally {
21260            if (profilerInfo != null && profilerInfo.profileFd != null) {
21261                try {
21262                    profilerInfo.profileFd.close();
21263                } catch (IOException e) {
21264                }
21265            }
21266        }
21267    }
21268
21269    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21270        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21271                userId, true, ALLOW_FULL_ONLY, callName, null);
21272        ProcessRecord proc = null;
21273        try {
21274            int pid = Integer.parseInt(process);
21275            synchronized (mPidsSelfLocked) {
21276                proc = mPidsSelfLocked.get(pid);
21277            }
21278        } catch (NumberFormatException e) {
21279        }
21280
21281        if (proc == null) {
21282            ArrayMap<String, SparseArray<ProcessRecord>> all
21283                    = mProcessNames.getMap();
21284            SparseArray<ProcessRecord> procs = all.get(process);
21285            if (procs != null && procs.size() > 0) {
21286                proc = procs.valueAt(0);
21287                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21288                    for (int i=1; i<procs.size(); i++) {
21289                        ProcessRecord thisProc = procs.valueAt(i);
21290                        if (thisProc.userId == userId) {
21291                            proc = thisProc;
21292                            break;
21293                        }
21294                    }
21295                }
21296            }
21297        }
21298
21299        return proc;
21300    }
21301
21302    public boolean dumpHeap(String process, int userId, boolean managed,
21303            String path, ParcelFileDescriptor fd) throws RemoteException {
21304
21305        try {
21306            synchronized (this) {
21307                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21308                // its own permission (same as profileControl).
21309                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21310                        != PackageManager.PERMISSION_GRANTED) {
21311                    throw new SecurityException("Requires permission "
21312                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21313                }
21314
21315                if (fd == null) {
21316                    throw new IllegalArgumentException("null fd");
21317                }
21318
21319                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21320                if (proc == null || proc.thread == null) {
21321                    throw new IllegalArgumentException("Unknown process: " + process);
21322                }
21323
21324                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21325                if (!isDebuggable) {
21326                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21327                        throw new SecurityException("Process not debuggable: " + proc);
21328                    }
21329                }
21330
21331                proc.thread.dumpHeap(managed, path, fd);
21332                fd = null;
21333                return true;
21334            }
21335        } catch (RemoteException e) {
21336            throw new IllegalStateException("Process disappeared");
21337        } finally {
21338            if (fd != null) {
21339                try {
21340                    fd.close();
21341                } catch (IOException e) {
21342                }
21343            }
21344        }
21345    }
21346
21347    @Override
21348    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21349            String reportPackage) {
21350        if (processName != null) {
21351            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21352                    "setDumpHeapDebugLimit()");
21353        } else {
21354            synchronized (mPidsSelfLocked) {
21355                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21356                if (proc == null) {
21357                    throw new SecurityException("No process found for calling pid "
21358                            + Binder.getCallingPid());
21359                }
21360                if (!Build.IS_DEBUGGABLE
21361                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21362                    throw new SecurityException("Not running a debuggable build");
21363                }
21364                processName = proc.processName;
21365                uid = proc.uid;
21366                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21367                    throw new SecurityException("Package " + reportPackage + " is not running in "
21368                            + proc);
21369                }
21370            }
21371        }
21372        synchronized (this) {
21373            if (maxMemSize > 0) {
21374                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21375            } else {
21376                if (uid != 0) {
21377                    mMemWatchProcesses.remove(processName, uid);
21378                } else {
21379                    mMemWatchProcesses.getMap().remove(processName);
21380                }
21381            }
21382        }
21383    }
21384
21385    @Override
21386    public void dumpHeapFinished(String path) {
21387        synchronized (this) {
21388            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21389                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21390                        + " does not match last pid " + mMemWatchDumpPid);
21391                return;
21392            }
21393            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21394                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21395                        + " does not match last path " + mMemWatchDumpFile);
21396                return;
21397            }
21398            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21399            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21400        }
21401    }
21402
21403    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21404    public void monitor() {
21405        synchronized (this) { }
21406    }
21407
21408    void onCoreSettingsChange(Bundle settings) {
21409        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21410            ProcessRecord processRecord = mLruProcesses.get(i);
21411            try {
21412                if (processRecord.thread != null) {
21413                    processRecord.thread.setCoreSettings(settings);
21414                }
21415            } catch (RemoteException re) {
21416                /* ignore */
21417            }
21418        }
21419    }
21420
21421    // Multi-user methods
21422
21423    /**
21424     * Start user, if its not already running, but don't bring it to foreground.
21425     */
21426    @Override
21427    public boolean startUserInBackground(final int userId) {
21428        return mUserController.startUser(userId, /* foreground */ false);
21429    }
21430
21431    @Override
21432    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21433        return mUserController.unlockUser(userId, token, secret, listener);
21434    }
21435
21436    @Override
21437    public boolean switchUser(final int targetUserId) {
21438        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21439        UserInfo currentUserInfo;
21440        UserInfo targetUserInfo;
21441        synchronized (this) {
21442            int currentUserId = mUserController.getCurrentUserIdLocked();
21443            currentUserInfo = mUserController.getUserInfo(currentUserId);
21444            targetUserInfo = mUserController.getUserInfo(targetUserId);
21445            if (targetUserInfo == null) {
21446                Slog.w(TAG, "No user info for user #" + targetUserId);
21447                return false;
21448            }
21449            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21450                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21451                        + " when device is in demo mode");
21452                return false;
21453            }
21454            if (!targetUserInfo.supportsSwitchTo()) {
21455                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21456                return false;
21457            }
21458            if (targetUserInfo.isManagedProfile()) {
21459                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21460                return false;
21461            }
21462            mUserController.setTargetUserIdLocked(targetUserId);
21463        }
21464        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21465        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21466        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21467        return true;
21468    }
21469
21470    void scheduleStartProfilesLocked() {
21471        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21472            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21473                    DateUtils.SECOND_IN_MILLIS);
21474        }
21475    }
21476
21477    @Override
21478    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21479        return mUserController.stopUser(userId, force, callback);
21480    }
21481
21482    @Override
21483    public UserInfo getCurrentUser() {
21484        return mUserController.getCurrentUser();
21485    }
21486
21487    @Override
21488    public boolean isUserRunning(int userId, int flags) {
21489        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21490                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21491            String msg = "Permission Denial: isUserRunning() from pid="
21492                    + Binder.getCallingPid()
21493                    + ", uid=" + Binder.getCallingUid()
21494                    + " requires " + INTERACT_ACROSS_USERS;
21495            Slog.w(TAG, msg);
21496            throw new SecurityException(msg);
21497        }
21498        synchronized (this) {
21499            return mUserController.isUserRunningLocked(userId, flags);
21500        }
21501    }
21502
21503    @Override
21504    public int[] getRunningUserIds() {
21505        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21506                != PackageManager.PERMISSION_GRANTED) {
21507            String msg = "Permission Denial: isUserRunning() from pid="
21508                    + Binder.getCallingPid()
21509                    + ", uid=" + Binder.getCallingUid()
21510                    + " requires " + INTERACT_ACROSS_USERS;
21511            Slog.w(TAG, msg);
21512            throw new SecurityException(msg);
21513        }
21514        synchronized (this) {
21515            return mUserController.getStartedUserArrayLocked();
21516        }
21517    }
21518
21519    @Override
21520    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21521        mUserController.registerUserSwitchObserver(observer, name);
21522    }
21523
21524    @Override
21525    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21526        mUserController.unregisterUserSwitchObserver(observer);
21527    }
21528
21529    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21530        if (info == null) return null;
21531        ApplicationInfo newInfo = new ApplicationInfo(info);
21532        newInfo.initForUser(userId);
21533        return newInfo;
21534    }
21535
21536    public boolean isUserStopped(int userId) {
21537        synchronized (this) {
21538            return mUserController.getStartedUserStateLocked(userId) == null;
21539        }
21540    }
21541
21542    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21543        if (aInfo == null
21544                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21545            return aInfo;
21546        }
21547
21548        ActivityInfo info = new ActivityInfo(aInfo);
21549        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21550        return info;
21551    }
21552
21553    private boolean processSanityChecksLocked(ProcessRecord process) {
21554        if (process == null || process.thread == null) {
21555            return false;
21556        }
21557
21558        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21559        if (!isDebuggable) {
21560            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21561                return false;
21562            }
21563        }
21564
21565        return true;
21566    }
21567
21568    public boolean startBinderTracking() throws RemoteException {
21569        synchronized (this) {
21570            mBinderTransactionTrackingEnabled = true;
21571            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21572            // permission (same as profileControl).
21573            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21574                    != PackageManager.PERMISSION_GRANTED) {
21575                throw new SecurityException("Requires permission "
21576                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21577            }
21578
21579            for (int i = 0; i < mLruProcesses.size(); i++) {
21580                ProcessRecord process = mLruProcesses.get(i);
21581                if (!processSanityChecksLocked(process)) {
21582                    continue;
21583                }
21584                try {
21585                    process.thread.startBinderTracking();
21586                } catch (RemoteException e) {
21587                    Log.v(TAG, "Process disappared");
21588                }
21589            }
21590            return true;
21591        }
21592    }
21593
21594    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21595        try {
21596            synchronized (this) {
21597                mBinderTransactionTrackingEnabled = false;
21598                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21599                // permission (same as profileControl).
21600                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21601                        != PackageManager.PERMISSION_GRANTED) {
21602                    throw new SecurityException("Requires permission "
21603                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21604                }
21605
21606                if (fd == null) {
21607                    throw new IllegalArgumentException("null fd");
21608                }
21609
21610                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21611                pw.println("Binder transaction traces for all processes.\n");
21612                for (ProcessRecord process : mLruProcesses) {
21613                    if (!processSanityChecksLocked(process)) {
21614                        continue;
21615                    }
21616
21617                    pw.println("Traces for process: " + process.processName);
21618                    pw.flush();
21619                    try {
21620                        TransferPipe tp = new TransferPipe();
21621                        try {
21622                            process.thread.stopBinderTrackingAndDump(
21623                                    tp.getWriteFd().getFileDescriptor());
21624                            tp.go(fd.getFileDescriptor());
21625                        } finally {
21626                            tp.kill();
21627                        }
21628                    } catch (IOException e) {
21629                        pw.println("Failure while dumping IPC traces from " + process +
21630                                ".  Exception: " + e);
21631                        pw.flush();
21632                    } catch (RemoteException e) {
21633                        pw.println("Got a RemoteException while dumping IPC traces from " +
21634                                process + ".  Exception: " + e);
21635                        pw.flush();
21636                    }
21637                }
21638                fd = null;
21639                return true;
21640            }
21641        } finally {
21642            if (fd != null) {
21643                try {
21644                    fd.close();
21645                } catch (IOException e) {
21646                }
21647            }
21648        }
21649    }
21650
21651    private final class LocalService extends ActivityManagerInternal {
21652        @Override
21653        public void onWakefulnessChanged(int wakefulness) {
21654            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21655        }
21656
21657        @Override
21658        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21659                String processName, String abiOverride, int uid, Runnable crashHandler) {
21660            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21661                    processName, abiOverride, uid, crashHandler);
21662        }
21663
21664        @Override
21665        public SleepToken acquireSleepToken(String tag) {
21666            Preconditions.checkNotNull(tag);
21667
21668            ComponentName requestedVrService = null;
21669            ComponentName callingVrActivity = null;
21670            int userId = -1;
21671            synchronized (ActivityManagerService.this) {
21672                if (mFocusedActivity != null) {
21673                    requestedVrService = mFocusedActivity.requestedVrComponent;
21674                    callingVrActivity = mFocusedActivity.info.getComponentName();
21675                    userId = mFocusedActivity.userId;
21676                }
21677            }
21678
21679            if (requestedVrService != null) {
21680                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21681            }
21682
21683            synchronized (ActivityManagerService.this) {
21684                SleepTokenImpl token = new SleepTokenImpl(tag);
21685                mSleepTokens.add(token);
21686                updateSleepIfNeededLocked();
21687                return token;
21688            }
21689        }
21690
21691        @Override
21692        public ComponentName getHomeActivityForUser(int userId) {
21693            synchronized (ActivityManagerService.this) {
21694                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21695                return homeActivity == null ? null : homeActivity.realActivity;
21696            }
21697        }
21698
21699        @Override
21700        public void onUserRemoved(int userId) {
21701            synchronized (ActivityManagerService.this) {
21702                ActivityManagerService.this.onUserStoppedLocked(userId);
21703            }
21704        }
21705
21706        @Override
21707        public void onLocalVoiceInteractionStarted(IBinder activity,
21708                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21709            synchronized (ActivityManagerService.this) {
21710                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21711                        voiceSession, voiceInteractor);
21712            }
21713        }
21714
21715        @Override
21716        public void notifyStartingWindowDrawn() {
21717            synchronized (ActivityManagerService.this) {
21718                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21719            }
21720        }
21721
21722        @Override
21723        public void notifyAppTransitionStarting(int reason) {
21724            synchronized (ActivityManagerService.this) {
21725                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21726            }
21727        }
21728
21729        @Override
21730        public void notifyAppTransitionFinished() {
21731            synchronized (ActivityManagerService.this) {
21732                mStackSupervisor.notifyAppTransitionDone();
21733            }
21734        }
21735
21736        @Override
21737        public void notifyAppTransitionCancelled() {
21738            synchronized (ActivityManagerService.this) {
21739                mStackSupervisor.notifyAppTransitionDone();
21740            }
21741        }
21742
21743        @Override
21744        public List<IBinder> getTopVisibleActivities() {
21745            synchronized (ActivityManagerService.this) {
21746                return mStackSupervisor.getTopVisibleActivities();
21747            }
21748        }
21749
21750        @Override
21751        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21752            synchronized (ActivityManagerService.this) {
21753                mStackSupervisor.setDockedStackMinimized(minimized);
21754            }
21755        }
21756
21757        @Override
21758        public void killForegroundAppsForUser(int userHandle) {
21759            synchronized (ActivityManagerService.this) {
21760                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21761                final int NP = mProcessNames.getMap().size();
21762                for (int ip = 0; ip < NP; ip++) {
21763                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21764                    final int NA = apps.size();
21765                    for (int ia = 0; ia < NA; ia++) {
21766                        final ProcessRecord app = apps.valueAt(ia);
21767                        if (app.persistent) {
21768                            // We don't kill persistent processes.
21769                            continue;
21770                        }
21771                        if (app.removed) {
21772                            procs.add(app);
21773                        } else if (app.userId == userHandle && app.foregroundActivities) {
21774                            app.removed = true;
21775                            procs.add(app);
21776                        }
21777                    }
21778                }
21779
21780                final int N = procs.size();
21781                for (int i = 0; i < N; i++) {
21782                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21783                }
21784            }
21785        }
21786
21787        @Override
21788        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21789            if (!(target instanceof PendingIntentRecord)) {
21790                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21791                return;
21792            }
21793            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21794        }
21795
21796        @Override
21797        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21798                int userId) {
21799            Preconditions.checkNotNull(values, "Configuration must not be null");
21800            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21801            synchronized (ActivityManagerService.this) {
21802                updateConfigurationLocked(values, null, false, true, userId,
21803                        false /* deferResume */);
21804            }
21805        }
21806
21807        @Override
21808        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
21809                Bundle bOptions) {
21810            Preconditions.checkNotNull(intents, "intents");
21811            final String[] resolvedTypes = new String[intents.length];
21812            for (int i = 0; i < intents.length; i++) {
21813                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
21814            }
21815
21816            // UID of the package on user userId.
21817            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21818            // packageUid may not be initialized.
21819            int packageUid = 0;
21820            try {
21821                packageUid = AppGlobals.getPackageManager().getPackageUid(
21822                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21823            } catch (RemoteException e) {
21824                // Shouldn't happen.
21825            }
21826
21827            synchronized (ActivityManagerService.this) {
21828                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
21829                        /*resultTo*/ null, bOptions, userId);
21830            }
21831        }
21832    }
21833
21834    private final class SleepTokenImpl extends SleepToken {
21835        private final String mTag;
21836        private final long mAcquireTime;
21837
21838        public SleepTokenImpl(String tag) {
21839            mTag = tag;
21840            mAcquireTime = SystemClock.uptimeMillis();
21841        }
21842
21843        @Override
21844        public void release() {
21845            synchronized (ActivityManagerService.this) {
21846                if (mSleepTokens.remove(this)) {
21847                    updateSleepIfNeededLocked();
21848                }
21849            }
21850        }
21851
21852        @Override
21853        public String toString() {
21854            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21855        }
21856    }
21857
21858    /**
21859     * An implementation of IAppTask, that allows an app to manage its own tasks via
21860     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21861     * only the process that calls getAppTasks() can call the AppTask methods.
21862     */
21863    class AppTaskImpl extends IAppTask.Stub {
21864        private int mTaskId;
21865        private int mCallingUid;
21866
21867        public AppTaskImpl(int taskId, int callingUid) {
21868            mTaskId = taskId;
21869            mCallingUid = callingUid;
21870        }
21871
21872        private void checkCaller() {
21873            if (mCallingUid != Binder.getCallingUid()) {
21874                throw new SecurityException("Caller " + mCallingUid
21875                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21876            }
21877        }
21878
21879        @Override
21880        public void finishAndRemoveTask() {
21881            checkCaller();
21882
21883            synchronized (ActivityManagerService.this) {
21884                long origId = Binder.clearCallingIdentity();
21885                try {
21886                    // We remove the task from recents to preserve backwards
21887                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21888                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21889                    }
21890                } finally {
21891                    Binder.restoreCallingIdentity(origId);
21892                }
21893            }
21894        }
21895
21896        @Override
21897        public ActivityManager.RecentTaskInfo getTaskInfo() {
21898            checkCaller();
21899
21900            synchronized (ActivityManagerService.this) {
21901                long origId = Binder.clearCallingIdentity();
21902                try {
21903                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21904                    if (tr == null) {
21905                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21906                    }
21907                    return createRecentTaskInfoFromTaskRecord(tr);
21908                } finally {
21909                    Binder.restoreCallingIdentity(origId);
21910                }
21911            }
21912        }
21913
21914        @Override
21915        public void moveToFront() {
21916            checkCaller();
21917            // Will bring task to front if it already has a root activity.
21918            final long origId = Binder.clearCallingIdentity();
21919            try {
21920                synchronized (this) {
21921                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21922                }
21923            } finally {
21924                Binder.restoreCallingIdentity(origId);
21925            }
21926        }
21927
21928        @Override
21929        public int startActivity(IBinder whoThread, String callingPackage,
21930                Intent intent, String resolvedType, Bundle bOptions) {
21931            checkCaller();
21932
21933            int callingUser = UserHandle.getCallingUserId();
21934            TaskRecord tr;
21935            IApplicationThread appThread;
21936            synchronized (ActivityManagerService.this) {
21937                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21938                if (tr == null) {
21939                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21940                }
21941                appThread = ApplicationThreadNative.asInterface(whoThread);
21942                if (appThread == null) {
21943                    throw new IllegalArgumentException("Bad app thread " + appThread);
21944                }
21945            }
21946            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21947                    resolvedType, null, null, null, null, 0, 0, null, null,
21948                    null, bOptions, false, callingUser, null, tr);
21949        }
21950
21951        @Override
21952        public void setExcludeFromRecents(boolean exclude) {
21953            checkCaller();
21954
21955            synchronized (ActivityManagerService.this) {
21956                long origId = Binder.clearCallingIdentity();
21957                try {
21958                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21959                    if (tr == null) {
21960                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21961                    }
21962                    Intent intent = tr.getBaseIntent();
21963                    if (exclude) {
21964                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21965                    } else {
21966                        intent.setFlags(intent.getFlags()
21967                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21968                    }
21969                } finally {
21970                    Binder.restoreCallingIdentity(origId);
21971                }
21972            }
21973        }
21974    }
21975
21976    /**
21977     * Kill processes for the user with id userId and that depend on the package named packageName
21978     */
21979    @Override
21980    public void killPackageDependents(String packageName, int userId) {
21981        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21982        if (packageName == null) {
21983            throw new NullPointerException(
21984                    "Cannot kill the dependents of a package without its name.");
21985        }
21986
21987        long callingId = Binder.clearCallingIdentity();
21988        IPackageManager pm = AppGlobals.getPackageManager();
21989        int pkgUid = -1;
21990        try {
21991            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21992        } catch (RemoteException e) {
21993        }
21994        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21995            throw new IllegalArgumentException(
21996                    "Cannot kill dependents of non-existing package " + packageName);
21997        }
21998        try {
21999            synchronized(this) {
22000                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22001                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22002                        "dep: " + packageName);
22003            }
22004        } finally {
22005            Binder.restoreCallingIdentity(callingId);
22006        }
22007    }
22008}
22009