ActivityManagerService.java revision fed503cb461f884b4589cadd6ee9d48381500749
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 android.app.ApplicationThreadConstants;
20import android.os.IDeviceIdentifiersPolicyService;
21import android.util.Size;
22import android.util.TypedValue;
23import android.view.DisplayInfo;
24import com.android.internal.telephony.TelephonyIntents;
25import com.google.android.collect.Lists;
26import com.google.android.collect.Maps;
27import com.android.internal.R;
28import com.android.internal.annotations.GuardedBy;
29import com.android.internal.app.AssistUtils;
30import com.android.internal.app.DumpHeapActivity;
31import com.android.internal.app.IAppOpsCallback;
32import com.android.internal.app.IAppOpsService;
33import com.android.internal.app.IVoiceInteractor;
34import com.android.internal.app.ProcessMap;
35import com.android.internal.app.SystemUserHomeActivity;
36import com.android.internal.app.procstats.ProcessStats;
37import com.android.internal.os.BackgroundThread;
38import com.android.internal.os.BatteryStatsImpl;
39import com.android.internal.os.IResultReceiver;
40import com.android.internal.os.ProcessCpuTracker;
41import com.android.internal.os.TransferPipe;
42import com.android.internal.os.Zygote;
43import com.android.internal.os.InstallerConnection.InstallerException;
44import com.android.internal.util.ArrayUtils;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.DeviceIdleController;
52import com.android.server.IntentResolver;
53import com.android.server.LocalServices;
54import com.android.server.LockGuard;
55import com.android.server.ServiceThread;
56import com.android.server.SystemService;
57import com.android.server.SystemServiceManager;
58import com.android.server.Watchdog;
59import com.android.server.am.ActivityStack.ActivityState;
60import com.android.server.firewall.IntentFirewall;
61import com.android.server.pm.Installer;
62import com.android.server.statusbar.StatusBarManagerInternal;
63import com.android.server.vr.VrManagerInternal;
64import com.android.server.wm.WindowManagerService;
65
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68import org.xmlpull.v1.XmlSerializer;
69
70import android.Manifest;
71import android.Manifest.permission;
72import android.annotation.NonNull;
73import android.annotation.UserIdInt;
74import android.app.Activity;
75import android.app.ActivityManager;
76import android.app.ActivityManager.RunningTaskInfo;
77import android.app.ActivityManager.StackId;
78import android.app.ActivityManager.StackInfo;
79import android.app.ActivityManager.TaskDescription;
80import android.app.ActivityManager.TaskThumbnailInfo;
81import android.app.ActivityManagerInternal;
82import android.app.ActivityManagerInternal.SleepToken;
83import android.app.ActivityManagerNative;
84import android.app.ActivityOptions;
85import android.app.ActivityThread;
86import android.app.AlertDialog;
87import android.app.AppGlobals;
88import android.app.AppOpsManager;
89import android.app.ApplicationErrorReport;
90import android.app.BroadcastOptions;
91import android.app.Dialog;
92import android.app.IActivityContainer;
93import android.app.IActivityContainerCallback;
94import android.app.IActivityController;
95import android.app.IAppTask;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.ITaskStackListener;
103import android.app.IUiAutomationConnection;
104import android.app.IUidObserver;
105import android.app.IUserSwitchObserver;
106import android.app.Instrumentation;
107import android.app.Notification;
108import android.app.NotificationManager;
109import android.app.PendingIntent;
110import android.app.ProfilerInfo;
111import android.app.admin.DevicePolicyManager;
112import android.app.assist.AssistContent;
113import android.app.assist.AssistStructure;
114import android.app.backup.IBackupManager;
115import android.app.usage.UsageEvents;
116import android.app.usage.UsageStatsManagerInternal;
117import android.appwidget.AppWidgetManager;
118import android.content.ActivityNotFoundException;
119import android.content.BroadcastReceiver;
120import android.content.ClipData;
121import android.content.ComponentCallbacks2;
122import android.content.ComponentName;
123import android.content.ContentProvider;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.DialogInterface;
127import android.content.IContentProvider;
128import android.content.IIntentReceiver;
129import android.content.IIntentSender;
130import android.content.Intent;
131import android.content.IntentFilter;
132import android.content.IntentSender;
133import android.content.pm.ActivityInfo;
134import android.content.pm.ApplicationInfo;
135import android.content.pm.ConfigurationInfo;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageManager;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.PackageInfo;
140import android.content.pm.PackageManager;
141import android.content.pm.PackageManager.NameNotFoundException;
142import android.content.pm.PackageManagerInternal;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.PathPermission;
145import android.content.pm.PermissionInfo;
146import android.content.pm.ProviderInfo;
147import android.content.pm.ResolveInfo;
148import android.content.pm.ServiceInfo;
149import android.content.pm.UserInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.content.res.Resources;
153import android.database.ContentObserver;
154import android.graphics.Bitmap;
155import android.graphics.Point;
156import android.graphics.Rect;
157import android.location.LocationManager;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.BatteryStats;
162import android.os.Binder;
163import android.os.Build;
164import android.os.Bundle;
165import android.os.Debug;
166import android.os.DropBoxManager;
167import android.os.Environment;
168import android.os.FactoryTest;
169import android.os.FileObserver;
170import android.os.FileUtils;
171import android.os.Handler;
172import android.os.IBinder;
173import android.os.IPermissionController;
174import android.os.IProcessInfoService;
175import android.os.IProgressListener;
176import android.os.LocaleList;
177import android.os.Looper;
178import android.os.Message;
179import android.os.Parcel;
180import android.os.ParcelFileDescriptor;
181import android.os.PersistableBundle;
182import android.os.PowerManager;
183import android.os.PowerManagerInternal;
184import android.os.Process;
185import android.os.RemoteCallbackList;
186import android.os.RemoteException;
187import android.os.ResultReceiver;
188import android.os.ServiceManager;
189import android.os.ShellCallback;
190import android.os.StrictMode;
191import android.os.SystemClock;
192import android.os.SystemProperties;
193import android.os.Trace;
194import android.os.TransactionTooLargeException;
195import android.os.UpdateLock;
196import android.os.UserHandle;
197import android.os.UserManager;
198import android.os.WorkSource;
199import android.os.storage.IMountService;
200import android.os.storage.MountServiceInternal;
201import android.os.storage.StorageManager;
202import android.provider.Settings;
203import android.service.voice.IVoiceInteractionSession;
204import android.service.voice.VoiceInteractionManagerInternal;
205import android.service.voice.VoiceInteractionSession;
206import android.telecom.TelecomManager;
207import android.text.format.DateUtils;
208import android.text.format.Time;
209import android.text.style.SuggestionSpan;
210import android.util.ArrayMap;
211import android.util.ArraySet;
212import android.util.AtomicFile;
213import android.util.DebugUtils;
214import android.util.DisplayMetrics;
215import android.util.EventLog;
216import android.util.Log;
217import android.util.Pair;
218import android.util.PrintWriterPrinter;
219import android.util.Slog;
220import android.util.SparseArray;
221import android.util.TimeUtils;
222import android.util.Xml;
223import android.view.Gravity;
224import android.view.LayoutInflater;
225import android.view.View;
226import android.view.WindowManager;
227
228import java.io.File;
229import java.io.FileDescriptor;
230import java.io.FileInputStream;
231import java.io.FileNotFoundException;
232import java.io.FileOutputStream;
233import java.io.IOException;
234import java.io.InputStreamReader;
235import java.io.PrintWriter;
236import java.io.StringWriter;
237import java.lang.ref.WeakReference;
238import java.nio.charset.StandardCharsets;
239import java.util.ArrayList;
240import java.util.Arrays;
241import java.util.Collections;
242import java.util.Comparator;
243import java.util.HashMap;
244import java.util.HashSet;
245import java.util.Iterator;
246import java.util.List;
247import java.util.Locale;
248import java.util.Map;
249import java.util.Objects;
250import java.util.Set;
251import java.util.concurrent.atomic.AtomicBoolean;
252import java.util.concurrent.atomic.AtomicLong;
253
254import dalvik.system.VMRuntime;
255
256import libcore.io.IoUtils;
257import libcore.util.EmptyArray;
258
259import static android.Manifest.permission.CHANGE_CONFIGURATION;
260import static android.Manifest.permission.INTERACT_ACROSS_USERS;
261import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
262import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
263import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
264import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
265import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
266import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
267import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
268import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
269import static android.app.ActivityManager.StackId.HOME_STACK_ID;
270import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
271import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
272import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
273import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
274import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
275import static android.content.pm.PackageManager.GET_PROVIDERS;
276import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
277import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
278import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
279import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
280import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
281import static android.content.pm.PackageManager.PERMISSION_GRANTED;
282import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
283import static android.os.Build.VERSION_CODES.N;
284import static android.os.Process.PROC_CHAR;
285import static android.os.Process.PROC_OUT_LONG;
286import static android.os.Process.PROC_PARENS;
287import static android.os.Process.PROC_SPACE_TERM;
288import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
289import static android.provider.Settings.Global.DEBUG_APP;
290import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
291import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
292import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
293import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
294import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
295import static android.provider.Settings.System.FONT_SCALE;
296import static android.util.TypedValue.COMPLEX_UNIT_DIP;
297import static android.view.Display.DEFAULT_DISPLAY;
298
299import static com.android.internal.util.XmlUtils.readBooleanAttribute;
300import static com.android.internal.util.XmlUtils.readIntAttribute;
301import static com.android.internal.util.XmlUtils.readLongAttribute;
302import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
303import static com.android.internal.util.XmlUtils.writeIntAttribute;
304import static com.android.internal.util.XmlUtils.writeLongAttribute;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
362import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
363import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
364import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
365import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
366import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
367import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
368import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
369import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
370import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
371import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
372import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
373import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
374import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
375import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
376import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
377import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
378import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
379import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
380import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
381import static org.xmlpull.v1.XmlPullParser.START_TAG;
382
383public final class ActivityManagerService extends ActivityManagerNative
384        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
385
386    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
387    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
388    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
389    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
390    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
391    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
392    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
393    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
394    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
395    private static final String TAG_LRU = TAG + POSTFIX_LRU;
396    private static final String TAG_MU = TAG + POSTFIX_MU;
397    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
398    private static final String TAG_POWER = TAG + POSTFIX_POWER;
399    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
400    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
401    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
402    private static final String TAG_PSS = TAG + POSTFIX_PSS;
403    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
404    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
405    private static final String TAG_STACK = TAG + POSTFIX_STACK;
406    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
407    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
408    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
409    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
410    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
411
412    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
413    // here so that while the job scheduler can depend on AMS, the other way around
414    // need not be the case.
415    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
416
417    /** Control over CPU and battery monitoring */
418    // write battery stats every 30 minutes.
419    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
420    static final boolean MONITOR_CPU_USAGE = true;
421    // don't sample cpu less than every 5 seconds.
422    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
423    // wait possibly forever for next cpu sample.
424    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
425    static final boolean MONITOR_THREAD_CPU_USAGE = false;
426
427    // The flags that are set for all calls we make to the package manager.
428    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
429
430    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
431
432    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
433
434    // Amount of time after a call to stopAppSwitches() during which we will
435    // prevent further untrusted switches from happening.
436    static final long APP_SWITCH_DELAY_TIME = 5*1000;
437
438    // How long we wait for a launched process to attach to the activity manager
439    // before we decide it's never going to come up for real.
440    static final int PROC_START_TIMEOUT = 10*1000;
441    // How long we wait for an attached process to publish its content providers
442    // before we decide it must be hung.
443    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
444
445    // How long we will retain processes hosting content providers in the "last activity"
446    // state before allowing them to drop down to the regular cached LRU list.  This is
447    // to avoid thrashing of provider processes under low memory situations.
448    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
449
450    // How long we wait for a launched process to attach to the activity manager
451    // before we decide it's never going to come up for real, when the process was
452    // started with a wrapper for instrumentation (such as Valgrind) because it
453    // could take much longer than usual.
454    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
455
456    // How long to wait after going idle before forcing apps to GC.
457    static final int GC_TIMEOUT = 5*1000;
458
459    // The minimum amount of time between successive GC requests for a process.
460    static final int GC_MIN_INTERVAL = 60*1000;
461
462    // The minimum amount of time between successive PSS requests for a process.
463    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
464
465    // The minimum amount of time between successive PSS requests for a process
466    // when the request is due to the memory state being lowered.
467    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
468
469    // The rate at which we check for apps using excessive power -- 15 mins.
470    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
471
472    // The minimum sample duration we will allow before deciding we have
473    // enough data on wake locks to start killing things.
474    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
475
476    // The minimum sample duration we will allow before deciding we have
477    // enough data on CPU usage to start killing things.
478    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
479
480    // How long we allow a receiver to run before giving up on it.
481    static final int BROADCAST_FG_TIMEOUT = 10*1000;
482    static final int BROADCAST_BG_TIMEOUT = 60*1000;
483
484    // How long we wait until we timeout on key dispatching.
485    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
486
487    // How long we wait until we timeout on key dispatching during instrumentation.
488    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
489
490    // This is the amount of time an app needs to be running a foreground service before
491    // we will consider it to be doing interaction for usage stats.
492    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
493
494    // Maximum amount of time we will allow to elapse before re-reporting usage stats
495    // interaction with foreground processes.
496    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
497
498    // This is the amount of time we allow an app to settle after it goes into the background,
499    // before we start restricting what it can do.
500    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
501
502    // How long to wait in getAssistContextExtras for the activity and foreground services
503    // to respond with the result.
504    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
505
506    // How long top wait when going through the modern assist (which doesn't need to block
507    // on getting this result before starting to launch its UI).
508    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
509
510    // Maximum number of persisted Uri grants a package is allowed
511    static final int MAX_PERSISTED_URI_GRANTS = 128;
512
513    static final int MY_PID = Process.myPid();
514
515    static final String[] EMPTY_STRING_ARRAY = new String[0];
516
517    // How many bytes to write into the dropbox log before truncating
518    static final int DROPBOX_MAX_SIZE = 192 * 1024;
519    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
520    // as one line, but close enough for now.
521    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
522
523    // Access modes for handleIncomingUser.
524    static final int ALLOW_NON_FULL = 0;
525    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
526    static final int ALLOW_FULL_ONLY = 2;
527
528    // Necessary ApplicationInfo flags to mark an app as persistent
529    private static final int PERSISTENT_MASK =
530            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
531
532    // Intent sent when remote bugreport collection has been completed
533    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
534            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
535
536    // Used to indicate that a task is removed it should also be removed from recents.
537    private static final boolean REMOVE_FROM_RECENTS = true;
538    // Used to indicate that an app transition should be animated.
539    static final boolean ANIMATE = true;
540
541    // Determines whether to take full screen screenshots
542    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
543    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544
545    /** All system services */
546    SystemServiceManager mSystemServiceManager;
547
548    private Installer mInstaller;
549
550    /** Run all ActivityStacks through this */
551    final ActivityStackSupervisor mStackSupervisor;
552
553    final ActivityStarter mActivityStarter;
554
555    final TaskChangeNotificationController mTaskChangeNotificationController;
556
557    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559    public IntentFirewall mIntentFirewall;
560
561    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562    // default action automatically.  Important for devices without direct input
563    // devices.
564    private boolean mShowDialogs = true;
565    private boolean mInVrMode = false;
566
567    // Whether we should use SCHED_FIFO for UI and RenderThreads.
568    private boolean mUseFifoUiScheduling = false;
569
570    BroadcastQueue mFgBroadcastQueue;
571    BroadcastQueue mBgBroadcastQueue;
572    // Convenient for easy iteration over the queues. Foreground is first
573    // so that dispatch of foreground broadcasts gets precedence.
574    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
575
576    BroadcastStats mLastBroadcastStats;
577    BroadcastStats mCurBroadcastStats;
578
579    BroadcastQueue broadcastQueueForIntent(Intent intent) {
580        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
581        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
582                "Broadcast intent " + intent + " on "
583                + (isFg ? "foreground" : "background") + " queue");
584        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
585    }
586
587    /**
588     * The last resumed activity. This is identical to the current resumed activity most
589     * of the time but could be different when we're pausing one activity before we resume
590     * another activity.
591     */
592    private ActivityRecord mLastResumedActivity;
593
594    /**
595     * If non-null, we are tracking the time the user spends in the currently focused app.
596     */
597    private AppTimeTracker mCurAppTimeTracker;
598
599    /**
600     * List of intents that were used to start the most recent tasks.
601     */
602    final RecentTasks mRecentTasks;
603
604    /**
605     * For addAppTask: cached of the last activity component that was added.
606     */
607    ComponentName mLastAddedTaskComponent;
608
609    /**
610     * For addAppTask: cached of the last activity uid that was added.
611     */
612    int mLastAddedTaskUid;
613
614    /**
615     * For addAppTask: cached of the last ActivityInfo that was added.
616     */
617    ActivityInfo mLastAddedTaskActivity;
618
619    /**
620     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
621     */
622    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
623
624    /**
625     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
626     */
627    String mDeviceOwnerName;
628
629    final UserController mUserController;
630
631    final AppErrors mAppErrors;
632
633    public boolean canShowErrorDialogs() {
634        return mShowDialogs && !mSleeping && !mShuttingDown
635                && mLockScreenShown != LOCK_SCREEN_SHOWN;
636    }
637
638    private static final class PriorityState {
639        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
640        // the current thread is currently in. When it drops down to zero, we will no longer boost
641        // the thread's priority.
642        private int regionCounter = 0;
643
644        // The thread's previous priority before boosting.
645        private int prevPriority = Integer.MIN_VALUE;
646    }
647
648    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
649        @Override protected PriorityState initialValue() {
650            return new PriorityState();
651        }
652    };
653
654    static void boostPriorityForLockedSection() {
655        int tid = Process.myTid();
656        int prevPriority = Process.getThreadPriority(tid);
657        PriorityState state = sThreadPriorityState.get();
658        if (state.regionCounter == 0 && prevPriority > -2) {
659            state.prevPriority = prevPriority;
660            Process.setThreadPriority(tid, -2);
661        }
662        state.regionCounter++;
663    }
664
665    static void resetPriorityAfterLockedSection() {
666        PriorityState state = sThreadPriorityState.get();
667        state.regionCounter--;
668        if (state.regionCounter == 0 && state.prevPriority > -2) {
669            Process.setThreadPriority(Process.myTid(), state.prevPriority);
670        }
671    }
672
673    public class PendingAssistExtras extends Binder implements Runnable {
674        public final ActivityRecord activity;
675        public final Bundle extras;
676        public final Intent intent;
677        public final String hint;
678        public final IResultReceiver receiver;
679        public final int userHandle;
680        public boolean haveResult = false;
681        public Bundle result = null;
682        public AssistStructure structure = null;
683        public AssistContent content = null;
684        public Bundle receiverExtras;
685
686        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
687                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
688            activity = _activity;
689            extras = _extras;
690            intent = _intent;
691            hint = _hint;
692            receiver = _receiver;
693            receiverExtras = _receiverExtras;
694            userHandle = _userHandle;
695        }
696        @Override
697        public void run() {
698            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
699            synchronized (this) {
700                haveResult = true;
701                notifyAll();
702            }
703            pendingAssistExtrasTimedOut(this);
704        }
705    }
706
707    final ArrayList<PendingAssistExtras> mPendingAssistExtras
708            = new ArrayList<PendingAssistExtras>();
709
710    /**
711     * Process management.
712     */
713    final ProcessList mProcessList = new ProcessList();
714
715    /**
716     * All of the applications we currently have running organized by name.
717     * The keys are strings of the application package name (as
718     * returned by the package manager), and the keys are ApplicationRecord
719     * objects.
720     */
721    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
722
723    /**
724     * Tracking long-term execution of processes to look for abuse and other
725     * bad app behavior.
726     */
727    final ProcessStatsService mProcessStats;
728
729    /**
730     * The currently running isolated processes.
731     */
732    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
733
734    /**
735     * Counter for assigning isolated process uids, to avoid frequently reusing the
736     * same ones.
737     */
738    int mNextIsolatedProcessUid = 0;
739
740    /**
741     * The currently running heavy-weight process, if any.
742     */
743    ProcessRecord mHeavyWeightProcess = null;
744
745    /**
746     * All of the processes we currently have running organized by pid.
747     * The keys are the pid running the application.
748     *
749     * <p>NOTE: This object is protected by its own lock, NOT the global
750     * activity manager lock!
751     */
752    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
753
754    /**
755     * All of the processes that have been forced to be foreground.  The key
756     * is the pid of the caller who requested it (we hold a death
757     * link on it).
758     */
759    abstract class ForegroundToken implements IBinder.DeathRecipient {
760        int pid;
761        IBinder token;
762    }
763    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
764
765    /**
766     * List of records for processes that someone had tried to start before the
767     * system was ready.  We don't start them at that point, but ensure they
768     * are started by the time booting is complete.
769     */
770    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
771
772    /**
773     * List of persistent applications that are in the process
774     * of being started.
775     */
776    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
777
778    /**
779     * Processes that are being forcibly torn down.
780     */
781    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * List of running applications, sorted by recent usage.
785     * The first entry in the list is the least recently used.
786     */
787    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
788
789    /**
790     * Where in mLruProcesses that the processes hosting activities start.
791     */
792    int mLruProcessActivityStart = 0;
793
794    /**
795     * Where in mLruProcesses that the processes hosting services start.
796     * This is after (lower index) than mLruProcessesActivityStart.
797     */
798    int mLruProcessServiceStart = 0;
799
800    /**
801     * List of processes that should gc as soon as things are idle.
802     */
803    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
804
805    /**
806     * Processes we want to collect PSS data from.
807     */
808    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
809
810    private boolean mBinderTransactionTrackingEnabled = false;
811
812    /**
813     * Last time we requested PSS data of all processes.
814     */
815    long mLastFullPssTime = SystemClock.uptimeMillis();
816
817    /**
818     * If set, the next time we collect PSS data we should do a full collection
819     * with data from native processes and the kernel.
820     */
821    boolean mFullPssPending = false;
822
823    /**
824     * This is the process holding what we currently consider to be
825     * the "home" activity.
826     */
827    ProcessRecord mHomeProcess;
828
829    /**
830     * This is the process holding the activity the user last visited that
831     * is in a different process from the one they are currently in.
832     */
833    ProcessRecord mPreviousProcess;
834
835    /**
836     * The time at which the previous process was last visible.
837     */
838    long mPreviousProcessVisibleTime;
839
840    /**
841     * Track all uids that have actively running processes.
842     */
843    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
844
845    /**
846     * This is for verifying the UID report flow.
847     */
848    static final boolean VALIDATE_UID_STATES = true;
849    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
850
851    /**
852     * Packages that the user has asked to have run in screen size
853     * compatibility mode instead of filling the screen.
854     */
855    final CompatModePackages mCompatModePackages;
856
857    /**
858     * Set of IntentSenderRecord objects that are currently active.
859     */
860    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
861            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
862
863    /**
864     * Fingerprints (hashCode()) of stack traces that we've
865     * already logged DropBox entries for.  Guarded by itself.  If
866     * something (rogue user app) forces this over
867     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
868     */
869    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
870    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
871
872    /**
873     * Strict Mode background batched logging state.
874     *
875     * The string buffer is guarded by itself, and its lock is also
876     * used to determine if another batched write is already
877     * in-flight.
878     */
879    private final StringBuilder mStrictModeBuffer = new StringBuilder();
880
881    /**
882     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
883     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
884     */
885    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
886
887    /**
888     * Resolver for broadcast intents to registered receivers.
889     * Holds BroadcastFilter (subclass of IntentFilter).
890     */
891    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
892            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
893        @Override
894        protected boolean allowFilterResult(
895                BroadcastFilter filter, List<BroadcastFilter> dest) {
896            IBinder target = filter.receiverList.receiver.asBinder();
897            for (int i = dest.size() - 1; i >= 0; i--) {
898                if (dest.get(i).receiverList.receiver.asBinder() == target) {
899                    return false;
900                }
901            }
902            return true;
903        }
904
905        @Override
906        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
907            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
908                    || userId == filter.owningUserId) {
909                return super.newResult(filter, match, userId);
910            }
911            return null;
912        }
913
914        @Override
915        protected BroadcastFilter[] newArray(int size) {
916            return new BroadcastFilter[size];
917        }
918
919        @Override
920        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
921            return packageName.equals(filter.packageName);
922        }
923    };
924
925    /**
926     * State of all active sticky broadcasts per user.  Keys are the action of the
927     * sticky Intent, values are an ArrayList of all broadcasted intents with
928     * that action (which should usually be one).  The SparseArray is keyed
929     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
930     * for stickies that are sent to all users.
931     */
932    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
933            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
934
935    final ActiveServices mServices;
936
937    final static class Association {
938        final int mSourceUid;
939        final String mSourceProcess;
940        final int mTargetUid;
941        final ComponentName mTargetComponent;
942        final String mTargetProcess;
943
944        int mCount;
945        long mTime;
946
947        int mNesting;
948        long mStartTime;
949
950        // states of the source process when the bind occurred.
951        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
952        long mLastStateUptime;
953        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
954                - ActivityManager.MIN_PROCESS_STATE+1];
955
956        Association(int sourceUid, String sourceProcess, int targetUid,
957                ComponentName targetComponent, String targetProcess) {
958            mSourceUid = sourceUid;
959            mSourceProcess = sourceProcess;
960            mTargetUid = targetUid;
961            mTargetComponent = targetComponent;
962            mTargetProcess = targetProcess;
963        }
964    }
965
966    /**
967     * When service association tracking is enabled, this is all of the associations we
968     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
969     * -> association data.
970     */
971    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
972            mAssociations = new SparseArray<>();
973    boolean mTrackingAssociations;
974
975    /**
976     * Backup/restore process management
977     */
978    String mBackupAppName = null;
979    BackupRecord mBackupTarget = null;
980
981    final ProviderMap mProviderMap;
982
983    /**
984     * List of content providers who have clients waiting for them.  The
985     * application is currently being launched and the provider will be
986     * removed from this list once it is published.
987     */
988    final ArrayList<ContentProviderRecord> mLaunchingProviders
989            = new ArrayList<ContentProviderRecord>();
990
991    /**
992     * File storing persisted {@link #mGrantedUriPermissions}.
993     */
994    private final AtomicFile mGrantFile;
995
996    /** XML constants used in {@link #mGrantFile} */
997    private static final String TAG_URI_GRANTS = "uri-grants";
998    private static final String TAG_URI_GRANT = "uri-grant";
999    private static final String ATTR_USER_HANDLE = "userHandle";
1000    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1001    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1002    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1003    private static final String ATTR_TARGET_PKG = "targetPkg";
1004    private static final String ATTR_URI = "uri";
1005    private static final String ATTR_MODE_FLAGS = "modeFlags";
1006    private static final String ATTR_CREATED_TIME = "createdTime";
1007    private static final String ATTR_PREFIX = "prefix";
1008
1009    /**
1010     * Global set of specific {@link Uri} permissions that have been granted.
1011     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1012     * to {@link UriPermission#uri} to {@link UriPermission}.
1013     */
1014    @GuardedBy("this")
1015    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1016            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1017
1018    public static class GrantUri {
1019        public final int sourceUserId;
1020        public final Uri uri;
1021        public boolean prefix;
1022
1023        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1024            this.sourceUserId = sourceUserId;
1025            this.uri = uri;
1026            this.prefix = prefix;
1027        }
1028
1029        @Override
1030        public int hashCode() {
1031            int hashCode = 1;
1032            hashCode = 31 * hashCode + sourceUserId;
1033            hashCode = 31 * hashCode + uri.hashCode();
1034            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1035            return hashCode;
1036        }
1037
1038        @Override
1039        public boolean equals(Object o) {
1040            if (o instanceof GrantUri) {
1041                GrantUri other = (GrantUri) o;
1042                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1043                        && prefix == other.prefix;
1044            }
1045            return false;
1046        }
1047
1048        @Override
1049        public String toString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public String toSafeString() {
1056            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1057            if (prefix) result += " [prefix]";
1058            return result;
1059        }
1060
1061        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1062            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1063                    ContentProvider.getUriWithoutUserId(uri), false);
1064        }
1065    }
1066
1067    CoreSettingsObserver mCoreSettingsObserver;
1068
1069    FontScaleSettingObserver mFontScaleSettingObserver;
1070
1071    private final class FontScaleSettingObserver extends ContentObserver {
1072        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1073
1074        public FontScaleSettingObserver() {
1075            super(mHandler);
1076            ContentResolver resolver = mContext.getContentResolver();
1077            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1078        }
1079
1080        @Override
1081        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1082            if (mFontScaleUri.equals(uri)) {
1083                updateFontScaleIfNeeded(userId);
1084            }
1085        }
1086    }
1087
1088    /**
1089     * Thread-local storage used to carry caller permissions over through
1090     * indirect content-provider access.
1091     */
1092    private class Identity {
1093        public final IBinder token;
1094        public final int pid;
1095        public final int uid;
1096
1097        Identity(IBinder _token, int _pid, int _uid) {
1098            token = _token;
1099            pid = _pid;
1100            uid = _uid;
1101        }
1102    }
1103
1104    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1105
1106    /**
1107     * All information we have collected about the runtime performance of
1108     * any user id that can impact battery performance.
1109     */
1110    final BatteryStatsService mBatteryStatsService;
1111
1112    /**
1113     * Information about component usage
1114     */
1115    UsageStatsManagerInternal mUsageStatsService;
1116
1117    /**
1118     * Access to DeviceIdleController service.
1119     */
1120    DeviceIdleController.LocalService mLocalDeviceIdleController;
1121
1122    /**
1123     * Information about and control over application operations
1124     */
1125    final AppOpsService mAppOpsService;
1126
1127    /** Current sequencing integer of the configuration, for skipping old configurations. */
1128    private int mConfigurationSeq;
1129
1130    /**
1131     * Temp object used when global and/or display override configuration is updated. It is also
1132     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1133     * anyone...
1134     */
1135    private Configuration mTempConfig = new Configuration();
1136
1137    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1138            new UpdateConfigurationResult();
1139    private static final class UpdateConfigurationResult {
1140        // Configuration changes that were updated.
1141        int changes;
1142        // If the activity was relaunched to match the new configuration.
1143        boolean activityRelaunched;
1144
1145        void reset() {
1146            changes = 0;
1147            activityRelaunched = false;
1148        }
1149    }
1150
1151    boolean mSuppressResizeConfigChanges;
1152
1153    /**
1154     * Hardware-reported OpenGLES version.
1155     */
1156    final int GL_ES_VERSION;
1157
1158    /**
1159     * List of initialization arguments to pass to all processes when binding applications to them.
1160     * For example, references to the commonly used services.
1161     */
1162    HashMap<String, IBinder> mAppBindArgs;
1163    HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165    /**
1166     * Temporary to avoid allocations.  Protected by main lock.
1167     */
1168    final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170    /**
1171     * Used to control how we initialize the service.
1172     */
1173    ComponentName mTopComponent;
1174    String mTopAction = Intent.ACTION_MAIN;
1175    String mTopData;
1176
1177    volatile boolean mProcessesReady = false;
1178    volatile boolean mSystemReady = false;
1179    volatile boolean mOnBattery = false;
1180    volatile int mFactoryTest;
1181
1182    @GuardedBy("this") boolean mBooting = false;
1183    @GuardedBy("this") boolean mCallFinishBooting = false;
1184    @GuardedBy("this") boolean mBootAnimationComplete = false;
1185    @GuardedBy("this") boolean mLaunchWarningShown = false;
1186    @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188    Context mContext;
1189
1190    /**
1191     * The time at which we will allow normal application switches again,
1192     * after a call to {@link #stopAppSwitches()}.
1193     */
1194    long mAppSwitchesAllowedTime;
1195
1196    /**
1197     * This is set to true after the first switch after mAppSwitchesAllowedTime
1198     * is set; any switches after that will clear the time.
1199     */
1200    boolean mDidAppSwitch;
1201
1202    /**
1203     * Last time (in realtime) at which we checked for power usage.
1204     */
1205    long mLastPowerCheckRealtime;
1206
1207    /**
1208     * Last time (in uptime) at which we checked for power usage.
1209     */
1210    long mLastPowerCheckUptime;
1211
1212    /**
1213     * Set while we are wanting to sleep, to prevent any
1214     * activities from being started/resumed.
1215     */
1216    private boolean mSleeping = false;
1217
1218    /**
1219     * The process state used for processes that are running the top activities.
1220     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221     */
1222    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1223
1224    /**
1225     * Set while we are running a voice interaction.  This overrides
1226     * sleeping while it is active.
1227     */
1228    private IVoiceInteractionSession mRunningVoice;
1229
1230    /**
1231     * For some direct access we need to power manager.
1232     */
1233    PowerManagerInternal mLocalPowerManager;
1234
1235    /**
1236     * We want to hold a wake lock while running a voice interaction session, since
1237     * this may happen with the screen off and we need to keep the CPU running to
1238     * be able to continue to interact with the user.
1239     */
1240    PowerManager.WakeLock mVoiceWakeLock;
1241
1242    /**
1243     * State of external calls telling us if the device is awake or asleep.
1244     */
1245    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1246
1247    /**
1248     * A list of tokens that cause the top activity to be put to sleep.
1249     * They are used by components that may hide and block interaction with underlying
1250     * activities.
1251     */
1252    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253
1254    static final int LOCK_SCREEN_HIDDEN = 0;
1255    static final int LOCK_SCREEN_LEAVING = 1;
1256    static final int LOCK_SCREEN_SHOWN = 2;
1257    /**
1258     * State of external call telling us if the lock screen is shown.
1259     */
1260    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1261
1262    /**
1263     * Set if we are shutting down the system, similar to sleeping.
1264     */
1265    boolean mShuttingDown = false;
1266
1267    /**
1268     * Current sequence id for oom_adj computation traversal.
1269     */
1270    int mAdjSeq = 0;
1271
1272    /**
1273     * Current sequence id for process LRU updating.
1274     */
1275    int mLruSeq = 0;
1276
1277    /**
1278     * Keep track of the non-cached/empty process we last found, to help
1279     * determine how to distribute cached/empty processes next time.
1280     */
1281    int mNumNonCachedProcs = 0;
1282
1283    /**
1284     * Keep track of the number of cached hidden procs, to balance oom adj
1285     * distribution between those and empty procs.
1286     */
1287    int mNumCachedHiddenProcs = 0;
1288
1289    /**
1290     * Keep track of the number of service processes we last found, to
1291     * determine on the next iteration which should be B services.
1292     */
1293    int mNumServiceProcs = 0;
1294    int mNewNumAServiceProcs = 0;
1295    int mNewNumServiceProcs = 0;
1296
1297    /**
1298     * Allow the current computed overall memory level of the system to go down?
1299     * This is set to false when we are killing processes for reasons other than
1300     * memory management, so that the now smaller process list will not be taken as
1301     * an indication that memory is tighter.
1302     */
1303    boolean mAllowLowerMemLevel = false;
1304
1305    /**
1306     * The last computed memory level, for holding when we are in a state that
1307     * processes are going away for other reasons.
1308     */
1309    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1310
1311    /**
1312     * The last total number of process we have, to determine if changes actually look
1313     * like a shrinking number of process due to lower RAM.
1314     */
1315    int mLastNumProcesses;
1316
1317    /**
1318     * The uptime of the last time we performed idle maintenance.
1319     */
1320    long mLastIdleTime = SystemClock.uptimeMillis();
1321
1322    /**
1323     * Total time spent with RAM that has been added in the past since the last idle time.
1324     */
1325    long mLowRamTimeSinceLastIdle = 0;
1326
1327    /**
1328     * If RAM is currently low, when that horrible situation started.
1329     */
1330    long mLowRamStartTime = 0;
1331
1332    /**
1333     * For reporting to battery stats the current top application.
1334     */
1335    private String mCurResumedPackage = null;
1336    private int mCurResumedUid = -1;
1337
1338    /**
1339     * For reporting to battery stats the apps currently running foreground
1340     * service.  The ProcessMap is package/uid tuples; each of these contain
1341     * an array of the currently foreground processes.
1342     */
1343    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344            = new ProcessMap<ArrayList<ProcessRecord>>();
1345
1346    /**
1347     * This is set if we had to do a delayed dexopt of an app before launching
1348     * it, to increase the ANR timeouts in that case.
1349     */
1350    boolean mDidDexOpt;
1351
1352    /**
1353     * Set if the systemServer made a call to enterSafeMode.
1354     */
1355    boolean mSafeMode;
1356
1357    /**
1358     * If true, we are running under a test environment so will sample PSS from processes
1359     * much more rapidly to try to collect better data when the tests are rapidly
1360     * running through apps.
1361     */
1362    boolean mTestPssMode = false;
1363
1364    String mDebugApp = null;
1365    boolean mWaitForDebugger = false;
1366    boolean mDebugTransient = false;
1367    String mOrigDebugApp = null;
1368    boolean mOrigWaitForDebugger = false;
1369    boolean mAlwaysFinishActivities = false;
1370    boolean mLenientBackgroundCheck = false;
1371    boolean mForceResizableActivities;
1372    boolean mSupportsMultiWindow;
1373    boolean mSupportsFreeformWindowManagement;
1374    boolean mSupportsPictureInPicture;
1375    boolean mSupportsLeanbackOnly;
1376    IActivityController mController = null;
1377    boolean mControllerIsAMonkey = false;
1378    String mProfileApp = null;
1379    ProcessRecord mProfileProc = null;
1380    String mProfileFile;
1381    ParcelFileDescriptor mProfileFd;
1382    int mSamplingInterval = 0;
1383    boolean mAutoStopProfiler = false;
1384    int mProfileType = 0;
1385    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386    String mMemWatchDumpProcName;
1387    String mMemWatchDumpFile;
1388    int mMemWatchDumpPid;
1389    int mMemWatchDumpUid;
1390    String mTrackAllocationApp = null;
1391    String mNativeDebuggingApp = null;
1392
1393    final long[] mTmpLong = new long[2];
1394
1395    // The size and position information that describes where the pinned stack will go by default.
1396    // In particular, the size is defined in DPs.
1397    Size mDefaultPinnedStackSizeDp;
1398    Size mDefaultPinnedStackScreenEdgeInsetsDp;
1399    int mDefaultPinnedStackGravity;
1400
1401    static final class ProcessChangeItem {
1402        static final int CHANGE_ACTIVITIES = 1<<0;
1403        static final int CHANGE_PROCESS_STATE = 1<<1;
1404        int changes;
1405        int uid;
1406        int pid;
1407        int processState;
1408        boolean foregroundActivities;
1409    }
1410
1411    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1412    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1413
1414    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1415    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1416
1417    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1418    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1419
1420    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1421    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1422
1423    /**
1424     * Runtime CPU use collection thread.  This object's lock is used to
1425     * perform synchronization with the thread (notifying it to run).
1426     */
1427    final Thread mProcessCpuThread;
1428
1429    /**
1430     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1431     * Must acquire this object's lock when accessing it.
1432     * NOTE: this lock will be held while doing long operations (trawling
1433     * through all processes in /proc), so it should never be acquired by
1434     * any critical paths such as when holding the main activity manager lock.
1435     */
1436    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1437            MONITOR_THREAD_CPU_USAGE);
1438    final AtomicLong mLastCpuTime = new AtomicLong(0);
1439    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1440
1441    long mLastWriteTime = 0;
1442
1443    /**
1444     * Used to retain an update lock when the foreground activity is in
1445     * immersive mode.
1446     */
1447    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1448
1449    /**
1450     * Set to true after the system has finished booting.
1451     */
1452    boolean mBooted = false;
1453
1454    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1455    int mProcessLimitOverride = -1;
1456
1457    WindowManagerService mWindowManager;
1458    final ActivityThread mSystemThread;
1459
1460    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1461        final ProcessRecord mApp;
1462        final int mPid;
1463        final IApplicationThread mAppThread;
1464
1465        AppDeathRecipient(ProcessRecord app, int pid,
1466                IApplicationThread thread) {
1467            if (DEBUG_ALL) Slog.v(
1468                TAG, "New death recipient " + this
1469                + " for thread " + thread.asBinder());
1470            mApp = app;
1471            mPid = pid;
1472            mAppThread = thread;
1473        }
1474
1475        @Override
1476        public void binderDied() {
1477            if (DEBUG_ALL) Slog.v(
1478                TAG, "Death received in " + this
1479                + " for thread " + mAppThread.asBinder());
1480            synchronized(ActivityManagerService.this) {
1481                appDiedLocked(mApp, mPid, mAppThread, true);
1482            }
1483        }
1484    }
1485
1486    static final int SHOW_ERROR_UI_MSG = 1;
1487    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1488    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1489    static final int UPDATE_CONFIGURATION_MSG = 4;
1490    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1491    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1492    static final int SERVICE_TIMEOUT_MSG = 12;
1493    static final int UPDATE_TIME_ZONE = 13;
1494    static final int SHOW_UID_ERROR_UI_MSG = 14;
1495    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1496    static final int PROC_START_TIMEOUT_MSG = 20;
1497    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1498    static final int KILL_APPLICATION_MSG = 22;
1499    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1500    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1501    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1502    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1503    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1504    static final int CLEAR_DNS_CACHE_MSG = 28;
1505    static final int UPDATE_HTTP_PROXY_MSG = 29;
1506    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1507    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1508    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1509    static final int REPORT_MEM_USAGE_MSG = 33;
1510    static final int REPORT_USER_SWITCH_MSG = 34;
1511    static final int CONTINUE_USER_SWITCH_MSG = 35;
1512    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1513    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1514    static final int PERSIST_URI_GRANTS_MSG = 38;
1515    static final int REQUEST_ALL_PSS_MSG = 39;
1516    static final int START_PROFILES_MSG = 40;
1517    static final int UPDATE_TIME = 41;
1518    static final int SYSTEM_USER_START_MSG = 42;
1519    static final int SYSTEM_USER_CURRENT_MSG = 43;
1520    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1521    static final int FINISH_BOOTING_MSG = 45;
1522    static final int START_USER_SWITCH_UI_MSG = 46;
1523    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1524    static final int DISMISS_DIALOG_UI_MSG = 48;
1525    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1526    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1527    static final int DELETE_DUMPHEAP_MSG = 51;
1528    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1529    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1530    static final int REPORT_TIME_TRACKER_MSG = 54;
1531    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1532    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1533    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1534    static final int IDLE_UIDS_MSG = 58;
1535    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1536    static final int LOG_STACK_STATE = 60;
1537    static final int VR_MODE_CHANGE_MSG = 61;
1538    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 62;
1539    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 63;
1540    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 64;
1541    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 65;
1542    static final int START_USER_SWITCH_FG_MSG = 712;
1543
1544    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1545    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1546    static final int FIRST_COMPAT_MODE_MSG = 300;
1547    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1548
1549    static ServiceThread sKillThread = null;
1550    static KillHandler sKillHandler = null;
1551
1552    CompatModeDialog mCompatModeDialog;
1553    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1554    long mLastMemUsageReportTime = 0;
1555
1556    /**
1557     * Flag whether the current user is a "monkey", i.e. whether
1558     * the UI is driven by a UI automation tool.
1559     */
1560    private boolean mUserIsMonkey;
1561
1562    /** Flag whether the device has a Recents UI */
1563    boolean mHasRecents;
1564
1565    /** The dimensions of the thumbnails in the Recents UI. */
1566    int mThumbnailWidth;
1567    int mThumbnailHeight;
1568    float mFullscreenThumbnailScale;
1569
1570    final ServiceThread mHandlerThread;
1571    final MainHandler mHandler;
1572    final UiHandler mUiHandler;
1573
1574    PackageManagerInternal mPackageManagerInt;
1575
1576    // VoiceInteraction session ID that changes for each new request except when
1577    // being called for multiwindow assist in a single session.
1578    private int mViSessionId = 1000;
1579
1580    final boolean mPermissionReviewRequired;
1581
1582    /**
1583     * Current global configuration information. Contains general settings for the entire system,
1584     * also corresponds to the merged configuration of the default display.
1585     */
1586    Configuration getGlobalConfiguration() {
1587        return mStackSupervisor.getConfiguration();
1588    }
1589
1590    final class KillHandler extends Handler {
1591        static final int KILL_PROCESS_GROUP_MSG = 4000;
1592
1593        public KillHandler(Looper looper) {
1594            super(looper, null, true);
1595        }
1596
1597        @Override
1598        public void handleMessage(Message msg) {
1599            switch (msg.what) {
1600                case KILL_PROCESS_GROUP_MSG:
1601                {
1602                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1605                }
1606                break;
1607
1608                default:
1609                    super.handleMessage(msg);
1610            }
1611        }
1612    }
1613
1614    final class UiHandler extends Handler {
1615        public UiHandler() {
1616            super(com.android.server.UiThread.get().getLooper(), null, true);
1617        }
1618
1619        @Override
1620        public void handleMessage(Message msg) {
1621            switch (msg.what) {
1622            case SHOW_ERROR_UI_MSG: {
1623                mAppErrors.handleShowAppErrorUi(msg);
1624                ensureBootCompleted();
1625            } break;
1626            case SHOW_NOT_RESPONDING_UI_MSG: {
1627                mAppErrors.handleShowAnrUi(msg);
1628                ensureBootCompleted();
1629            } break;
1630            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632                synchronized (ActivityManagerService.this) {
1633                    ProcessRecord proc = (ProcessRecord) data.get("app");
1634                    if (proc == null) {
1635                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1636                        break;
1637                    }
1638                    if (proc.crashDialog != null) {
1639                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1640                        return;
1641                    }
1642                    AppErrorResult res = (AppErrorResult) data.get("result");
1643                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644                        Dialog d = new StrictModeViolationDialog(mContext,
1645                                ActivityManagerService.this, res, proc);
1646                        d.show();
1647                        proc.crashDialog = d;
1648                    } else {
1649                        // The device is asleep, so just pretend that the user
1650                        // saw a crash dialog and hit "force quit".
1651                        res.set(0);
1652                    }
1653                }
1654                ensureBootCompleted();
1655            } break;
1656            case SHOW_FACTORY_ERROR_UI_MSG: {
1657                Dialog d = new FactoryErrorDialog(
1658                    mContext, msg.getData().getCharSequence("msg"));
1659                d.show();
1660                ensureBootCompleted();
1661            } break;
1662            case WAIT_FOR_DEBUGGER_UI_MSG: {
1663                synchronized (ActivityManagerService.this) {
1664                    ProcessRecord app = (ProcessRecord)msg.obj;
1665                    if (msg.arg1 != 0) {
1666                        if (!app.waitedForDebugger) {
1667                            Dialog d = new AppWaitingForDebuggerDialog(
1668                                    ActivityManagerService.this,
1669                                    mContext, app);
1670                            app.waitDialog = d;
1671                            app.waitedForDebugger = true;
1672                            d.show();
1673                        }
1674                    } else {
1675                        if (app.waitDialog != null) {
1676                            app.waitDialog.dismiss();
1677                            app.waitDialog = null;
1678                        }
1679                    }
1680                }
1681            } break;
1682            case SHOW_UID_ERROR_UI_MSG: {
1683                if (mShowDialogs) {
1684                    AlertDialog d = new BaseErrorDialog(mContext);
1685                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                    d.setCancelable(false);
1687                    d.setTitle(mContext.getText(R.string.android_system_label));
1688                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                    d.show();
1692                }
1693            } break;
1694            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1695                if (mShowDialogs) {
1696                    AlertDialog d = new BaseErrorDialog(mContext);
1697                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                    d.setCancelable(false);
1699                    d.setTitle(mContext.getText(R.string.android_system_label));
1700                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                    d.show();
1704                }
1705            } break;
1706            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    ActivityRecord ar = (ActivityRecord) msg.obj;
1709                    if (mCompatModeDialog != null) {
1710                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1711                                ar.info.applicationInfo.packageName)) {
1712                            return;
1713                        }
1714                        mCompatModeDialog.dismiss();
1715                        mCompatModeDialog = null;
1716                    }
1717                    if (ar != null && false) {
1718                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1719                                ar.packageName)) {
1720                            int mode = mCompatModePackages.computeCompatModeLocked(
1721                                    ar.info.applicationInfo);
1722                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724                                mCompatModeDialog = new CompatModeDialog(
1725                                        ActivityManagerService.this, mContext,
1726                                        ar.info.applicationInfo);
1727                                mCompatModeDialog.show();
1728                            }
1729                        }
1730                    }
1731                }
1732                break;
1733            }
1734            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1737                    if (mUnsupportedDisplaySizeDialog != null) {
1738                        mUnsupportedDisplaySizeDialog.dismiss();
1739                        mUnsupportedDisplaySizeDialog = null;
1740                    }
1741                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1742                            ar.packageName)) {
1743                        // TODO(multi-display): Show dialog on appropriate display.
1744                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1745                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1746                        mUnsupportedDisplaySizeDialog.show();
1747                    }
1748                }
1749                break;
1750            }
1751            case START_USER_SWITCH_UI_MSG: {
1752                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1753                break;
1754            }
1755            case DISMISS_DIALOG_UI_MSG: {
1756                final Dialog d = (Dialog) msg.obj;
1757                d.dismiss();
1758                break;
1759            }
1760            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1761                dispatchProcessesChanged();
1762                break;
1763            }
1764            case DISPATCH_PROCESS_DIED_UI_MSG: {
1765                final int pid = msg.arg1;
1766                final int uid = msg.arg2;
1767                dispatchProcessDied(pid, uid);
1768                break;
1769            }
1770            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1771                dispatchUidsChanged();
1772            } break;
1773            }
1774        }
1775    }
1776
1777    final class MainHandler extends Handler {
1778        public MainHandler(Looper looper) {
1779            super(looper, null, true);
1780        }
1781
1782        @Override
1783        public void handleMessage(Message msg) {
1784            switch (msg.what) {
1785            case UPDATE_CONFIGURATION_MSG: {
1786                final ContentResolver resolver = mContext.getContentResolver();
1787                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1788                        msg.arg1);
1789            } break;
1790            case GC_BACKGROUND_PROCESSES_MSG: {
1791                synchronized (ActivityManagerService.this) {
1792                    performAppGcsIfAppropriateLocked();
1793                }
1794            } break;
1795            case SERVICE_TIMEOUT_MSG: {
1796                if (mDidDexOpt) {
1797                    mDidDexOpt = false;
1798                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1799                    nmsg.obj = msg.obj;
1800                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1801                    return;
1802                }
1803                mServices.serviceTimeout((ProcessRecord)msg.obj);
1804            } break;
1805            case UPDATE_TIME_ZONE: {
1806                synchronized (ActivityManagerService.this) {
1807                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1808                        ProcessRecord r = mLruProcesses.get(i);
1809                        if (r.thread != null) {
1810                            try {
1811                                r.thread.updateTimeZone();
1812                            } catch (RemoteException ex) {
1813                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1814                            }
1815                        }
1816                    }
1817                }
1818            } break;
1819            case CLEAR_DNS_CACHE_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1822                        ProcessRecord r = mLruProcesses.get(i);
1823                        if (r.thread != null) {
1824                            try {
1825                                r.thread.clearDnsCache();
1826                            } catch (RemoteException ex) {
1827                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1828                            }
1829                        }
1830                    }
1831                }
1832            } break;
1833            case UPDATE_HTTP_PROXY_MSG: {
1834                ProxyInfo proxy = (ProxyInfo)msg.obj;
1835                String host = "";
1836                String port = "";
1837                String exclList = "";
1838                Uri pacFileUrl = Uri.EMPTY;
1839                if (proxy != null) {
1840                    host = proxy.getHost();
1841                    port = Integer.toString(proxy.getPort());
1842                    exclList = proxy.getExclusionListAsString();
1843                    pacFileUrl = proxy.getPacFileUrl();
1844                }
1845                synchronized (ActivityManagerService.this) {
1846                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1847                        ProcessRecord r = mLruProcesses.get(i);
1848                        if (r.thread != null) {
1849                            try {
1850                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1851                            } catch (RemoteException ex) {
1852                                Slog.w(TAG, "Failed to update http proxy for: " +
1853                                        r.info.processName);
1854                            }
1855                        }
1856                    }
1857                }
1858            } break;
1859            case PROC_START_TIMEOUT_MSG: {
1860                if (mDidDexOpt) {
1861                    mDidDexOpt = false;
1862                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1863                    nmsg.obj = msg.obj;
1864                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1865                    return;
1866                }
1867                ProcessRecord app = (ProcessRecord)msg.obj;
1868                synchronized (ActivityManagerService.this) {
1869                    processStartTimedOutLocked(app);
1870                }
1871            } break;
1872            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1873                ProcessRecord app = (ProcessRecord)msg.obj;
1874                synchronized (ActivityManagerService.this) {
1875                    processContentProviderPublishTimedOutLocked(app);
1876                }
1877            } break;
1878            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1879                synchronized (ActivityManagerService.this) {
1880                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1881                }
1882            } break;
1883            case KILL_APPLICATION_MSG: {
1884                synchronized (ActivityManagerService.this) {
1885                    final int appId = msg.arg1;
1886                    final int userId = msg.arg2;
1887                    Bundle bundle = (Bundle)msg.obj;
1888                    String pkg = bundle.getString("pkg");
1889                    String reason = bundle.getString("reason");
1890                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1891                            false, userId, reason);
1892                }
1893            } break;
1894            case FINALIZE_PENDING_INTENT_MSG: {
1895                ((PendingIntentRecord)msg.obj).completeFinalize();
1896            } break;
1897            case POST_HEAVY_NOTIFICATION_MSG: {
1898                INotificationManager inm = NotificationManager.getService();
1899                if (inm == null) {
1900                    return;
1901                }
1902
1903                ActivityRecord root = (ActivityRecord)msg.obj;
1904                ProcessRecord process = root.app;
1905                if (process == null) {
1906                    return;
1907                }
1908
1909                try {
1910                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1911                    String text = mContext.getString(R.string.heavy_weight_notification,
1912                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1913                    Notification notification = new Notification.Builder(context)
1914                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1915                            .setWhen(0)
1916                            .setOngoing(true)
1917                            .setTicker(text)
1918                            .setColor(mContext.getColor(
1919                                    com.android.internal.R.color.system_notification_accent_color))
1920                            .setContentTitle(text)
1921                            .setContentText(
1922                                    mContext.getText(R.string.heavy_weight_notification_detail))
1923                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1924                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1925                                    new UserHandle(root.userId)))
1926                            .build();
1927                    try {
1928                        int[] outId = new int[1];
1929                        inm.enqueueNotificationWithTag("android", "android", null,
1930                                R.string.heavy_weight_notification,
1931                                notification, outId, root.userId);
1932                    } catch (RuntimeException e) {
1933                        Slog.w(ActivityManagerService.TAG,
1934                                "Error showing notification for heavy-weight app", e);
1935                    } catch (RemoteException e) {
1936                    }
1937                } catch (NameNotFoundException e) {
1938                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1939                }
1940            } break;
1941            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1942                INotificationManager inm = NotificationManager.getService();
1943                if (inm == null) {
1944                    return;
1945                }
1946                try {
1947                    inm.cancelNotificationWithTag("android", null,
1948                            R.string.heavy_weight_notification,  msg.arg1);
1949                } catch (RuntimeException e) {
1950                    Slog.w(ActivityManagerService.TAG,
1951                            "Error canceling notification for service", e);
1952                } catch (RemoteException e) {
1953                }
1954            } break;
1955            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1956                synchronized (ActivityManagerService.this) {
1957                    checkExcessivePowerUsageLocked(true);
1958                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1960                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1961                }
1962            } break;
1963            case REPORT_MEM_USAGE_MSG: {
1964                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1965                Thread thread = new Thread() {
1966                    @Override public void run() {
1967                        reportMemUsage(memInfos);
1968                    }
1969                };
1970                thread.start();
1971                break;
1972            }
1973            case START_USER_SWITCH_FG_MSG: {
1974                mUserController.startUserInForeground(msg.arg1);
1975                break;
1976            }
1977            case REPORT_USER_SWITCH_MSG: {
1978                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1979                break;
1980            }
1981            case CONTINUE_USER_SWITCH_MSG: {
1982                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1983                break;
1984            }
1985            case USER_SWITCH_TIMEOUT_MSG: {
1986                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1987                break;
1988            }
1989            case IMMERSIVE_MODE_LOCK_MSG: {
1990                final boolean nextState = (msg.arg1 != 0);
1991                if (mUpdateLock.isHeld() != nextState) {
1992                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1993                            "Applying new update lock state '" + nextState
1994                            + "' for " + (ActivityRecord)msg.obj);
1995                    if (nextState) {
1996                        mUpdateLock.acquire();
1997                    } else {
1998                        mUpdateLock.release();
1999                    }
2000                }
2001                break;
2002            }
2003            case PERSIST_URI_GRANTS_MSG: {
2004                writeGrantedUriPermissions();
2005                break;
2006            }
2007            case REQUEST_ALL_PSS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2010                }
2011                break;
2012            }
2013            case START_PROFILES_MSG: {
2014                synchronized (ActivityManagerService.this) {
2015                    mUserController.startProfilesLocked();
2016                }
2017                break;
2018            }
2019            case UPDATE_TIME: {
2020                synchronized (ActivityManagerService.this) {
2021                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2022                        ProcessRecord r = mLruProcesses.get(i);
2023                        if (r.thread != null) {
2024                            try {
2025                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2026                            } catch (RemoteException ex) {
2027                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2028                            }
2029                        }
2030                    }
2031                }
2032                break;
2033            }
2034            case SYSTEM_USER_START_MSG: {
2035                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2036                        Integer.toString(msg.arg1), msg.arg1);
2037                mSystemServiceManager.startUser(msg.arg1);
2038                break;
2039            }
2040            case SYSTEM_USER_UNLOCK_MSG: {
2041                final int userId = msg.arg1;
2042                mSystemServiceManager.unlockUser(userId);
2043                synchronized (ActivityManagerService.this) {
2044                    mRecentTasks.loadUserRecentsLocked(userId);
2045                }
2046                if (userId == UserHandle.USER_SYSTEM) {
2047                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2048                }
2049                installEncryptionUnawareProviders(userId);
2050                mUserController.finishUserUnlocked((UserState) msg.obj);
2051                break;
2052            }
2053            case SYSTEM_USER_CURRENT_MSG: {
2054                mBatteryStatsService.noteEvent(
2055                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2056                        Integer.toString(msg.arg2), msg.arg2);
2057                mBatteryStatsService.noteEvent(
2058                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2059                        Integer.toString(msg.arg1), msg.arg1);
2060                mSystemServiceManager.switchUser(msg.arg1);
2061                break;
2062            }
2063            case ENTER_ANIMATION_COMPLETE_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2066                    if (r != null && r.app != null && r.app.thread != null) {
2067                        try {
2068                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2069                        } catch (RemoteException e) {
2070                        }
2071                    }
2072                }
2073                break;
2074            }
2075            case FINISH_BOOTING_MSG: {
2076                if (msg.arg1 != 0) {
2077                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2078                    finishBooting();
2079                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2080                }
2081                if (msg.arg2 != 0) {
2082                    enableScreenAfterBoot();
2083                }
2084                break;
2085            }
2086            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2087                try {
2088                    Locale l = (Locale) msg.obj;
2089                    IBinder service = ServiceManager.getService("mount");
2090                    IMountService mountService = IMountService.Stub.asInterface(service);
2091                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2092                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2093                } catch (RemoteException e) {
2094                    Log.e(TAG, "Error storing locale for decryption UI", e);
2095                }
2096                break;
2097            }
2098            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2099                final int uid = msg.arg1;
2100                final byte[] firstPacket = (byte[]) msg.obj;
2101
2102                synchronized (mPidsSelfLocked) {
2103                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2104                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2105                        if (p.uid == uid) {
2106                            try {
2107                                p.thread.notifyCleartextNetwork(firstPacket);
2108                            } catch (RemoteException ignored) {
2109                            }
2110                        }
2111                    }
2112                }
2113                break;
2114            }
2115            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2116                final String procName;
2117                final int uid;
2118                final long memLimit;
2119                final String reportPackage;
2120                synchronized (ActivityManagerService.this) {
2121                    procName = mMemWatchDumpProcName;
2122                    uid = mMemWatchDumpUid;
2123                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2124                    if (val == null) {
2125                        val = mMemWatchProcesses.get(procName, 0);
2126                    }
2127                    if (val != null) {
2128                        memLimit = val.first;
2129                        reportPackage = val.second;
2130                    } else {
2131                        memLimit = 0;
2132                        reportPackage = null;
2133                    }
2134                }
2135                if (procName == null) {
2136                    return;
2137                }
2138
2139                if (DEBUG_PSS) Slog.d(TAG_PSS,
2140                        "Showing dump heap notification from " + procName + "/" + uid);
2141
2142                INotificationManager inm = NotificationManager.getService();
2143                if (inm == null) {
2144                    return;
2145                }
2146
2147                String text = mContext.getString(R.string.dump_heap_notification, procName);
2148
2149
2150                Intent deleteIntent = new Intent();
2151                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2152                Intent intent = new Intent();
2153                intent.setClassName("android", DumpHeapActivity.class.getName());
2154                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2155                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2156                if (reportPackage != null) {
2157                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2158                }
2159                int userId = UserHandle.getUserId(uid);
2160                Notification notification = new Notification.Builder(mContext)
2161                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2162                        .setWhen(0)
2163                        .setOngoing(true)
2164                        .setAutoCancel(true)
2165                        .setTicker(text)
2166                        .setColor(mContext.getColor(
2167                                com.android.internal.R.color.system_notification_accent_color))
2168                        .setContentTitle(text)
2169                        .setContentText(
2170                                mContext.getText(R.string.dump_heap_notification_detail))
2171                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2172                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2173                                new UserHandle(userId)))
2174                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2175                                deleteIntent, 0, UserHandle.SYSTEM))
2176                        .build();
2177
2178                try {
2179                    int[] outId = new int[1];
2180                    inm.enqueueNotificationWithTag("android", "android", null,
2181                            R.string.dump_heap_notification,
2182                            notification, outId, userId);
2183                } catch (RuntimeException e) {
2184                    Slog.w(ActivityManagerService.TAG,
2185                            "Error showing notification for dump heap", e);
2186                } catch (RemoteException e) {
2187                }
2188            } break;
2189            case DELETE_DUMPHEAP_MSG: {
2190                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2191                        DumpHeapActivity.JAVA_URI,
2192                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2193                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2194                        UserHandle.myUserId());
2195                synchronized (ActivityManagerService.this) {
2196                    mMemWatchDumpFile = null;
2197                    mMemWatchDumpProcName = null;
2198                    mMemWatchDumpPid = -1;
2199                    mMemWatchDumpUid = -1;
2200                }
2201            } break;
2202            case FOREGROUND_PROFILE_CHANGED_MSG: {
2203                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2204            } break;
2205            case REPORT_TIME_TRACKER_MSG: {
2206                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2207                tracker.deliverResult(mContext);
2208            } break;
2209            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2210                mUserController.dispatchUserSwitchComplete(msg.arg1);
2211            } break;
2212            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2213                mUserController.dispatchLockedBootComplete(msg.arg1);
2214            } break;
2215            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2216                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2217                try {
2218                    connection.shutdown();
2219                } catch (RemoteException e) {
2220                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2221                }
2222                // Only a UiAutomation can set this flag and now that
2223                // it is finished we make sure it is reset to its default.
2224                mUserIsMonkey = false;
2225            } break;
2226            case IDLE_UIDS_MSG: {
2227                idleUids();
2228            } break;
2229            case VR_MODE_CHANGE_MSG: {
2230                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2231                if (vrService == null) {
2232                    break;
2233                }
2234                final ActivityRecord r = (ActivityRecord) msg.obj;
2235                boolean vrMode;
2236                ComponentName requestedPackage;
2237                ComponentName callingPackage;
2238                int userId;
2239                synchronized (ActivityManagerService.this) {
2240                    vrMode = r.requestedVrComponent != null;
2241                    requestedPackage = r.requestedVrComponent;
2242                    userId = r.userId;
2243                    callingPackage = r.info.getComponentName();
2244                    if (mInVrMode != vrMode) {
2245                        mInVrMode = vrMode;
2246                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2247                        if (r.app != null) {
2248                            ProcessRecord proc = r.app;
2249                            if (proc.vrThreadTid > 0) {
2250                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2251                                    try {
2252                                        if (mInVrMode == true) {
2253                                            Process.setThreadScheduler(proc.vrThreadTid,
2254                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2255                                        } else {
2256                                            Process.setThreadScheduler(proc.vrThreadTid,
2257                                                Process.SCHED_OTHER, 0);
2258                                        }
2259                                    } catch (IllegalArgumentException e) {
2260                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2261                                                + " not exist:\n" + e);
2262                                    }
2263                                }
2264                            }
2265                        }
2266                    }
2267                }
2268                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2269            } break;
2270            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2271                final ActivityRecord r = (ActivityRecord) msg.obj;
2272                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2273                if (needsVrMode) {
2274                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2275                            r.info.getComponentName(), false);
2276                }
2277            } break;
2278            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2279                synchronized (ActivityManagerService.this) {
2280                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2281                        ProcessRecord r = mLruProcesses.get(i);
2282                        if (r.thread != null) {
2283                            try {
2284                                r.thread.handleTrustStorageUpdate();
2285                            } catch (RemoteException ex) {
2286                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2287                                        r.info.processName);
2288                            }
2289                        }
2290                    }
2291                }
2292            } break;
2293            }
2294        }
2295    };
2296
2297    static final int COLLECT_PSS_BG_MSG = 1;
2298
2299    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2300        @Override
2301        public void handleMessage(Message msg) {
2302            switch (msg.what) {
2303            case COLLECT_PSS_BG_MSG: {
2304                long start = SystemClock.uptimeMillis();
2305                MemInfoReader memInfo = null;
2306                synchronized (ActivityManagerService.this) {
2307                    if (mFullPssPending) {
2308                        mFullPssPending = false;
2309                        memInfo = new MemInfoReader();
2310                    }
2311                }
2312                if (memInfo != null) {
2313                    updateCpuStatsNow();
2314                    long nativeTotalPss = 0;
2315                    final List<ProcessCpuTracker.Stats> stats;
2316                    synchronized (mProcessCpuTracker) {
2317                        stats = mProcessCpuTracker.getStats( (st)-> {
2318                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2319                        });
2320                    }
2321                    final int N = stats.size();
2322                    for (int j = 0; j < N; j++) {
2323                        synchronized (mPidsSelfLocked) {
2324                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2325                                // This is one of our own processes; skip it.
2326                                continue;
2327                            }
2328                        }
2329                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2330                    }
2331                    memInfo.readMemInfo();
2332                    synchronized (ActivityManagerService.this) {
2333                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2334                                + (SystemClock.uptimeMillis()-start) + "ms");
2335                        final long cachedKb = memInfo.getCachedSizeKb();
2336                        final long freeKb = memInfo.getFreeSizeKb();
2337                        final long zramKb = memInfo.getZramTotalSizeKb();
2338                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2339                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2340                                kernelKb*1024, nativeTotalPss*1024);
2341                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2342                                nativeTotalPss);
2343                    }
2344                }
2345
2346                int num = 0;
2347                long[] tmp = new long[2];
2348                do {
2349                    ProcessRecord proc;
2350                    int procState;
2351                    int pid;
2352                    long lastPssTime;
2353                    synchronized (ActivityManagerService.this) {
2354                        if (mPendingPssProcesses.size() <= 0) {
2355                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2356                                    "Collected PSS of " + num + " processes in "
2357                                    + (SystemClock.uptimeMillis() - start) + "ms");
2358                            mPendingPssProcesses.clear();
2359                            return;
2360                        }
2361                        proc = mPendingPssProcesses.remove(0);
2362                        procState = proc.pssProcState;
2363                        lastPssTime = proc.lastPssTime;
2364                        if (proc.thread != null && procState == proc.setProcState
2365                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2366                                        < SystemClock.uptimeMillis()) {
2367                            pid = proc.pid;
2368                        } else {
2369                            proc = null;
2370                            pid = 0;
2371                        }
2372                    }
2373                    if (proc != null) {
2374                        long pss = Debug.getPss(pid, tmp, null);
2375                        synchronized (ActivityManagerService.this) {
2376                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2377                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2378                                num++;
2379                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2380                                        SystemClock.uptimeMillis());
2381                            }
2382                        }
2383                    }
2384                } while (true);
2385            }
2386            }
2387        }
2388    };
2389
2390    public void setSystemProcess() {
2391        try {
2392            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2393            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2394            ServiceManager.addService("meminfo", new MemBinder(this));
2395            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2396            ServiceManager.addService("dbinfo", new DbBinder(this));
2397            if (MONITOR_CPU_USAGE) {
2398                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2399            }
2400            ServiceManager.addService("permission", new PermissionController(this));
2401            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2402
2403            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2404                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2405            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2406
2407            synchronized (this) {
2408                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2409                app.persistent = true;
2410                app.pid = MY_PID;
2411                app.maxAdj = ProcessList.SYSTEM_ADJ;
2412                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2413                synchronized (mPidsSelfLocked) {
2414                    mPidsSelfLocked.put(app.pid, app);
2415                }
2416                updateLruProcessLocked(app, false, null);
2417                updateOomAdjLocked();
2418            }
2419        } catch (PackageManager.NameNotFoundException e) {
2420            throw new RuntimeException(
2421                    "Unable to find android system package", e);
2422        }
2423    }
2424
2425    public void setWindowManager(WindowManagerService wm) {
2426        mWindowManager = wm;
2427        mStackSupervisor.setWindowManager(wm);
2428        mActivityStarter.setWindowManager(wm);
2429    }
2430
2431    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2432        mUsageStatsService = usageStatsManager;
2433    }
2434
2435    public void startObservingNativeCrashes() {
2436        final NativeCrashListener ncl = new NativeCrashListener(this);
2437        ncl.start();
2438    }
2439
2440    public IAppOpsService getAppOpsService() {
2441        return mAppOpsService;
2442    }
2443
2444    static class MemBinder extends Binder {
2445        ActivityManagerService mActivityManagerService;
2446        MemBinder(ActivityManagerService activityManagerService) {
2447            mActivityManagerService = activityManagerService;
2448        }
2449
2450        @Override
2451        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2452            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2453                    != PackageManager.PERMISSION_GRANTED) {
2454                pw.println("Permission Denial: can't dump meminfo from from pid="
2455                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2456                        + " without permission " + android.Manifest.permission.DUMP);
2457                return;
2458            }
2459
2460            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2461        }
2462    }
2463
2464    static class GraphicsBinder extends Binder {
2465        ActivityManagerService mActivityManagerService;
2466        GraphicsBinder(ActivityManagerService activityManagerService) {
2467            mActivityManagerService = activityManagerService;
2468        }
2469
2470        @Override
2471        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2472            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2473                    != PackageManager.PERMISSION_GRANTED) {
2474                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2475                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2476                        + " without permission " + android.Manifest.permission.DUMP);
2477                return;
2478            }
2479
2480            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2481        }
2482    }
2483
2484    static class DbBinder extends Binder {
2485        ActivityManagerService mActivityManagerService;
2486        DbBinder(ActivityManagerService activityManagerService) {
2487            mActivityManagerService = activityManagerService;
2488        }
2489
2490        @Override
2491        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2492            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2493                    != PackageManager.PERMISSION_GRANTED) {
2494                pw.println("Permission Denial: can't dump dbinfo from from pid="
2495                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2496                        + " without permission " + android.Manifest.permission.DUMP);
2497                return;
2498            }
2499
2500            mActivityManagerService.dumpDbInfo(fd, pw, args);
2501        }
2502    }
2503
2504    static class CpuBinder extends Binder {
2505        ActivityManagerService mActivityManagerService;
2506        CpuBinder(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 cpuinfo from from pid="
2515                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2516                        + " without permission " + android.Manifest.permission.DUMP);
2517                return;
2518            }
2519
2520            synchronized (mActivityManagerService.mProcessCpuTracker) {
2521                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2522                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2523                        SystemClock.uptimeMillis()));
2524            }
2525        }
2526    }
2527
2528    public static final class Lifecycle extends SystemService {
2529        private final ActivityManagerService mService;
2530
2531        public Lifecycle(Context context) {
2532            super(context);
2533            mService = new ActivityManagerService(context);
2534        }
2535
2536        @Override
2537        public void onStart() {
2538            mService.start();
2539        }
2540
2541        public ActivityManagerService getService() {
2542            return mService;
2543        }
2544    }
2545
2546    // Note: This method is invoked on the main thread but may need to attach various
2547    // handlers to other threads.  So take care to be explicit about the looper.
2548    public ActivityManagerService(Context systemContext) {
2549        mContext = systemContext;
2550        mFactoryTest = FactoryTest.getMode();
2551        mSystemThread = ActivityThread.currentActivityThread();
2552
2553        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2554
2555        mPermissionReviewRequired = mContext.getResources().getBoolean(
2556                com.android.internal.R.bool.config_permissionReviewRequired);
2557
2558        mHandlerThread = new ServiceThread(TAG,
2559                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2560        mHandlerThread.start();
2561        mHandler = new MainHandler(mHandlerThread.getLooper());
2562        mUiHandler = new UiHandler();
2563
2564        /* static; one-time init here */
2565        if (sKillHandler == null) {
2566            sKillThread = new ServiceThread(TAG + ":kill",
2567                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2568            sKillThread.start();
2569            sKillHandler = new KillHandler(sKillThread.getLooper());
2570        }
2571
2572        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2573                "foreground", BROADCAST_FG_TIMEOUT, false);
2574        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2575                "background", BROADCAST_BG_TIMEOUT, true);
2576        mBroadcastQueues[0] = mFgBroadcastQueue;
2577        mBroadcastQueues[1] = mBgBroadcastQueue;
2578
2579        mServices = new ActiveServices(this);
2580        mProviderMap = new ProviderMap(this);
2581        mAppErrors = new AppErrors(mContext, this);
2582
2583        // TODO: Move creation of battery stats service outside of activity manager service.
2584        File dataDir = Environment.getDataDirectory();
2585        File systemDir = new File(dataDir, "system");
2586        systemDir.mkdirs();
2587        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2588        mBatteryStatsService.getActiveStatistics().readLocked();
2589        mBatteryStatsService.scheduleWriteToDisk();
2590        mOnBattery = DEBUG_POWER ? true
2591                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2592        mBatteryStatsService.getActiveStatistics().setCallback(this);
2593
2594        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2595
2596        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2597        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2598                new IAppOpsCallback.Stub() {
2599                    @Override public void opChanged(int op, int uid, String packageName) {
2600                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2601                            if (mAppOpsService.checkOperation(op, uid, packageName)
2602                                    != AppOpsManager.MODE_ALLOWED) {
2603                                runInBackgroundDisabled(uid);
2604                            }
2605                        }
2606                    }
2607                });
2608
2609        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2610
2611        mUserController = new UserController(this);
2612
2613        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2614            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2615
2616        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2617            mUseFifoUiScheduling = true;
2618        }
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mTempConfig.setToDefaults();
2623        mTempConfig.setLocales(LocaleList.getDefault());
2624        mConfigurationSeq = mTempConfig.seq = 1;
2625
2626        mProcessCpuTracker.init();
2627
2628        mStackSupervisor = new ActivityStackSupervisor(this);
2629        mStackSupervisor.onConfigurationChanged(mTempConfig);
2630        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2631        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2632        mTaskChangeNotificationController =
2633                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2634        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637        mProcessCpuThread = new Thread("CpuTracker") {
2638            @Override
2639            public void run() {
2640                while (true) {
2641                    try {
2642                        try {
2643                            synchronized(this) {
2644                                final long now = SystemClock.uptimeMillis();
2645                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                //        + ", write delay=" + nextWriteDelay);
2649                                if (nextWriteDelay < nextCpuDelay) {
2650                                    nextCpuDelay = nextWriteDelay;
2651                                }
2652                                if (nextCpuDelay > 0) {
2653                                    mProcessCpuMutexFree.set(true);
2654                                    this.wait(nextCpuDelay);
2655                                }
2656                            }
2657                        } catch (InterruptedException e) {
2658                        }
2659                        updateCpuStatsNow();
2660                    } catch (Exception e) {
2661                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                    }
2663                }
2664            }
2665        };
2666
2667        Watchdog.getInstance().addMonitor(this);
2668        Watchdog.getInstance().addThread(mHandler);
2669    }
2670
2671    public void setSystemServiceManager(SystemServiceManager mgr) {
2672        mSystemServiceManager = mgr;
2673    }
2674
2675    public void setInstaller(Installer installer) {
2676        mInstaller = installer;
2677    }
2678
2679    private void start() {
2680        Process.removeAllProcessGroups();
2681        mProcessCpuThread.start();
2682
2683        mBatteryStatsService.publish(mContext);
2684        mAppOpsService.publish(mContext);
2685        Slog.d("AppOps", "AppOpsService published");
2686        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687    }
2688
2689    void onUserStoppedLocked(int userId) {
2690        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691    }
2692
2693    public void initPowerManagement() {
2694        mStackSupervisor.initPowerManagement();
2695        mBatteryStatsService.initPowerManagement();
2696        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699        mVoiceWakeLock.setReferenceCounted(false);
2700    }
2701
2702    @Override
2703    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704            throws RemoteException {
2705        if (code == SYSPROPS_TRANSACTION) {
2706            // We need to tell all apps about the system property change.
2707            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708            synchronized(this) {
2709                final int NP = mProcessNames.getMap().size();
2710                for (int ip=0; ip<NP; ip++) {
2711                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                    final int NA = apps.size();
2713                    for (int ia=0; ia<NA; ia++) {
2714                        ProcessRecord app = apps.valueAt(ia);
2715                        if (app.thread != null) {
2716                            procs.add(app.thread.asBinder());
2717                        }
2718                    }
2719                }
2720            }
2721
2722            int N = procs.size();
2723            for (int i=0; i<N; i++) {
2724                Parcel data2 = Parcel.obtain();
2725                try {
2726                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                } catch (RemoteException e) {
2728                }
2729                data2.recycle();
2730            }
2731        }
2732        try {
2733            return super.onTransact(code, data, reply, flags);
2734        } catch (RuntimeException e) {
2735            // The activity manager only throws security exceptions, so let's
2736            // log all others.
2737            if (!(e instanceof SecurityException)) {
2738                Slog.wtf(TAG, "Activity Manager Crash", e);
2739            }
2740            throw e;
2741        }
2742    }
2743
2744    void updateCpuStats() {
2745        final long now = SystemClock.uptimeMillis();
2746        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747            return;
2748        }
2749        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750            synchronized (mProcessCpuThread) {
2751                mProcessCpuThread.notify();
2752            }
2753        }
2754    }
2755
2756    void updateCpuStatsNow() {
2757        synchronized (mProcessCpuTracker) {
2758            mProcessCpuMutexFree.set(false);
2759            final long now = SystemClock.uptimeMillis();
2760            boolean haveNewCpuStats = false;
2761
2762            if (MONITOR_CPU_USAGE &&
2763                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                mLastCpuTime.set(now);
2765                mProcessCpuTracker.update();
2766                if (mProcessCpuTracker.hasGoodLastStats()) {
2767                    haveNewCpuStats = true;
2768                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                    //Slog.i(TAG, "Total CPU usage: "
2770                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                    // Slog the cpu usage if the property is set.
2773                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                        int user = mProcessCpuTracker.getLastUserTime();
2775                        int system = mProcessCpuTracker.getLastSystemTime();
2776                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                        int irq = mProcessCpuTracker.getLastIrqTime();
2778                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                        int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                        int total = user + system + iowait + irq + softIrq + idle;
2782                        if (total == 0) total = 1;
2783
2784                        EventLog.writeEvent(EventLogTags.CPU,
2785                                ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                (user * 100) / total,
2787                                (system * 100) / total,
2788                                (iowait * 100) / total,
2789                                (irq * 100) / total,
2790                                (softIrq * 100) / total);
2791                    }
2792                }
2793            }
2794
2795            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796            synchronized(bstats) {
2797                synchronized(mPidsSelfLocked) {
2798                    if (haveNewCpuStats) {
2799                        if (bstats.startAddingCpuLocked()) {
2800                            int totalUTime = 0;
2801                            int totalSTime = 0;
2802                            final int N = mProcessCpuTracker.countStats();
2803                            for (int i=0; i<N; i++) {
2804                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                if (!st.working) {
2806                                    continue;
2807                                }
2808                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                totalUTime += st.rel_utime;
2810                                totalSTime += st.rel_stime;
2811                                if (pr != null) {
2812                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                    if (ps == null || !ps.isActive()) {
2814                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                pr.info.uid, pr.processName);
2816                                    }
2817                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                } else {
2820                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                    if (ps == null || !ps.isActive()) {
2822                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                bstats.mapUid(st.uid), st.name);
2824                                    }
2825                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                }
2827                            }
2828                            final int userTime = mProcessCpuTracker.getLastUserTime();
2829                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                        }
2837                    }
2838                }
2839
2840                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                    mLastWriteTime = now;
2842                    mBatteryStatsService.scheduleWriteToDisk();
2843                }
2844            }
2845        }
2846    }
2847
2848    @Override
2849    public void batteryNeedsCpuUpdate() {
2850        updateCpuStatsNow();
2851    }
2852
2853    @Override
2854    public void batteryPowerChanged(boolean onBattery) {
2855        // When plugging in, update the CPU stats first before changing
2856        // the plug state.
2857        updateCpuStatsNow();
2858        synchronized (this) {
2859            synchronized(mPidsSelfLocked) {
2860                mOnBattery = DEBUG_POWER ? true : onBattery;
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batterySendBroadcast(Intent intent) {
2867        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                AppOpsManager.OP_NONE, null, false, false,
2869                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870    }
2871
2872    /**
2873     * Initialize the application bind args. These are passed to each
2874     * process when the bindApplication() IPC is sent to the process. They're
2875     * lazily setup to make sure the services are running when they're asked for.
2876     */
2877    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878        // Isolated processes won't get this optimization, so that we don't
2879        // violate the rules about which services they have access to.
2880        if (isolated) {
2881            if (mIsolatedAppBindArgs == null) {
2882                mIsolatedAppBindArgs = new HashMap<>();
2883                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2884            }
2885            return mIsolatedAppBindArgs;
2886        }
2887
2888        if (mAppBindArgs == null) {
2889            mAppBindArgs = new HashMap<>();
2890
2891            // Setup the application init args
2892            mAppBindArgs.put("package", ServiceManager.getService("package"));
2893            mAppBindArgs.put("window", ServiceManager.getService("window"));
2894            mAppBindArgs.put(Context.ALARM_SERVICE,
2895                    ServiceManager.getService(Context.ALARM_SERVICE));
2896        }
2897        return mAppBindArgs;
2898    }
2899
2900    /**
2901     * Update AMS states when an activity is resumed. This should only be called by
2902     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2903     */
2904    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2905        if (r.task.isApplicationTask()) {
2906            if (mCurAppTimeTracker != r.appTimeTracker) {
2907                // We are switching app tracking.  Complete the current one.
2908                if (mCurAppTimeTracker != null) {
2909                    mCurAppTimeTracker.stop();
2910                    mHandler.obtainMessage(
2911                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2912                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2913                    mCurAppTimeTracker = null;
2914                }
2915                if (r.appTimeTracker != null) {
2916                    mCurAppTimeTracker = r.appTimeTracker;
2917                    startTimeTrackingFocusedActivityLocked();
2918                }
2919            } else {
2920                startTimeTrackingFocusedActivityLocked();
2921            }
2922        } else {
2923            r.appTimeTracker = null;
2924        }
2925        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2926        // TODO: Probably not, because we don't want to resume voice on switching
2927        // back to this activity
2928        if (r.task.voiceInteractor != null) {
2929            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2930        } else {
2931            finishRunningVoiceLocked();
2932            IVoiceInteractionSession session;
2933            if (mLastResumedActivity != null
2934                    && ((session = mLastResumedActivity.task.voiceSession) != null
2935                    || (session = mLastResumedActivity.voiceSession) != null)) {
2936                // We had been in a voice interaction session, but now focused has
2937                // move to something different.  Just finish the session, we can't
2938                // return to it and retain the proper state and synchronization with
2939                // the voice interaction service.
2940                finishVoiceTask(session);
2941            }
2942        }
2943
2944        mWindowManager.setFocusedApp(r.appToken, true);
2945
2946        applyUpdateLockStateLocked(r);
2947        applyUpdateVrModeLocked(r);
2948        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2949            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2950            mHandler.obtainMessage(
2951                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2952        }
2953
2954        mLastResumedActivity = r;
2955
2956        EventLogTags.writeAmSetResumedActivity(
2957                r == null ? -1 : r.userId,
2958                r == null ? "NULL" : r.shortComponentName,
2959                reason);
2960    }
2961
2962    @Override
2963    public void setFocusedStack(int stackId) {
2964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2965        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2966        final long callingId = Binder.clearCallingIdentity();
2967        try {
2968            synchronized (this) {
2969                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2970                if (stack == null) {
2971                    return;
2972                }
2973                final ActivityRecord r = stack.topRunningActivityLocked();
2974                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
2975                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2976                }
2977            }
2978        } finally {
2979            Binder.restoreCallingIdentity(callingId);
2980        }
2981    }
2982
2983    @Override
2984    public void setFocusedTask(int taskId) {
2985        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2986        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2987        final long callingId = Binder.clearCallingIdentity();
2988        try {
2989            synchronized (this) {
2990                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2991                if (task == null) {
2992                    return;
2993                }
2994                final ActivityRecord r = task.topRunningActivityLocked();
2995                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
2996                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2997                }
2998            }
2999        } finally {
3000            Binder.restoreCallingIdentity(callingId);
3001        }
3002    }
3003
3004    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3005    @Override
3006    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3007        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3008        mTaskChangeNotificationController.registerTaskStackListener(listener);
3009    }
3010
3011    /**
3012     * Unregister a task stack listener so that it stops receiving callbacks.
3013     */
3014    @Override
3015    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3016         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3017         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3018     }
3019
3020    @Override
3021    public void notifyActivityDrawn(IBinder token) {
3022        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3023        synchronized (this) {
3024            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3025            if (r != null) {
3026                r.getStack().notifyActivityDrawnLocked(r);
3027            }
3028        }
3029    }
3030
3031    final void applyUpdateLockStateLocked(ActivityRecord r) {
3032        // Modifications to the UpdateLock state are done on our handler, outside
3033        // the activity manager's locks.  The new state is determined based on the
3034        // state *now* of the relevant activity record.  The object is passed to
3035        // the handler solely for logging detail, not to be consulted/modified.
3036        final boolean nextState = r != null && r.immersive;
3037        mHandler.sendMessage(
3038                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3039    }
3040
3041    final void applyUpdateVrModeLocked(ActivityRecord r) {
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3044    }
3045
3046    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3047        mHandler.sendMessage(
3048                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3049    }
3050
3051    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3052            ComponentName callingPackage, boolean immediate) {
3053        VrManagerInternal vrService =
3054                LocalServices.getService(VrManagerInternal.class);
3055        if (immediate) {
3056            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3057        } else {
3058            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3059        }
3060    }
3061
3062    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3063        Message msg = Message.obtain();
3064        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3065        msg.obj = r.task.askedCompatMode ? null : r;
3066        mUiHandler.sendMessage(msg);
3067    }
3068
3069    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3070        final Configuration globalConfig = getGlobalConfiguration();
3071        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3072                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3073            final Message msg = Message.obtain();
3074            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3075            msg.obj = r;
3076            mUiHandler.sendMessage(msg);
3077        }
3078    }
3079
3080    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3081            String what, Object obj, ProcessRecord srcApp) {
3082        app.lastActivityTime = now;
3083
3084        if (app.activities.size() > 0) {
3085            // Don't want to touch dependent processes that are hosting activities.
3086            return index;
3087        }
3088
3089        int lrui = mLruProcesses.lastIndexOf(app);
3090        if (lrui < 0) {
3091            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3092                    + what + " " + obj + " from " + srcApp);
3093            return index;
3094        }
3095
3096        if (lrui >= index) {
3097            // Don't want to cause this to move dependent processes *back* in the
3098            // list as if they were less frequently used.
3099            return index;
3100        }
3101
3102        if (lrui >= mLruProcessActivityStart) {
3103            // Don't want to touch dependent processes that are hosting activities.
3104            return index;
3105        }
3106
3107        mLruProcesses.remove(lrui);
3108        if (index > 0) {
3109            index--;
3110        }
3111        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3112                + " in LRU list: " + app);
3113        mLruProcesses.add(index, app);
3114        return index;
3115    }
3116
3117    static void killProcessGroup(int uid, int pid) {
3118        if (sKillHandler != null) {
3119            sKillHandler.sendMessage(
3120                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3121        } else {
3122            Slog.w(TAG, "Asked to kill process group before system bringup!");
3123            Process.killProcessGroup(uid, pid);
3124        }
3125    }
3126
3127    final void removeLruProcessLocked(ProcessRecord app) {
3128        int lrui = mLruProcesses.lastIndexOf(app);
3129        if (lrui >= 0) {
3130            if (!app.killed) {
3131                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3132                Process.killProcessQuiet(app.pid);
3133                killProcessGroup(app.uid, app.pid);
3134            }
3135            if (lrui <= mLruProcessActivityStart) {
3136                mLruProcessActivityStart--;
3137            }
3138            if (lrui <= mLruProcessServiceStart) {
3139                mLruProcessServiceStart--;
3140            }
3141            mLruProcesses.remove(lrui);
3142        }
3143    }
3144
3145    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3146            ProcessRecord client) {
3147        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3148                || app.treatLikeActivity;
3149        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3150        if (!activityChange && hasActivity) {
3151            // The process has activities, so we are only allowing activity-based adjustments
3152            // to move it.  It should be kept in the front of the list with other
3153            // processes that have activities, and we don't want those to change their
3154            // order except due to activity operations.
3155            return;
3156        }
3157
3158        mLruSeq++;
3159        final long now = SystemClock.uptimeMillis();
3160        app.lastActivityTime = now;
3161
3162        // First a quick reject: if the app is already at the position we will
3163        // put it, then there is nothing to do.
3164        if (hasActivity) {
3165            final int N = mLruProcesses.size();
3166            if (N > 0 && mLruProcesses.get(N-1) == app) {
3167                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3168                return;
3169            }
3170        } else {
3171            if (mLruProcessServiceStart > 0
3172                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3173                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3174                return;
3175            }
3176        }
3177
3178        int lrui = mLruProcesses.lastIndexOf(app);
3179
3180        if (app.persistent && lrui >= 0) {
3181            // We don't care about the position of persistent processes, as long as
3182            // they are in the list.
3183            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3184            return;
3185        }
3186
3187        /* In progress: compute new position first, so we can avoid doing work
3188           if the process is not actually going to move.  Not yet working.
3189        int addIndex;
3190        int nextIndex;
3191        boolean inActivity = false, inService = false;
3192        if (hasActivity) {
3193            // Process has activities, put it at the very tipsy-top.
3194            addIndex = mLruProcesses.size();
3195            nextIndex = mLruProcessServiceStart;
3196            inActivity = true;
3197        } else if (hasService) {
3198            // Process has services, put it at the top of the service list.
3199            addIndex = mLruProcessActivityStart;
3200            nextIndex = mLruProcessServiceStart;
3201            inActivity = true;
3202            inService = true;
3203        } else  {
3204            // Process not otherwise of interest, it goes to the top of the non-service area.
3205            addIndex = mLruProcessServiceStart;
3206            if (client != null) {
3207                int clientIndex = mLruProcesses.lastIndexOf(client);
3208                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3209                        + app);
3210                if (clientIndex >= 0 && addIndex > clientIndex) {
3211                    addIndex = clientIndex;
3212                }
3213            }
3214            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3215        }
3216
3217        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3218                + mLruProcessActivityStart + "): " + app);
3219        */
3220
3221        if (lrui >= 0) {
3222            if (lrui < mLruProcessActivityStart) {
3223                mLruProcessActivityStart--;
3224            }
3225            if (lrui < mLruProcessServiceStart) {
3226                mLruProcessServiceStart--;
3227            }
3228            /*
3229            if (addIndex > lrui) {
3230                addIndex--;
3231            }
3232            if (nextIndex > lrui) {
3233                nextIndex--;
3234            }
3235            */
3236            mLruProcesses.remove(lrui);
3237        }
3238
3239        /*
3240        mLruProcesses.add(addIndex, app);
3241        if (inActivity) {
3242            mLruProcessActivityStart++;
3243        }
3244        if (inService) {
3245            mLruProcessActivityStart++;
3246        }
3247        */
3248
3249        int nextIndex;
3250        if (hasActivity) {
3251            final int N = mLruProcesses.size();
3252            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3253                // Process doesn't have activities, but has clients with
3254                // activities...  move it up, but one below the top (the top
3255                // should always have a real activity).
3256                if (DEBUG_LRU) Slog.d(TAG_LRU,
3257                        "Adding to second-top of LRU activity list: " + app);
3258                mLruProcesses.add(N - 1, app);
3259                // To keep it from spamming the LRU list (by making a bunch of clients),
3260                // we will push down any other entries owned by the app.
3261                final int uid = app.info.uid;
3262                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3263                    ProcessRecord subProc = mLruProcesses.get(i);
3264                    if (subProc.info.uid == uid) {
3265                        // We want to push this one down the list.  If the process after
3266                        // it is for the same uid, however, don't do so, because we don't
3267                        // want them internally to be re-ordered.
3268                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3269                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3270                                    "Pushing uid " + uid + " swapping at " + i + ": "
3271                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3272                            ProcessRecord tmp = mLruProcesses.get(i);
3273                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3274                            mLruProcesses.set(i - 1, tmp);
3275                            i--;
3276                        }
3277                    } else {
3278                        // A gap, we can stop here.
3279                        break;
3280                    }
3281                }
3282            } else {
3283                // Process has activities, put it at the very tipsy-top.
3284                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3285                mLruProcesses.add(app);
3286            }
3287            nextIndex = mLruProcessServiceStart;
3288        } else if (hasService) {
3289            // Process has services, put it at the top of the service list.
3290            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3291            mLruProcesses.add(mLruProcessActivityStart, app);
3292            nextIndex = mLruProcessServiceStart;
3293            mLruProcessActivityStart++;
3294        } else  {
3295            // Process not otherwise of interest, it goes to the top of the non-service area.
3296            int index = mLruProcessServiceStart;
3297            if (client != null) {
3298                // If there is a client, don't allow the process to be moved up higher
3299                // in the list than that client.
3300                int clientIndex = mLruProcesses.lastIndexOf(client);
3301                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3302                        + " when updating " + app);
3303                if (clientIndex <= lrui) {
3304                    // Don't allow the client index restriction to push it down farther in the
3305                    // list than it already is.
3306                    clientIndex = lrui;
3307                }
3308                if (clientIndex >= 0 && index > clientIndex) {
3309                    index = clientIndex;
3310                }
3311            }
3312            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3313            mLruProcesses.add(index, app);
3314            nextIndex = index-1;
3315            mLruProcessActivityStart++;
3316            mLruProcessServiceStart++;
3317        }
3318
3319        // If the app is currently using a content provider or service,
3320        // bump those processes as well.
3321        for (int j=app.connections.size()-1; j>=0; j--) {
3322            ConnectionRecord cr = app.connections.valueAt(j);
3323            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3324                    && cr.binding.service.app != null
3325                    && cr.binding.service.app.lruSeq != mLruSeq
3326                    && !cr.binding.service.app.persistent) {
3327                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3328                        "service connection", cr, app);
3329            }
3330        }
3331        for (int j=app.conProviders.size()-1; j>=0; j--) {
3332            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3333            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3334                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3335                        "provider reference", cpr, app);
3336            }
3337        }
3338    }
3339
3340    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3341        if (uid == Process.SYSTEM_UID) {
3342            // The system gets to run in any process.  If there are multiple
3343            // processes with the same uid, just pick the first (this
3344            // should never happen).
3345            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3346            if (procs == null) return null;
3347            final int procCount = procs.size();
3348            for (int i = 0; i < procCount; i++) {
3349                final int procUid = procs.keyAt(i);
3350                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3351                    // Don't use an app process or different user process for system component.
3352                    continue;
3353                }
3354                return procs.valueAt(i);
3355            }
3356        }
3357        ProcessRecord proc = mProcessNames.get(processName, uid);
3358        if (false && proc != null && !keepIfLarge
3359                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3360                && proc.lastCachedPss >= 4000) {
3361            // Turn this condition on to cause killing to happen regularly, for testing.
3362            if (proc.baseProcessTracker != null) {
3363                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3364            }
3365            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3366        } else if (proc != null && !keepIfLarge
3367                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3368                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3369            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3370            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3371                if (proc.baseProcessTracker != null) {
3372                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3373                }
3374                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3375            }
3376        }
3377        return proc;
3378    }
3379
3380    void notifyPackageUse(String packageName, int reason) {
3381        IPackageManager pm = AppGlobals.getPackageManager();
3382        try {
3383            pm.notifyPackageUse(packageName, reason);
3384        } catch (RemoteException e) {
3385        }
3386    }
3387
3388    boolean isNextTransitionForward() {
3389        int transit = mWindowManager.getPendingAppTransition();
3390        return transit == TRANSIT_ACTIVITY_OPEN
3391                || transit == TRANSIT_TASK_OPEN
3392                || transit == TRANSIT_TASK_TO_FRONT;
3393    }
3394
3395    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3396            String processName, String abiOverride, int uid, Runnable crashHandler) {
3397        synchronized(this) {
3398            ApplicationInfo info = new ApplicationInfo();
3399            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3400            // For isolated processes, the former contains the parent's uid and the latter the
3401            // actual uid of the isolated process.
3402            // In the special case introduced by this method (which is, starting an isolated
3403            // process directly from the SystemServer without an actual parent app process) the
3404            // closest thing to a parent's uid is SYSTEM_UID.
3405            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3406            // the |isolated| logic in the ProcessRecord constructor.
3407            info.uid = Process.SYSTEM_UID;
3408            info.processName = processName;
3409            info.className = entryPoint;
3410            info.packageName = "android";
3411            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3412                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3413                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3414                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3415                    crashHandler);
3416            return proc != null ? proc.pid : 0;
3417        }
3418    }
3419
3420    final ProcessRecord startProcessLocked(String processName,
3421            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3422            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3423            boolean isolated, boolean keepIfLarge) {
3424        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3425                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3426                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3427                null /* crashHandler */);
3428    }
3429
3430    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3431            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3432            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3433            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3434        long startTime = SystemClock.elapsedRealtime();
3435        ProcessRecord app;
3436        if (!isolated) {
3437            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3438            checkTime(startTime, "startProcess: after getProcessRecord");
3439
3440            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3441                // If we are in the background, then check to see if this process
3442                // is bad.  If so, we will just silently fail.
3443                if (mAppErrors.isBadProcessLocked(info)) {
3444                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3445                            + "/" + info.processName);
3446                    return null;
3447                }
3448            } else {
3449                // When the user is explicitly starting a process, then clear its
3450                // crash count so that we won't make it bad until they see at
3451                // least one crash dialog again, and make the process good again
3452                // if it had been bad.
3453                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3454                        + "/" + info.processName);
3455                mAppErrors.resetProcessCrashTimeLocked(info);
3456                if (mAppErrors.isBadProcessLocked(info)) {
3457                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3458                            UserHandle.getUserId(info.uid), info.uid,
3459                            info.processName);
3460                    mAppErrors.clearBadProcessLocked(info);
3461                    if (app != null) {
3462                        app.bad = false;
3463                    }
3464                }
3465            }
3466        } else {
3467            // If this is an isolated process, it can't re-use an existing process.
3468            app = null;
3469        }
3470
3471        // We don't have to do anything more if:
3472        // (1) There is an existing application record; and
3473        // (2) The caller doesn't think it is dead, OR there is no thread
3474        //     object attached to it so we know it couldn't have crashed; and
3475        // (3) There is a pid assigned to it, so it is either starting or
3476        //     already running.
3477        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3478                + " app=" + app + " knownToBeDead=" + knownToBeDead
3479                + " thread=" + (app != null ? app.thread : null)
3480                + " pid=" + (app != null ? app.pid : -1));
3481        if (app != null && app.pid > 0) {
3482            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3483                // We already have the app running, or are waiting for it to
3484                // come up (we have a pid but not yet its thread), so keep it.
3485                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3486                // If this is a new package in the process, add the package to the list
3487                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3488                checkTime(startTime, "startProcess: done, added package to proc");
3489                return app;
3490            }
3491
3492            // An application record is attached to a previous process,
3493            // clean it up now.
3494            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3495            checkTime(startTime, "startProcess: bad proc running, killing");
3496            killProcessGroup(app.uid, app.pid);
3497            handleAppDiedLocked(app, true, true);
3498            checkTime(startTime, "startProcess: done killing old proc");
3499        }
3500
3501        String hostingNameStr = hostingName != null
3502                ? hostingName.flattenToShortString() : null;
3503
3504        if (app == null) {
3505            checkTime(startTime, "startProcess: creating new process record");
3506            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3507            if (app == null) {
3508                Slog.w(TAG, "Failed making new process record for "
3509                        + processName + "/" + info.uid + " isolated=" + isolated);
3510                return null;
3511            }
3512            app.crashHandler = crashHandler;
3513            checkTime(startTime, "startProcess: done creating new process record");
3514        } else {
3515            // If this is a new package in the process, add the package to the list
3516            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3517            checkTime(startTime, "startProcess: added package to existing proc");
3518        }
3519
3520        // If the system is not ready yet, then hold off on starting this
3521        // process until it is.
3522        if (!mProcessesReady
3523                && !isAllowedWhileBooting(info)
3524                && !allowWhileBooting) {
3525            if (!mProcessesOnHold.contains(app)) {
3526                mProcessesOnHold.add(app);
3527            }
3528            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3529                    "System not ready, putting on hold: " + app);
3530            checkTime(startTime, "startProcess: returning with proc on hold");
3531            return app;
3532        }
3533
3534        checkTime(startTime, "startProcess: stepping in to startProcess");
3535        startProcessLocked(
3536                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3537        checkTime(startTime, "startProcess: done starting proc!");
3538        return (app.pid != 0) ? app : null;
3539    }
3540
3541    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3542        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3543    }
3544
3545    private final void startProcessLocked(ProcessRecord app,
3546            String hostingType, String hostingNameStr) {
3547        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3548                null /* entryPoint */, null /* entryPointArgs */);
3549    }
3550
3551    private final void startProcessLocked(ProcessRecord app, String hostingType,
3552            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3553        long startTime = SystemClock.elapsedRealtime();
3554        if (app.pid > 0 && app.pid != MY_PID) {
3555            checkTime(startTime, "startProcess: removing from pids map");
3556            synchronized (mPidsSelfLocked) {
3557                mPidsSelfLocked.remove(app.pid);
3558                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3559            }
3560            checkTime(startTime, "startProcess: done removing from pids map");
3561            app.setPid(0);
3562        }
3563
3564        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3565                "startProcessLocked removing on hold: " + app);
3566        mProcessesOnHold.remove(app);
3567
3568        checkTime(startTime, "startProcess: starting to update cpu stats");
3569        updateCpuStats();
3570        checkTime(startTime, "startProcess: done updating cpu stats");
3571
3572        try {
3573            try {
3574                final int userId = UserHandle.getUserId(app.uid);
3575                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3576            } catch (RemoteException e) {
3577                throw e.rethrowAsRuntimeException();
3578            }
3579
3580            int uid = app.uid;
3581            int[] gids = null;
3582            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3583            if (!app.isolated) {
3584                int[] permGids = null;
3585                try {
3586                    checkTime(startTime, "startProcess: getting gids from package manager");
3587                    final IPackageManager pm = AppGlobals.getPackageManager();
3588                    permGids = pm.getPackageGids(app.info.packageName,
3589                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3590                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3591                            MountServiceInternal.class);
3592                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3593                            app.info.packageName);
3594                } catch (RemoteException e) {
3595                    throw e.rethrowAsRuntimeException();
3596                }
3597
3598                /*
3599                 * Add shared application and profile GIDs so applications can share some
3600                 * resources like shared libraries and access user-wide resources
3601                 */
3602                if (ArrayUtils.isEmpty(permGids)) {
3603                    gids = new int[2];
3604                } else {
3605                    gids = new int[permGids.length + 2];
3606                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3607                }
3608                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3609                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3610            }
3611            checkTime(startTime, "startProcess: building args");
3612            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3613                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3614                        && mTopComponent != null
3615                        && app.processName.equals(mTopComponent.getPackageName())) {
3616                    uid = 0;
3617                }
3618                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3619                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3620                    uid = 0;
3621                }
3622            }
3623            int debugFlags = 0;
3624            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3625                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3626                // Also turn on CheckJNI for debuggable apps. It's quite
3627                // awkward to turn on otherwise.
3628                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3629            }
3630            // Run the app in safe mode if its manifest requests so or the
3631            // system is booted in safe mode.
3632            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3633                mSafeMode == true) {
3634                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3635            }
3636            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3637                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3638            }
3639            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3640            if ("true".equals(genDebugInfoProperty)) {
3641                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3642            }
3643            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3644                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3645            }
3646            if ("1".equals(SystemProperties.get("debug.assert"))) {
3647                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3648            }
3649            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3650                // Enable all debug flags required by the native debugger.
3651                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3652                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3653                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3654                mNativeDebuggingApp = null;
3655            }
3656
3657            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3658            if (requiredAbi == null) {
3659                requiredAbi = Build.SUPPORTED_ABIS[0];
3660            }
3661
3662            String instructionSet = null;
3663            if (app.info.primaryCpuAbi != null) {
3664                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3665            }
3666
3667            app.gids = gids;
3668            app.requiredAbi = requiredAbi;
3669            app.instructionSet = instructionSet;
3670
3671            // Start the process.  It will either succeed and return a result containing
3672            // the PID of the new process, or else throw a RuntimeException.
3673            boolean isActivityProcess = (entryPoint == null);
3674            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3675            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3676                    app.processName);
3677            checkTime(startTime, "startProcess: asking zygote to start proc");
3678            Process.ProcessStartResult startResult = Process.start(entryPoint,
3679                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3680                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3681                    app.info.dataDir, entryPointArgs);
3682            checkTime(startTime, "startProcess: returned from zygote!");
3683            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3684
3685            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3686            checkTime(startTime, "startProcess: done updating battery stats");
3687
3688            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3689                    UserHandle.getUserId(uid), startResult.pid, uid,
3690                    app.processName, hostingType,
3691                    hostingNameStr != null ? hostingNameStr : "");
3692
3693            try {
3694                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3695                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3696            } catch (RemoteException ex) {
3697                // Ignore
3698            }
3699
3700            if (app.persistent) {
3701                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3702            }
3703
3704            checkTime(startTime, "startProcess: building log message");
3705            StringBuilder buf = mStringBuilder;
3706            buf.setLength(0);
3707            buf.append("Start proc ");
3708            buf.append(startResult.pid);
3709            buf.append(':');
3710            buf.append(app.processName);
3711            buf.append('/');
3712            UserHandle.formatUid(buf, uid);
3713            if (!isActivityProcess) {
3714                buf.append(" [");
3715                buf.append(entryPoint);
3716                buf.append("]");
3717            }
3718            buf.append(" for ");
3719            buf.append(hostingType);
3720            if (hostingNameStr != null) {
3721                buf.append(" ");
3722                buf.append(hostingNameStr);
3723            }
3724            Slog.i(TAG, buf.toString());
3725            app.setPid(startResult.pid);
3726            app.usingWrapper = startResult.usingWrapper;
3727            app.removed = false;
3728            app.killed = false;
3729            app.killedByAm = false;
3730            checkTime(startTime, "startProcess: starting to update pids map");
3731            ProcessRecord oldApp;
3732            synchronized (mPidsSelfLocked) {
3733                oldApp = mPidsSelfLocked.get(startResult.pid);
3734            }
3735            // If there is already an app occupying that pid that hasn't been cleaned up
3736            if (oldApp != null && !app.isolated) {
3737                // Clean up anything relating to this pid first
3738                Slog.w(TAG, "Reusing pid " + startResult.pid
3739                        + " while app is still mapped to it");
3740                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3741                        true /*replacingPid*/);
3742            }
3743            synchronized (mPidsSelfLocked) {
3744                this.mPidsSelfLocked.put(startResult.pid, app);
3745                if (isActivityProcess) {
3746                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3747                    msg.obj = app;
3748                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3749                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3750                }
3751            }
3752            checkTime(startTime, "startProcess: done updating pids map");
3753        } catch (RuntimeException e) {
3754            Slog.e(TAG, "Failure starting process " + app.processName, e);
3755
3756            // Something went very wrong while trying to start this process; one
3757            // common case is when the package is frozen due to an active
3758            // upgrade. To recover, clean up any active bookkeeping related to
3759            // starting this process. (We already invoked this method once when
3760            // the package was initially frozen through KILL_APPLICATION_MSG, so
3761            // it doesn't hurt to use it again.)
3762            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3763                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3764        }
3765    }
3766
3767    void updateUsageStats(ActivityRecord component, boolean resumed) {
3768        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3769                "updateUsageStats: comp=" + component + "res=" + resumed);
3770        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3771        if (resumed) {
3772            if (mUsageStatsService != null) {
3773                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3774                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3775            }
3776            synchronized (stats) {
3777                stats.noteActivityResumedLocked(component.app.uid);
3778            }
3779        } else {
3780            if (mUsageStatsService != null) {
3781                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3782                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3783            }
3784            synchronized (stats) {
3785                stats.noteActivityPausedLocked(component.app.uid);
3786            }
3787        }
3788    }
3789
3790    Intent getHomeIntent() {
3791        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3792        intent.setComponent(mTopComponent);
3793        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3794        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3795            intent.addCategory(Intent.CATEGORY_HOME);
3796        }
3797        return intent;
3798    }
3799
3800    boolean startHomeActivityLocked(int userId, String reason) {
3801        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3802                && mTopAction == null) {
3803            // We are running in factory test mode, but unable to find
3804            // the factory test app, so just sit around displaying the
3805            // error message and don't try to start anything.
3806            return false;
3807        }
3808        Intent intent = getHomeIntent();
3809        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3810        if (aInfo != null) {
3811            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3812            // Don't do this if the home app is currently being
3813            // instrumented.
3814            aInfo = new ActivityInfo(aInfo);
3815            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3816            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3817                    aInfo.applicationInfo.uid, true);
3818            if (app == null || app.instrumentationClass == null) {
3819                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3820                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3821            }
3822        } else {
3823            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3824        }
3825
3826        return true;
3827    }
3828
3829    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3830        ActivityInfo ai = null;
3831        ComponentName comp = intent.getComponent();
3832        try {
3833            if (comp != null) {
3834                // Factory test.
3835                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3836            } else {
3837                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3838                        intent,
3839                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3840                        flags, userId);
3841
3842                if (info != null) {
3843                    ai = info.activityInfo;
3844                }
3845            }
3846        } catch (RemoteException e) {
3847            // ignore
3848        }
3849
3850        return ai;
3851    }
3852
3853    /**
3854     * Starts the "new version setup screen" if appropriate.
3855     */
3856    void startSetupActivityLocked() {
3857        // Only do this once per boot.
3858        if (mCheckedForSetup) {
3859            return;
3860        }
3861
3862        // We will show this screen if the current one is a different
3863        // version than the last one shown, and we are not running in
3864        // low-level factory test mode.
3865        final ContentResolver resolver = mContext.getContentResolver();
3866        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3867                Settings.Global.getInt(resolver,
3868                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3869            mCheckedForSetup = true;
3870
3871            // See if we should be showing the platform update setup UI.
3872            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3873            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3874                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3875            if (!ris.isEmpty()) {
3876                final ResolveInfo ri = ris.get(0);
3877                String vers = ri.activityInfo.metaData != null
3878                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3879                        : null;
3880                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3881                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3882                            Intent.METADATA_SETUP_VERSION);
3883                }
3884                String lastVers = Settings.Secure.getString(
3885                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3886                if (vers != null && !vers.equals(lastVers)) {
3887                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3888                    intent.setComponent(new ComponentName(
3889                            ri.activityInfo.packageName, ri.activityInfo.name));
3890                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3891                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3892                            null, 0, 0, 0, null, false, false, null, null, null);
3893                }
3894            }
3895        }
3896    }
3897
3898    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3899        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3900    }
3901
3902    void enforceNotIsolatedCaller(String caller) {
3903        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3904            throw new SecurityException("Isolated process not allowed to call " + caller);
3905        }
3906    }
3907
3908    void enforceShellRestriction(String restriction, int userHandle) {
3909        if (Binder.getCallingUid() == Process.SHELL_UID) {
3910            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3911                throw new SecurityException("Shell does not have permission to access user "
3912                        + userHandle);
3913            }
3914        }
3915    }
3916
3917    @Override
3918    public int getFrontActivityScreenCompatMode() {
3919        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3920        synchronized (this) {
3921            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3922        }
3923    }
3924
3925    @Override
3926    public void setFrontActivityScreenCompatMode(int mode) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setFrontActivityScreenCompatMode");
3929        synchronized (this) {
3930            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3931        }
3932    }
3933
3934    @Override
3935    public int getPackageScreenCompatMode(String packageName) {
3936        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3937        synchronized (this) {
3938            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3939        }
3940    }
3941
3942    @Override
3943    public void setPackageScreenCompatMode(String packageName, int mode) {
3944        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3945                "setPackageScreenCompatMode");
3946        synchronized (this) {
3947            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3948        }
3949    }
3950
3951    @Override
3952    public boolean getPackageAskScreenCompat(String packageName) {
3953        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3954        synchronized (this) {
3955            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3956        }
3957    }
3958
3959    @Override
3960    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3961        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3962                "setPackageAskScreenCompat");
3963        synchronized (this) {
3964            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3965        }
3966    }
3967
3968    private boolean hasUsageStatsPermission(String callingPackage) {
3969        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3970                Binder.getCallingUid(), callingPackage);
3971        if (mode == AppOpsManager.MODE_DEFAULT) {
3972            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3973                    == PackageManager.PERMISSION_GRANTED;
3974        }
3975        return mode == AppOpsManager.MODE_ALLOWED;
3976    }
3977
3978    @Override
3979    public int getPackageProcessState(String packageName, String callingPackage) {
3980        if (!hasUsageStatsPermission(callingPackage)) {
3981            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
3982                    "getPackageProcessState");
3983        }
3984
3985        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3986        synchronized (this) {
3987            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3988                final ProcessRecord proc = mLruProcesses.get(i);
3989                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3990                        || procState > proc.setProcState) {
3991                    if (proc.pkgList.containsKey(packageName)) {
3992                        procState = proc.setProcState;
3993                        break;
3994                    }
3995                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
3996                        procState = proc.setProcState;
3997                    }
3998                }
3999            }
4000        }
4001        return procState;
4002    }
4003
4004    @Override
4005    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4006            throws RemoteException {
4007        synchronized (this) {
4008            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4009            if (app == null) {
4010                throw new IllegalArgumentException("Unknown process: " + process);
4011            }
4012            if (app.thread == null) {
4013                throw new IllegalArgumentException("Process has no app thread");
4014            }
4015            if (app.trimMemoryLevel >= level) {
4016                throw new IllegalArgumentException(
4017                        "Unable to set a higher trim level than current level");
4018            }
4019            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4020                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4021                throw new IllegalArgumentException("Unable to set a background trim level "
4022                    + "on a foreground process");
4023            }
4024            app.thread.scheduleTrimMemory(level);
4025            app.trimMemoryLevel = level;
4026            return true;
4027        }
4028    }
4029
4030    private void dispatchProcessesChanged() {
4031        int N;
4032        synchronized (this) {
4033            N = mPendingProcessChanges.size();
4034            if (mActiveProcessChanges.length < N) {
4035                mActiveProcessChanges = new ProcessChangeItem[N];
4036            }
4037            mPendingProcessChanges.toArray(mActiveProcessChanges);
4038            mPendingProcessChanges.clear();
4039            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4040                    "*** Delivering " + N + " process changes");
4041        }
4042
4043        int i = mProcessObservers.beginBroadcast();
4044        while (i > 0) {
4045            i--;
4046            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4047            if (observer != null) {
4048                try {
4049                    for (int j=0; j<N; j++) {
4050                        ProcessChangeItem item = mActiveProcessChanges[j];
4051                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4052                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4053                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4054                                    + item.uid + ": " + item.foregroundActivities);
4055                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4056                                    item.foregroundActivities);
4057                        }
4058                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4059                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4060                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4061                                    + ": " + item.processState);
4062                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4063                        }
4064                    }
4065                } catch (RemoteException e) {
4066                }
4067            }
4068        }
4069        mProcessObservers.finishBroadcast();
4070
4071        synchronized (this) {
4072            for (int j=0; j<N; j++) {
4073                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4074            }
4075        }
4076    }
4077
4078    private void dispatchProcessDied(int pid, int uid) {
4079        int i = mProcessObservers.beginBroadcast();
4080        while (i > 0) {
4081            i--;
4082            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4083            if (observer != null) {
4084                try {
4085                    observer.onProcessDied(pid, uid);
4086                } catch (RemoteException e) {
4087                }
4088            }
4089        }
4090        mProcessObservers.finishBroadcast();
4091    }
4092
4093    private void dispatchUidsChanged() {
4094        int N;
4095        synchronized (this) {
4096            N = mPendingUidChanges.size();
4097            if (mActiveUidChanges.length < N) {
4098                mActiveUidChanges = new UidRecord.ChangeItem[N];
4099            }
4100            for (int i=0; i<N; i++) {
4101                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4102                mActiveUidChanges[i] = change;
4103                if (change.uidRecord != null) {
4104                    change.uidRecord.pendingChange = null;
4105                    change.uidRecord = null;
4106                }
4107            }
4108            mPendingUidChanges.clear();
4109            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4110                    "*** Delivering " + N + " uid changes");
4111        }
4112
4113        int i = mUidObservers.beginBroadcast();
4114        while (i > 0) {
4115            i--;
4116            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4117            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4118            if (observer != null) {
4119                try {
4120                    for (int j=0; j<N; j++) {
4121                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4122                        final int change = item.change;
4123                        UidRecord validateUid = null;
4124                        if (VALIDATE_UID_STATES && i == 0) {
4125                            validateUid = mValidateUids.get(item.uid);
4126                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4127                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4128                                validateUid = new UidRecord(item.uid);
4129                                mValidateUids.put(item.uid, validateUid);
4130                            }
4131                        }
4132                        if (change == UidRecord.CHANGE_IDLE
4133                                || change == UidRecord.CHANGE_GONE_IDLE) {
4134                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4135                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4136                                        "UID idle uid=" + item.uid);
4137                                observer.onUidIdle(item.uid);
4138                            }
4139                            if (VALIDATE_UID_STATES && i == 0) {
4140                                if (validateUid != null) {
4141                                    validateUid.idle = true;
4142                                }
4143                            }
4144                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4145                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4146                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4147                                        "UID active uid=" + item.uid);
4148                                observer.onUidActive(item.uid);
4149                            }
4150                            if (VALIDATE_UID_STATES && i == 0) {
4151                                validateUid.idle = false;
4152                            }
4153                        }
4154                        if (change == UidRecord.CHANGE_GONE
4155                                || change == UidRecord.CHANGE_GONE_IDLE) {
4156                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4157                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4158                                        "UID gone uid=" + item.uid);
4159                                observer.onUidGone(item.uid);
4160                            }
4161                            if (VALIDATE_UID_STATES && i == 0) {
4162                                if (validateUid != null) {
4163                                    mValidateUids.remove(item.uid);
4164                                }
4165                            }
4166                        } else {
4167                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4168                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4169                                        "UID CHANGED uid=" + item.uid
4170                                                + ": " + item.processState);
4171                                observer.onUidStateChanged(item.uid, item.processState);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                validateUid.curProcState = validateUid.setProcState
4175                                        = item.processState;
4176                            }
4177                        }
4178                    }
4179                } catch (RemoteException e) {
4180                }
4181            }
4182        }
4183        mUidObservers.finishBroadcast();
4184
4185        synchronized (this) {
4186            for (int j=0; j<N; j++) {
4187                mAvailUidChanges.add(mActiveUidChanges[j]);
4188            }
4189        }
4190    }
4191
4192    @Override
4193    public final int startActivity(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4196        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4197                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4198                UserHandle.getCallingUserId());
4199    }
4200
4201    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4202        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4203        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4204                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4205                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4206
4207        // TODO: Switch to user app stacks here.
4208        String mimeType = intent.getType();
4209        final Uri data = intent.getData();
4210        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4211            mimeType = getProviderMimeType(data, userId);
4212        }
4213        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4214
4215        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4216        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4217                null, 0, 0, null, null, null, null, false, userId, container, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4224        enforceNotIsolatedCaller("startActivity");
4225        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4226                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4227        // TODO: Switch to user app stacks here.
4228        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4229                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4230                profilerInfo, null, null, bOptions, false, userId, null, null);
4231    }
4232
4233    @Override
4234    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4235            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4236            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4237            int userId) {
4238
4239        // This is very dangerous -- it allows you to perform a start activity (including
4240        // permission grants) as any app that may launch one of your own activities.  So
4241        // we will only allow this to be done from activities that are part of the core framework,
4242        // and then only when they are running as the system.
4243        final ActivityRecord sourceRecord;
4244        final int targetUid;
4245        final String targetPackage;
4246        synchronized (this) {
4247            if (resultTo == null) {
4248                throw new SecurityException("Must be called from an activity");
4249            }
4250            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4251            if (sourceRecord == null) {
4252                throw new SecurityException("Called with bad activity token: " + resultTo);
4253            }
4254            if (!sourceRecord.info.packageName.equals("android")) {
4255                throw new SecurityException(
4256                        "Must be called from an activity that is declared in the android package");
4257            }
4258            if (sourceRecord.app == null) {
4259                throw new SecurityException("Called without a process attached to activity");
4260            }
4261            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4262                // This is still okay, as long as this activity is running under the
4263                // uid of the original calling activity.
4264                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4265                    throw new SecurityException(
4266                            "Calling activity in uid " + sourceRecord.app.uid
4267                                    + " must be system uid or original calling uid "
4268                                    + sourceRecord.launchedFromUid);
4269                }
4270            }
4271            if (ignoreTargetSecurity) {
4272                if (intent.getComponent() == null) {
4273                    throw new SecurityException(
4274                            "Component must be specified with ignoreTargetSecurity");
4275                }
4276                if (intent.getSelector() != null) {
4277                    throw new SecurityException(
4278                            "Selector not allowed with ignoreTargetSecurity");
4279                }
4280            }
4281            targetUid = sourceRecord.launchedFromUid;
4282            targetPackage = sourceRecord.launchedFromPackage;
4283        }
4284
4285        if (userId == UserHandle.USER_NULL) {
4286            userId = UserHandle.getUserId(sourceRecord.app.uid);
4287        }
4288
4289        // TODO: Switch to user app stacks here.
4290        try {
4291            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4292                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4293                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4294            return ret;
4295        } catch (SecurityException e) {
4296            // XXX need to figure out how to propagate to original app.
4297            // A SecurityException here is generally actually a fault of the original
4298            // calling activity (such as a fairly granting permissions), so propagate it
4299            // back to them.
4300            /*
4301            StringBuilder msg = new StringBuilder();
4302            msg.append("While launching");
4303            msg.append(intent.toString());
4304            msg.append(": ");
4305            msg.append(e.getMessage());
4306            */
4307            throw e;
4308        }
4309    }
4310
4311    @Override
4312    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4313            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4314            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4315        enforceNotIsolatedCaller("startActivityAndWait");
4316        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4317                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4318        WaitResult res = new WaitResult();
4319        // TODO: Switch to user app stacks here.
4320        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4321                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4322                bOptions, false, userId, null, null);
4323        return res;
4324    }
4325
4326    @Override
4327    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4329            int startFlags, Configuration config, Bundle bOptions, int userId) {
4330        enforceNotIsolatedCaller("startActivityWithConfig");
4331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4332                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4333        // TODO: Switch to user app stacks here.
4334        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4336                null, null, config, bOptions, false, userId, null, null);
4337        return ret;
4338    }
4339
4340    @Override
4341    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4342            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4343            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4344            throws TransactionTooLargeException {
4345        enforceNotIsolatedCaller("startActivityIntentSender");
4346        // Refuse possible leaked file descriptors
4347        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4348            throw new IllegalArgumentException("File descriptors passed in Intent");
4349        }
4350
4351        IIntentSender sender = intent.getTarget();
4352        if (!(sender instanceof PendingIntentRecord)) {
4353            throw new IllegalArgumentException("Bad PendingIntent object");
4354        }
4355
4356        PendingIntentRecord pir = (PendingIntentRecord)sender;
4357
4358        synchronized (this) {
4359            // If this is coming from the currently resumed activity, it is
4360            // effectively saying that app switches are allowed at this point.
4361            final ActivityStack stack = getFocusedStack();
4362            if (stack.mResumedActivity != null &&
4363                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4364                mAppSwitchesAllowedTime = 0;
4365            }
4366        }
4367        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4368                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4369        return ret;
4370    }
4371
4372    @Override
4373    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4374            Intent intent, String resolvedType, IVoiceInteractionSession session,
4375            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4376            Bundle bOptions, int userId) {
4377        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: startVoiceActivity() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386        if (session == null || interactor == null) {
4387            throw new NullPointerException("null session or interactor");
4388        }
4389        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4390                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4393                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4394                null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4399            throws RemoteException {
4400        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4401        synchronized (this) {
4402            ActivityRecord activity = getFocusedStack().topActivity();
4403            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4404                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4405            }
4406            if (mRunningVoice != null || activity.task.voiceSession != null
4407                    || activity.voiceSession != null) {
4408                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4409                return;
4410            }
4411            if (activity.pendingVoiceInteractionStart) {
4412                Slog.w(TAG, "Pending start of voice interaction already.");
4413                return;
4414            }
4415            activity.pendingVoiceInteractionStart = true;
4416        }
4417        LocalServices.getService(VoiceInteractionManagerInternal.class)
4418                .startLocalVoiceInteraction(callingActivity, options);
4419    }
4420
4421    @Override
4422    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4423        LocalServices.getService(VoiceInteractionManagerInternal.class)
4424                .stopLocalVoiceInteraction(callingActivity);
4425    }
4426
4427    @Override
4428    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4429        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4430                .supportsLocalVoiceInteraction();
4431    }
4432
4433    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4434            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4435        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4436        if (activityToCallback == null) return;
4437        activityToCallback.setVoiceSessionLocked(voiceSession);
4438
4439        // Inform the activity
4440        try {
4441            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4442                    voiceInteractor);
4443            long token = Binder.clearCallingIdentity();
4444            try {
4445                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4446            } finally {
4447                Binder.restoreCallingIdentity(token);
4448            }
4449            // TODO: VI Should we cache the activity so that it's easier to find later
4450            // rather than scan through all the stacks and activities?
4451        } catch (RemoteException re) {
4452            activityToCallback.clearVoiceSessionLocked();
4453            // TODO: VI Should this terminate the voice session?
4454        }
4455    }
4456
4457    @Override
4458    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4459        synchronized (this) {
4460            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4461                if (keepAwake) {
4462                    mVoiceWakeLock.acquire();
4463                } else {
4464                    mVoiceWakeLock.release();
4465                }
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public boolean startNextMatchingActivity(IBinder callingActivity,
4472            Intent intent, Bundle bOptions) {
4473        // Refuse possible leaked file descriptors
4474        if (intent != null && intent.hasFileDescriptors() == true) {
4475            throw new IllegalArgumentException("File descriptors passed in Intent");
4476        }
4477        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4478
4479        synchronized (this) {
4480            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4481            if (r == null) {
4482                ActivityOptions.abort(options);
4483                return false;
4484            }
4485            if (r.app == null || r.app.thread == null) {
4486                // The caller is not running...  d'oh!
4487                ActivityOptions.abort(options);
4488                return false;
4489            }
4490            intent = new Intent(intent);
4491            // The caller is not allowed to change the data.
4492            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4493            // And we are resetting to find the next component...
4494            intent.setComponent(null);
4495
4496            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4497
4498            ActivityInfo aInfo = null;
4499            try {
4500                List<ResolveInfo> resolves =
4501                    AppGlobals.getPackageManager().queryIntentActivities(
4502                            intent, r.resolvedType,
4503                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4504                            UserHandle.getCallingUserId()).getList();
4505
4506                // Look for the original activity in the list...
4507                final int N = resolves != null ? resolves.size() : 0;
4508                for (int i=0; i<N; i++) {
4509                    ResolveInfo rInfo = resolves.get(i);
4510                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4511                            && rInfo.activityInfo.name.equals(r.info.name)) {
4512                        // We found the current one...  the next matching is
4513                        // after it.
4514                        i++;
4515                        if (i<N) {
4516                            aInfo = resolves.get(i).activityInfo;
4517                        }
4518                        if (debug) {
4519                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4520                                    + "/" + r.info.name);
4521                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4522                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4523                        }
4524                        break;
4525                    }
4526                }
4527            } catch (RemoteException e) {
4528            }
4529
4530            if (aInfo == null) {
4531                // Nobody who is next!
4532                ActivityOptions.abort(options);
4533                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4534                return false;
4535            }
4536
4537            intent.setComponent(new ComponentName(
4538                    aInfo.applicationInfo.packageName, aInfo.name));
4539            intent.setFlags(intent.getFlags()&~(
4540                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4541                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4542                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4543                    Intent.FLAG_ACTIVITY_NEW_TASK));
4544
4545            // Okay now we need to start the new activity, replacing the
4546            // currently running activity.  This is a little tricky because
4547            // we want to start the new one as if the current one is finished,
4548            // but not finish the current one first so that there is no flicker.
4549            // And thus...
4550            final boolean wasFinishing = r.finishing;
4551            r.finishing = true;
4552
4553            // Propagate reply information over to the new activity.
4554            final ActivityRecord resultTo = r.resultTo;
4555            final String resultWho = r.resultWho;
4556            final int requestCode = r.requestCode;
4557            r.resultTo = null;
4558            if (resultTo != null) {
4559                resultTo.removeResultsLocked(r, resultWho, requestCode);
4560            }
4561
4562            final long origId = Binder.clearCallingIdentity();
4563            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4564                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4565                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4566                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4567                    false, false, null, null, null);
4568            Binder.restoreCallingIdentity(origId);
4569
4570            r.finishing = wasFinishing;
4571            if (res != ActivityManager.START_SUCCESS) {
4572                return false;
4573            }
4574            return true;
4575        }
4576    }
4577
4578    @Override
4579    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4580        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4581            String msg = "Permission Denial: startActivityFromRecents called without " +
4582                    START_TASKS_FROM_RECENTS;
4583            Slog.w(TAG, msg);
4584            throw new SecurityException(msg);
4585        }
4586        final long origId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized (this) {
4589                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4590            }
4591        } finally {
4592            Binder.restoreCallingIdentity(origId);
4593        }
4594    }
4595
4596    final int startActivityInPackage(int uid, String callingPackage,
4597            Intent intent, String resolvedType, IBinder resultTo,
4598            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4599            IActivityContainer container, TaskRecord inTask) {
4600
4601        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4602                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4603
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607                null, null, null, bOptions, false, userId, container, inTask);
4608        return ret;
4609    }
4610
4611    @Override
4612    public final int startActivities(IApplicationThread caller, String callingPackage,
4613            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4614            int userId) {
4615        enforceNotIsolatedCaller("startActivities");
4616        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4618        // TODO: Switch to user app stacks here.
4619        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4620                resolvedTypes, resultTo, bOptions, userId);
4621        return ret;
4622    }
4623
4624    final int startActivitiesInPackage(int uid, String callingPackage,
4625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4626            Bundle bOptions, int userId) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4632                resultTo, bOptions, userId);
4633        return ret;
4634    }
4635
4636    @Override
4637    public void reportActivityFullyDrawn(IBinder token) {
4638        synchronized (this) {
4639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4640            if (r == null) {
4641                return;
4642            }
4643            r.reportFullyDrawnLocked();
4644        }
4645    }
4646
4647    @Override
4648    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4649        synchronized (this) {
4650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651            if (r == null) {
4652                return;
4653            }
4654            final long origId = Binder.clearCallingIdentity();
4655            try {
4656                r.setRequestedOrientation(requestedOrientation);
4657            } finally {
4658                Binder.restoreCallingIdentity(origId);
4659            }
4660        }
4661    }
4662
4663    @Override
4664    public int getRequestedOrientation(IBinder token) {
4665        synchronized (this) {
4666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4667            if (r == null) {
4668                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4669            }
4670            return mWindowManager.getAppOrientation(r.appToken);
4671        }
4672    }
4673
4674    @Override
4675    public final void requestActivityRelaunch(IBinder token) {
4676        synchronized(this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return;
4680            }
4681            final long origId = Binder.clearCallingIdentity();
4682            try {
4683                r.forceNewConfig = true;
4684                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4685                        false /* preserveWindow */);
4686            } finally {
4687                Binder.restoreCallingIdentity(origId);
4688            }
4689        }
4690    }
4691
4692    /**
4693     * This is the internal entry point for handling Activity.finish().
4694     *
4695     * @param token The Binder token referencing the Activity we want to finish.
4696     * @param resultCode Result code, if any, from this Activity.
4697     * @param resultData Result data (Intent), if any, from this Activity.
4698     * @param finishTask Whether to finish the task associated with this Activity.
4699     *
4700     * @return Returns true if the activity successfully finished, or false if it is still running.
4701     */
4702    @Override
4703    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4704            int finishTask) {
4705        // Refuse possible leaked file descriptors
4706        if (resultData != null && resultData.hasFileDescriptors() == true) {
4707            throw new IllegalArgumentException("File descriptors passed in Intent");
4708        }
4709
4710        synchronized(this) {
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r == null) {
4713                return true;
4714            }
4715            // Keep track of the root activity of the task before we finish it
4716            TaskRecord tr = r.task;
4717            ActivityRecord rootR = tr.getRootActivity();
4718            if (rootR == null) {
4719                Slog.w(TAG, "Finishing task with all activities already finished");
4720            }
4721            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4722            // finish.
4723            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4724                    mStackSupervisor.isLastLockedTask(tr)) {
4725                Slog.i(TAG, "Not finishing task in lock task mode");
4726                mStackSupervisor.showLockTaskToast();
4727                return false;
4728            }
4729            if (mController != null) {
4730                // Find the first activity that is not finishing.
4731                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4732                if (next != null) {
4733                    // ask watcher if this is allowed
4734                    boolean resumeOK = true;
4735                    try {
4736                        resumeOK = mController.activityResuming(next.packageName);
4737                    } catch (RemoteException e) {
4738                        mController = null;
4739                        Watchdog.getInstance().setActivityController(null);
4740                    }
4741
4742                    if (!resumeOK) {
4743                        Slog.i(TAG, "Not finishing activity because controller resumed");
4744                        return false;
4745                    }
4746                }
4747            }
4748            final long origId = Binder.clearCallingIdentity();
4749            try {
4750                boolean res;
4751                final boolean finishWithRootActivity =
4752                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4753                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4754                        || (finishWithRootActivity && r == rootR)) {
4755                    // If requested, remove the task that is associated to this activity only if it
4756                    // was the root activity in the task. The result code and data is ignored
4757                    // because we don't support returning them across task boundaries. Also, to
4758                    // keep backwards compatibility we remove the task from recents when finishing
4759                    // task with root activity.
4760                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4761                    if (!res) {
4762                        Slog.i(TAG, "Removing task failed to finish activity");
4763                    }
4764                } else {
4765                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4766                            resultData, "app-request", true);
4767                    if (!res) {
4768                        Slog.i(TAG, "Failed to finish by app-request");
4769                    }
4770                }
4771                return res;
4772            } finally {
4773                Binder.restoreCallingIdentity(origId);
4774            }
4775        }
4776    }
4777
4778    @Override
4779    public final void finishHeavyWeightApp() {
4780        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4781                != PackageManager.PERMISSION_GRANTED) {
4782            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4783                    + Binder.getCallingPid()
4784                    + ", uid=" + Binder.getCallingUid()
4785                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4786            Slog.w(TAG, msg);
4787            throw new SecurityException(msg);
4788        }
4789
4790        synchronized(this) {
4791            if (mHeavyWeightProcess == null) {
4792                return;
4793            }
4794
4795            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4796            for (int i = 0; i < activities.size(); i++) {
4797                ActivityRecord r = activities.get(i);
4798                if (!r.finishing && r.isInStackLocked()) {
4799                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4800                            null, "finish-heavy", true);
4801                }
4802            }
4803
4804            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4805                    mHeavyWeightProcess.userId, 0));
4806            mHeavyWeightProcess = null;
4807        }
4808    }
4809
4810    @Override
4811    public void crashApplication(int uid, int initialPid, String packageName,
4812            String message) {
4813        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4814                != PackageManager.PERMISSION_GRANTED) {
4815            String msg = "Permission Denial: crashApplication() from pid="
4816                    + Binder.getCallingPid()
4817                    + ", uid=" + Binder.getCallingUid()
4818                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4819            Slog.w(TAG, msg);
4820            throw new SecurityException(msg);
4821        }
4822
4823        synchronized(this) {
4824            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4825        }
4826    }
4827
4828    @Override
4829    public final void finishSubActivity(IBinder token, String resultWho,
4830            int requestCode) {
4831        synchronized(this) {
4832            final long origId = Binder.clearCallingIdentity();
4833            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4834            if (r != null) {
4835                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4836            }
4837            Binder.restoreCallingIdentity(origId);
4838        }
4839    }
4840
4841    @Override
4842    public boolean finishActivityAffinity(IBinder token) {
4843        synchronized(this) {
4844            final long origId = Binder.clearCallingIdentity();
4845            try {
4846                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4847                if (r == null) {
4848                    return false;
4849                }
4850
4851                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4852                // can finish.
4853                final TaskRecord task = r.task;
4854                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4855                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4856                    mStackSupervisor.showLockTaskToast();
4857                    return false;
4858                }
4859                return task.getStack().finishActivityAffinityLocked(r);
4860            } finally {
4861                Binder.restoreCallingIdentity(origId);
4862            }
4863        }
4864    }
4865
4866    @Override
4867    public void finishVoiceTask(IVoiceInteractionSession session) {
4868        synchronized (this) {
4869            final long origId = Binder.clearCallingIdentity();
4870            try {
4871                // TODO: VI Consider treating local voice interactions and voice tasks
4872                // differently here
4873                mStackSupervisor.finishVoiceTask(session);
4874            } finally {
4875                Binder.restoreCallingIdentity(origId);
4876            }
4877        }
4878
4879    }
4880
4881    @Override
4882    public boolean releaseActivityInstance(IBinder token) {
4883        synchronized(this) {
4884            final long origId = Binder.clearCallingIdentity();
4885            try {
4886                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4887                if (r == null) {
4888                    return false;
4889                }
4890                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4891            } finally {
4892                Binder.restoreCallingIdentity(origId);
4893            }
4894        }
4895    }
4896
4897    @Override
4898    public void releaseSomeActivities(IApplicationThread appInt) {
4899        synchronized(this) {
4900            final long origId = Binder.clearCallingIdentity();
4901            try {
4902                ProcessRecord app = getRecordForAppLocked(appInt);
4903                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4904            } finally {
4905                Binder.restoreCallingIdentity(origId);
4906            }
4907        }
4908    }
4909
4910    @Override
4911    public boolean willActivityBeVisible(IBinder token) {
4912        synchronized(this) {
4913            ActivityStack stack = ActivityRecord.getStackLocked(token);
4914            if (stack != null) {
4915                return stack.willActivityBeVisibleLocked(token);
4916            }
4917            return false;
4918        }
4919    }
4920
4921    @Override
4922    public void overridePendingTransition(IBinder token, String packageName,
4923            int enterAnim, int exitAnim) {
4924        synchronized(this) {
4925            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4926            if (self == null) {
4927                return;
4928            }
4929
4930            final long origId = Binder.clearCallingIdentity();
4931
4932            if (self.state == ActivityState.RESUMED
4933                    || self.state == ActivityState.PAUSING) {
4934                mWindowManager.overridePendingAppTransition(packageName,
4935                        enterAnim, exitAnim, null);
4936            }
4937
4938            Binder.restoreCallingIdentity(origId);
4939        }
4940    }
4941
4942    /**
4943     * Main function for removing an existing process from the activity manager
4944     * as a result of that process going away.  Clears out all connections
4945     * to the process.
4946     */
4947    private final void handleAppDiedLocked(ProcessRecord app,
4948            boolean restarting, boolean allowRestart) {
4949        int pid = app.pid;
4950        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4951                false /*replacingPid*/);
4952        if (!kept && !restarting) {
4953            removeLruProcessLocked(app);
4954            if (pid > 0) {
4955                ProcessList.remove(pid);
4956            }
4957        }
4958
4959        if (mProfileProc == app) {
4960            clearProfilerLocked();
4961        }
4962
4963        // Remove this application's activities from active lists.
4964        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4965
4966        app.activities.clear();
4967
4968        if (app.instrumentationClass != null) {
4969            Slog.w(TAG, "Crash of app " + app.processName
4970                  + " running instrumentation " + app.instrumentationClass);
4971            Bundle info = new Bundle();
4972            info.putString("shortMsg", "Process crashed.");
4973            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4974        }
4975
4976        if (!restarting && hasVisibleActivities
4977                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4978            // If there was nothing to resume, and we are not already restarting this process, but
4979            // there is a visible activity that is hosted by the process...  then make sure all
4980            // visible activities are running, taking care of restarting this process.
4981            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4982        }
4983    }
4984
4985    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4986        IBinder threadBinder = thread.asBinder();
4987        // Find the application record.
4988        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4989            ProcessRecord rec = mLruProcesses.get(i);
4990            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4991                return i;
4992            }
4993        }
4994        return -1;
4995    }
4996
4997    final ProcessRecord getRecordForAppLocked(
4998            IApplicationThread thread) {
4999        if (thread == null) {
5000            return null;
5001        }
5002
5003        int appIndex = getLRURecordIndexForAppLocked(thread);
5004        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5005    }
5006
5007    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5008        // If there are no longer any background processes running,
5009        // and the app that died was not running instrumentation,
5010        // then tell everyone we are now low on memory.
5011        boolean haveBg = false;
5012        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5013            ProcessRecord rec = mLruProcesses.get(i);
5014            if (rec.thread != null
5015                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5016                haveBg = true;
5017                break;
5018            }
5019        }
5020
5021        if (!haveBg) {
5022            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5023            if (doReport) {
5024                long now = SystemClock.uptimeMillis();
5025                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5026                    doReport = false;
5027                } else {
5028                    mLastMemUsageReportTime = now;
5029                }
5030            }
5031            final ArrayList<ProcessMemInfo> memInfos
5032                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5033            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5034            long now = SystemClock.uptimeMillis();
5035            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036                ProcessRecord rec = mLruProcesses.get(i);
5037                if (rec == dyingProc || rec.thread == null) {
5038                    continue;
5039                }
5040                if (doReport) {
5041                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5042                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5043                }
5044                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5045                    // The low memory report is overriding any current
5046                    // state for a GC request.  Make sure to do
5047                    // heavy/important/visible/foreground processes first.
5048                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5049                        rec.lastRequestedGc = 0;
5050                    } else {
5051                        rec.lastRequestedGc = rec.lastLowMemory;
5052                    }
5053                    rec.reportLowMemory = true;
5054                    rec.lastLowMemory = now;
5055                    mProcessesToGc.remove(rec);
5056                    addProcessToGcListLocked(rec);
5057                }
5058            }
5059            if (doReport) {
5060                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5061                mHandler.sendMessage(msg);
5062            }
5063            scheduleAppGcsLocked();
5064        }
5065    }
5066
5067    final void appDiedLocked(ProcessRecord app) {
5068       appDiedLocked(app, app.pid, app.thread, false);
5069    }
5070
5071    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5072            boolean fromBinderDied) {
5073        // First check if this ProcessRecord is actually active for the pid.
5074        synchronized (mPidsSelfLocked) {
5075            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5076            if (curProc != app) {
5077                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5078                return;
5079            }
5080        }
5081
5082        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5083        synchronized (stats) {
5084            stats.noteProcessDiedLocked(app.info.uid, pid);
5085        }
5086
5087        if (!app.killed) {
5088            if (!fromBinderDied) {
5089                Process.killProcessQuiet(pid);
5090            }
5091            killProcessGroup(app.uid, pid);
5092            app.killed = true;
5093        }
5094
5095        // Clean up already done if the process has been re-started.
5096        if (app.pid == pid && app.thread != null &&
5097                app.thread.asBinder() == thread.asBinder()) {
5098            boolean doLowMem = app.instrumentationClass == null;
5099            boolean doOomAdj = doLowMem;
5100            if (!app.killedByAm) {
5101                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5102                        + ") has died");
5103                mAllowLowerMemLevel = true;
5104            } else {
5105                // Note that we always want to do oom adj to update our state with the
5106                // new number of procs.
5107                mAllowLowerMemLevel = false;
5108                doLowMem = false;
5109            }
5110            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5111            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5112                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5113            handleAppDiedLocked(app, false, true);
5114
5115            if (doOomAdj) {
5116                updateOomAdjLocked();
5117            }
5118            if (doLowMem) {
5119                doLowMemReportIfNeededLocked(app);
5120            }
5121        } else if (app.pid != pid) {
5122            // A new process has already been started.
5123            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5124                    + ") has died and restarted (pid " + app.pid + ").");
5125            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5126        } else if (DEBUG_PROCESSES) {
5127            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5128                    + thread.asBinder());
5129        }
5130    }
5131
5132    /**
5133     * If a stack trace dump file is configured, dump process stack traces.
5134     * @param clearTraces causes the dump file to be erased prior to the new
5135     *    traces being written, if true; when false, the new traces will be
5136     *    appended to any existing file content.
5137     * @param firstPids of dalvik VM processes to dump stack traces for first
5138     * @param lastPids of dalvik VM processes to dump stack traces for last
5139     * @param nativeProcs optional list of native process names to dump stack crawls
5140     * @return file containing stack traces, or null if no dump file is configured
5141     */
5142    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5143            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5144        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5145        if (tracesPath == null || tracesPath.length() == 0) {
5146            return null;
5147        }
5148
5149        File tracesFile = new File(tracesPath);
5150        try {
5151            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5152            tracesFile.createNewFile();
5153            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5154        } catch (IOException e) {
5155            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5156            return null;
5157        }
5158
5159        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5160        return tracesFile;
5161    }
5162
5163    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5164            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5165        // Use a FileObserver to detect when traces finish writing.
5166        // The order of traces is considered important to maintain for legibility.
5167        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5168            @Override
5169            public synchronized void onEvent(int event, String path) { notify(); }
5170        };
5171
5172        try {
5173            observer.startWatching();
5174
5175            // First collect all of the stacks of the most important pids.
5176            if (firstPids != null) {
5177                try {
5178                    int num = firstPids.size();
5179                    for (int i = 0; i < num; i++) {
5180                        synchronized (observer) {
5181                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5182                                    + firstPids.get(i));
5183                            final long sime = SystemClock.elapsedRealtime();
5184                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5185                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5186                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5187                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5188                        }
5189                    }
5190                } catch (InterruptedException e) {
5191                    Slog.wtf(TAG, e);
5192                }
5193            }
5194
5195            // Next collect the stacks of the native pids
5196            if (nativeProcs != null) {
5197                int[] pids = Process.getPidsForCommands(nativeProcs);
5198                if (pids != null) {
5199                    for (int pid : pids) {
5200                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5201                        final long sime = SystemClock.elapsedRealtime();
5202                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5203                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5204                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5205                    }
5206                }
5207            }
5208
5209            // Lastly, measure CPU usage.
5210            if (processCpuTracker != null) {
5211                processCpuTracker.init();
5212                System.gc();
5213                processCpuTracker.update();
5214                try {
5215                    synchronized (processCpuTracker) {
5216                        processCpuTracker.wait(500); // measure over 1/2 second.
5217                    }
5218                } catch (InterruptedException e) {
5219                }
5220                processCpuTracker.update();
5221
5222                // We'll take the stack crawls of just the top apps using CPU.
5223                final int N = processCpuTracker.countWorkingStats();
5224                int numProcs = 0;
5225                for (int i=0; i<N && numProcs<5; i++) {
5226                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5227                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5228                        numProcs++;
5229                        try {
5230                            synchronized (observer) {
5231                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5232                                        + stats.pid);
5233                                final long stime = SystemClock.elapsedRealtime();
5234                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5235                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5236                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5237                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5238                            }
5239                        } catch (InterruptedException e) {
5240                            Slog.wtf(TAG, e);
5241                        }
5242                    } else if (DEBUG_ANR) {
5243                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5244                                + stats.pid);
5245                    }
5246                }
5247            }
5248        } finally {
5249            observer.stopWatching();
5250        }
5251    }
5252
5253    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5254        if (true || IS_USER_BUILD) {
5255            return;
5256        }
5257        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5258        if (tracesPath == null || tracesPath.length() == 0) {
5259            return;
5260        }
5261
5262        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5263        StrictMode.allowThreadDiskWrites();
5264        try {
5265            final File tracesFile = new File(tracesPath);
5266            final File tracesDir = tracesFile.getParentFile();
5267            final File tracesTmp = new File(tracesDir, "__tmp__");
5268            try {
5269                if (tracesFile.exists()) {
5270                    tracesTmp.delete();
5271                    tracesFile.renameTo(tracesTmp);
5272                }
5273                StringBuilder sb = new StringBuilder();
5274                Time tobj = new Time();
5275                tobj.set(System.currentTimeMillis());
5276                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5277                sb.append(": ");
5278                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5279                sb.append(" since ");
5280                sb.append(msg);
5281                FileOutputStream fos = new FileOutputStream(tracesFile);
5282                fos.write(sb.toString().getBytes());
5283                if (app == null) {
5284                    fos.write("\n*** No application process!".getBytes());
5285                }
5286                fos.close();
5287                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5288            } catch (IOException e) {
5289                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5290                return;
5291            }
5292
5293            if (app != null) {
5294                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5295                firstPids.add(app.pid);
5296                dumpStackTraces(tracesPath, firstPids, null, null, null);
5297            }
5298
5299            File lastTracesFile = null;
5300            File curTracesFile = null;
5301            for (int i=9; i>=0; i--) {
5302                String name = String.format(Locale.US, "slow%02d.txt", i);
5303                curTracesFile = new File(tracesDir, name);
5304                if (curTracesFile.exists()) {
5305                    if (lastTracesFile != null) {
5306                        curTracesFile.renameTo(lastTracesFile);
5307                    } else {
5308                        curTracesFile.delete();
5309                    }
5310                }
5311                lastTracesFile = curTracesFile;
5312            }
5313            tracesFile.renameTo(curTracesFile);
5314            if (tracesTmp.exists()) {
5315                tracesTmp.renameTo(tracesFile);
5316            }
5317        } finally {
5318            StrictMode.setThreadPolicy(oldPolicy);
5319        }
5320    }
5321
5322    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5323        if (!mLaunchWarningShown) {
5324            mLaunchWarningShown = true;
5325            mUiHandler.post(new Runnable() {
5326                @Override
5327                public void run() {
5328                    synchronized (ActivityManagerService.this) {
5329                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5330                        d.show();
5331                        mUiHandler.postDelayed(new Runnable() {
5332                            @Override
5333                            public void run() {
5334                                synchronized (ActivityManagerService.this) {
5335                                    d.dismiss();
5336                                    mLaunchWarningShown = false;
5337                                }
5338                            }
5339                        }, 4000);
5340                    }
5341                }
5342            });
5343        }
5344    }
5345
5346    @Override
5347    public boolean clearApplicationUserData(final String packageName,
5348            final IPackageDataObserver observer, int userId) {
5349        enforceNotIsolatedCaller("clearApplicationUserData");
5350        int uid = Binder.getCallingUid();
5351        int pid = Binder.getCallingPid();
5352        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5353                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5354
5355
5356        long callingId = Binder.clearCallingIdentity();
5357        try {
5358            IPackageManager pm = AppGlobals.getPackageManager();
5359            int pkgUid = -1;
5360            synchronized(this) {
5361                if (getPackageManagerInternalLocked().isPackageDataProtected(
5362                        userId, packageName)) {
5363                    throw new SecurityException(
5364                            "Cannot clear data for a protected package: " + packageName);
5365                }
5366
5367                try {
5368                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5369                } catch (RemoteException e) {
5370                }
5371                if (pkgUid == -1) {
5372                    Slog.w(TAG, "Invalid packageName: " + packageName);
5373                    if (observer != null) {
5374                        try {
5375                            observer.onRemoveCompleted(packageName, false);
5376                        } catch (RemoteException e) {
5377                            Slog.i(TAG, "Observer no longer exists.");
5378                        }
5379                    }
5380                    return false;
5381                }
5382                if (uid == pkgUid || checkComponentPermission(
5383                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5384                        pid, uid, -1, true)
5385                        == PackageManager.PERMISSION_GRANTED) {
5386                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5387                } else {
5388                    throw new SecurityException("PID " + pid + " does not have permission "
5389                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5390                                    + " of package " + packageName);
5391                }
5392
5393                // Remove all tasks match the cleared application package and user
5394                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5395                    final TaskRecord tr = mRecentTasks.get(i);
5396                    final String taskPackageName =
5397                            tr.getBaseIntent().getComponent().getPackageName();
5398                    if (tr.userId != userId) continue;
5399                    if (!taskPackageName.equals(packageName)) continue;
5400                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5401                }
5402            }
5403
5404            final int pkgUidF = pkgUid;
5405            final int userIdF = userId;
5406            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5407                @Override
5408                public void onRemoveCompleted(String packageName, boolean succeeded)
5409                        throws RemoteException {
5410                    synchronized (ActivityManagerService.this) {
5411                        finishForceStopPackageLocked(packageName, pkgUidF);
5412                    }
5413
5414                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5415                            Uri.fromParts("package", packageName, null));
5416                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5417                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5418                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5419                            null, null, 0, null, null, null, null, false, false, userIdF);
5420
5421                    if (observer != null) {
5422                        observer.onRemoveCompleted(packageName, succeeded);
5423                    }
5424                }
5425            };
5426
5427            try {
5428                // Clear application user data
5429                pm.clearApplicationUserData(packageName, localObserver, userId);
5430
5431                synchronized(this) {
5432                    // Remove all permissions granted from/to this package
5433                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5434                }
5435
5436                // Remove all zen rules created by this package; revoke it's zen access.
5437                INotificationManager inm = NotificationManager.getService();
5438                inm.removeAutomaticZenRules(packageName);
5439                inm.setNotificationPolicyAccessGranted(packageName, false);
5440
5441            } catch (RemoteException e) {
5442            }
5443        } finally {
5444            Binder.restoreCallingIdentity(callingId);
5445        }
5446        return true;
5447    }
5448
5449    @Override
5450    public void killBackgroundProcesses(final String packageName, int userId) {
5451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5452                != PackageManager.PERMISSION_GRANTED &&
5453                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5454                        != PackageManager.PERMISSION_GRANTED) {
5455            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5456                    + Binder.getCallingPid()
5457                    + ", uid=" + Binder.getCallingUid()
5458                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5459            Slog.w(TAG, msg);
5460            throw new SecurityException(msg);
5461        }
5462
5463        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5464                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5465        long callingId = Binder.clearCallingIdentity();
5466        try {
5467            IPackageManager pm = AppGlobals.getPackageManager();
5468            synchronized(this) {
5469                int appId = -1;
5470                try {
5471                    appId = UserHandle.getAppId(
5472                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5473                } catch (RemoteException e) {
5474                }
5475                if (appId == -1) {
5476                    Slog.w(TAG, "Invalid packageName: " + packageName);
5477                    return;
5478                }
5479                killPackageProcessesLocked(packageName, appId, userId,
5480                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5481            }
5482        } finally {
5483            Binder.restoreCallingIdentity(callingId);
5484        }
5485    }
5486
5487    @Override
5488    public void killAllBackgroundProcesses() {
5489        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5490                != PackageManager.PERMISSION_GRANTED) {
5491            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5492                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5493                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5494            Slog.w(TAG, msg);
5495            throw new SecurityException(msg);
5496        }
5497
5498        final long callingId = Binder.clearCallingIdentity();
5499        try {
5500            synchronized (this) {
5501                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5502                final int NP = mProcessNames.getMap().size();
5503                for (int ip = 0; ip < NP; ip++) {
5504                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5505                    final int NA = apps.size();
5506                    for (int ia = 0; ia < NA; ia++) {
5507                        final ProcessRecord app = apps.valueAt(ia);
5508                        if (app.persistent) {
5509                            // We don't kill persistent processes.
5510                            continue;
5511                        }
5512                        if (app.removed) {
5513                            procs.add(app);
5514                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5515                            app.removed = true;
5516                            procs.add(app);
5517                        }
5518                    }
5519                }
5520
5521                final int N = procs.size();
5522                for (int i = 0; i < N; i++) {
5523                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5524                }
5525
5526                mAllowLowerMemLevel = true;
5527
5528                updateOomAdjLocked();
5529                doLowMemReportIfNeededLocked(null);
5530            }
5531        } finally {
5532            Binder.restoreCallingIdentity(callingId);
5533        }
5534    }
5535
5536    /**
5537     * Kills all background processes, except those matching any of the
5538     * specified properties.
5539     *
5540     * @param minTargetSdk the target SDK version at or above which to preserve
5541     *                     processes, or {@code -1} to ignore the target SDK
5542     * @param maxProcState the process state at or below which to preserve
5543     *                     processes, or {@code -1} to ignore the process state
5544     */
5545    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5547                != PackageManager.PERMISSION_GRANTED) {
5548            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5549                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5550                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5551            Slog.w(TAG, msg);
5552            throw new SecurityException(msg);
5553        }
5554
5555        final long callingId = Binder.clearCallingIdentity();
5556        try {
5557            synchronized (this) {
5558                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5559                final int NP = mProcessNames.getMap().size();
5560                for (int ip = 0; ip < NP; ip++) {
5561                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5562                    final int NA = apps.size();
5563                    for (int ia = 0; ia < NA; ia++) {
5564                        final ProcessRecord app = apps.valueAt(ia);
5565                        if (app.removed) {
5566                            procs.add(app);
5567                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5568                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5569                            app.removed = true;
5570                            procs.add(app);
5571                        }
5572                    }
5573                }
5574
5575                final int N = procs.size();
5576                for (int i = 0; i < N; i++) {
5577                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5578                }
5579            }
5580        } finally {
5581            Binder.restoreCallingIdentity(callingId);
5582        }
5583    }
5584
5585    @Override
5586    public void forceStopPackage(final String packageName, int userId) {
5587        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5588                != PackageManager.PERMISSION_GRANTED) {
5589            String msg = "Permission Denial: forceStopPackage() from pid="
5590                    + Binder.getCallingPid()
5591                    + ", uid=" + Binder.getCallingUid()
5592                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5593            Slog.w(TAG, msg);
5594            throw new SecurityException(msg);
5595        }
5596        final int callingPid = Binder.getCallingPid();
5597        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5598                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5599        long callingId = Binder.clearCallingIdentity();
5600        try {
5601            IPackageManager pm = AppGlobals.getPackageManager();
5602            synchronized(this) {
5603                int[] users = userId == UserHandle.USER_ALL
5604                        ? mUserController.getUsers() : new int[] { userId };
5605                for (int user : users) {
5606                    int pkgUid = -1;
5607                    try {
5608                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5609                                user);
5610                    } catch (RemoteException e) {
5611                    }
5612                    if (pkgUid == -1) {
5613                        Slog.w(TAG, "Invalid packageName: " + packageName);
5614                        continue;
5615                    }
5616                    try {
5617                        pm.setPackageStoppedState(packageName, true, user);
5618                    } catch (RemoteException e) {
5619                    } catch (IllegalArgumentException e) {
5620                        Slog.w(TAG, "Failed trying to unstop package "
5621                                + packageName + ": " + e);
5622                    }
5623                    if (mUserController.isUserRunningLocked(user, 0)) {
5624                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5625                        finishForceStopPackageLocked(packageName, pkgUid);
5626                    }
5627                }
5628            }
5629        } finally {
5630            Binder.restoreCallingIdentity(callingId);
5631        }
5632    }
5633
5634    @Override
5635    public void addPackageDependency(String packageName) {
5636        synchronized (this) {
5637            int callingPid = Binder.getCallingPid();
5638            if (callingPid == Process.myPid()) {
5639                //  Yeah, um, no.
5640                return;
5641            }
5642            ProcessRecord proc;
5643            synchronized (mPidsSelfLocked) {
5644                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5645            }
5646            if (proc != null) {
5647                if (proc.pkgDeps == null) {
5648                    proc.pkgDeps = new ArraySet<String>(1);
5649                }
5650                proc.pkgDeps.add(packageName);
5651            }
5652        }
5653    }
5654
5655    /*
5656     * The pkg name and app id have to be specified.
5657     */
5658    @Override
5659    public void killApplication(String pkg, int appId, int userId, String reason) {
5660        if (pkg == null) {
5661            return;
5662        }
5663        // Make sure the uid is valid.
5664        if (appId < 0) {
5665            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5666            return;
5667        }
5668        int callerUid = Binder.getCallingUid();
5669        // Only the system server can kill an application
5670        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5671            // Post an aysnc message to kill the application
5672            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5673            msg.arg1 = appId;
5674            msg.arg2 = userId;
5675            Bundle bundle = new Bundle();
5676            bundle.putString("pkg", pkg);
5677            bundle.putString("reason", reason);
5678            msg.obj = bundle;
5679            mHandler.sendMessage(msg);
5680        } else {
5681            throw new SecurityException(callerUid + " cannot kill pkg: " +
5682                    pkg);
5683        }
5684    }
5685
5686    @Override
5687    public void closeSystemDialogs(String reason) {
5688        enforceNotIsolatedCaller("closeSystemDialogs");
5689
5690        final int pid = Binder.getCallingPid();
5691        final int uid = Binder.getCallingUid();
5692        final long origId = Binder.clearCallingIdentity();
5693        try {
5694            synchronized (this) {
5695                // Only allow this from foreground processes, so that background
5696                // applications can't abuse it to prevent system UI from being shown.
5697                if (uid >= Process.FIRST_APPLICATION_UID) {
5698                    ProcessRecord proc;
5699                    synchronized (mPidsSelfLocked) {
5700                        proc = mPidsSelfLocked.get(pid);
5701                    }
5702                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5703                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5704                                + " from background process " + proc);
5705                        return;
5706                    }
5707                }
5708                closeSystemDialogsLocked(reason);
5709            }
5710        } finally {
5711            Binder.restoreCallingIdentity(origId);
5712        }
5713    }
5714
5715    void closeSystemDialogsLocked(String reason) {
5716        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5717        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5718                | Intent.FLAG_RECEIVER_FOREGROUND);
5719        if (reason != null) {
5720            intent.putExtra("reason", reason);
5721        }
5722        mWindowManager.closeSystemDialogs(reason);
5723
5724        mStackSupervisor.closeSystemDialogsLocked();
5725
5726        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5727                AppOpsManager.OP_NONE, null, false, false,
5728                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5729    }
5730
5731    @Override
5732    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5733        enforceNotIsolatedCaller("getProcessMemoryInfo");
5734        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5735        for (int i=pids.length-1; i>=0; i--) {
5736            ProcessRecord proc;
5737            int oomAdj;
5738            synchronized (this) {
5739                synchronized (mPidsSelfLocked) {
5740                    proc = mPidsSelfLocked.get(pids[i]);
5741                    oomAdj = proc != null ? proc.setAdj : 0;
5742                }
5743            }
5744            infos[i] = new Debug.MemoryInfo();
5745            Debug.getMemoryInfo(pids[i], infos[i]);
5746            if (proc != null) {
5747                synchronized (this) {
5748                    if (proc.thread != null && proc.setAdj == oomAdj) {
5749                        // Record this for posterity if the process has been stable.
5750                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5751                                infos[i].getTotalUss(), false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return infos;
5757    }
5758
5759    @Override
5760    public long[] getProcessPss(int[] pids) {
5761        enforceNotIsolatedCaller("getProcessPss");
5762        long[] pss = new long[pids.length];
5763        for (int i=pids.length-1; i>=0; i--) {
5764            ProcessRecord proc;
5765            int oomAdj;
5766            synchronized (this) {
5767                synchronized (mPidsSelfLocked) {
5768                    proc = mPidsSelfLocked.get(pids[i]);
5769                    oomAdj = proc != null ? proc.setAdj : 0;
5770                }
5771            }
5772            long[] tmpUss = new long[1];
5773            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5774            if (proc != null) {
5775                synchronized (this) {
5776                    if (proc.thread != null && proc.setAdj == oomAdj) {
5777                        // Record this for posterity if the process has been stable.
5778                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5779                    }
5780                }
5781            }
5782        }
5783        return pss;
5784    }
5785
5786    @Override
5787    public void killApplicationProcess(String processName, int uid) {
5788        if (processName == null) {
5789            return;
5790        }
5791
5792        int callerUid = Binder.getCallingUid();
5793        // Only the system server can kill an application
5794        if (callerUid == Process.SYSTEM_UID) {
5795            synchronized (this) {
5796                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5797                if (app != null && app.thread != null) {
5798                    try {
5799                        app.thread.scheduleSuicide();
5800                    } catch (RemoteException e) {
5801                        // If the other end already died, then our work here is done.
5802                    }
5803                } else {
5804                    Slog.w(TAG, "Process/uid not found attempting kill of "
5805                            + processName + " / " + uid);
5806                }
5807            }
5808        } else {
5809            throw new SecurityException(callerUid + " cannot kill app process: " +
5810                    processName);
5811        }
5812    }
5813
5814    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5815        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5816                false, true, false, false, UserHandle.getUserId(uid), reason);
5817    }
5818
5819    private void finishForceStopPackageLocked(final String packageName, int uid) {
5820        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5821                Uri.fromParts("package", packageName, null));
5822        if (!mProcessesReady) {
5823            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5824                    | Intent.FLAG_RECEIVER_FOREGROUND);
5825        }
5826        intent.putExtra(Intent.EXTRA_UID, uid);
5827        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5828        broadcastIntentLocked(null, null, intent,
5829                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5830                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5831    }
5832
5833
5834    private final boolean killPackageProcessesLocked(String packageName, int appId,
5835            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5836            boolean doit, boolean evenPersistent, String reason) {
5837        ArrayList<ProcessRecord> procs = new ArrayList<>();
5838
5839        // Remove all processes this package may have touched: all with the
5840        // same UID (except for the system or root user), and all whose name
5841        // matches the package name.
5842        final int NP = mProcessNames.getMap().size();
5843        for (int ip=0; ip<NP; ip++) {
5844            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5845            final int NA = apps.size();
5846            for (int ia=0; ia<NA; ia++) {
5847                ProcessRecord app = apps.valueAt(ia);
5848                if (app.persistent && !evenPersistent) {
5849                    // we don't kill persistent processes
5850                    continue;
5851                }
5852                if (app.removed) {
5853                    if (doit) {
5854                        procs.add(app);
5855                    }
5856                    continue;
5857                }
5858
5859                // Skip process if it doesn't meet our oom adj requirement.
5860                if (app.setAdj < minOomAdj) {
5861                    continue;
5862                }
5863
5864                // If no package is specified, we call all processes under the
5865                // give user id.
5866                if (packageName == null) {
5867                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5868                        continue;
5869                    }
5870                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5871                        continue;
5872                    }
5873                // Package has been specified, we want to hit all processes
5874                // that match it.  We need to qualify this by the processes
5875                // that are running under the specified app and user ID.
5876                } else {
5877                    final boolean isDep = app.pkgDeps != null
5878                            && app.pkgDeps.contains(packageName);
5879                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5880                        continue;
5881                    }
5882                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5883                        continue;
5884                    }
5885                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5886                        continue;
5887                    }
5888                }
5889
5890                // Process has passed all conditions, kill it!
5891                if (!doit) {
5892                    return true;
5893                }
5894                app.removed = true;
5895                procs.add(app);
5896            }
5897        }
5898
5899        int N = procs.size();
5900        for (int i=0; i<N; i++) {
5901            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5902        }
5903        updateOomAdjLocked();
5904        return N > 0;
5905    }
5906
5907    private void cleanupDisabledPackageComponentsLocked(
5908            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5909
5910        Set<String> disabledClasses = null;
5911        boolean packageDisabled = false;
5912        IPackageManager pm = AppGlobals.getPackageManager();
5913
5914        if (changedClasses == null) {
5915            // Nothing changed...
5916            return;
5917        }
5918
5919        // Determine enable/disable state of the package and its components.
5920        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5921        for (int i = changedClasses.length - 1; i >= 0; i--) {
5922            final String changedClass = changedClasses[i];
5923
5924            if (changedClass.equals(packageName)) {
5925                try {
5926                    // Entire package setting changed
5927                    enabled = pm.getApplicationEnabledSetting(packageName,
5928                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5929                } catch (Exception e) {
5930                    // No such package/component; probably racing with uninstall.  In any
5931                    // event it means we have nothing further to do here.
5932                    return;
5933                }
5934                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5935                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5936                if (packageDisabled) {
5937                    // Entire package is disabled.
5938                    // No need to continue to check component states.
5939                    disabledClasses = null;
5940                    break;
5941                }
5942            } else {
5943                try {
5944                    enabled = pm.getComponentEnabledSetting(
5945                            new ComponentName(packageName, changedClass),
5946                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5947                } catch (Exception e) {
5948                    // As above, probably racing with uninstall.
5949                    return;
5950                }
5951                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5952                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5953                    if (disabledClasses == null) {
5954                        disabledClasses = new ArraySet<>(changedClasses.length);
5955                    }
5956                    disabledClasses.add(changedClass);
5957                }
5958            }
5959        }
5960
5961        if (!packageDisabled && disabledClasses == null) {
5962            // Nothing to do here...
5963            return;
5964        }
5965
5966        // Clean-up disabled activities.
5967        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5968                packageName, disabledClasses, true, false, userId) && mBooted) {
5969            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5970            mStackSupervisor.scheduleIdleLocked();
5971        }
5972
5973        // Clean-up disabled tasks
5974        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5975
5976        // Clean-up disabled services.
5977        mServices.bringDownDisabledPackageServicesLocked(
5978                packageName, disabledClasses, userId, false, killProcess, true);
5979
5980        // Clean-up disabled providers.
5981        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5982        mProviderMap.collectPackageProvidersLocked(
5983                packageName, disabledClasses, true, false, userId, providers);
5984        for (int i = providers.size() - 1; i >= 0; i--) {
5985            removeDyingProviderLocked(null, providers.get(i), true);
5986        }
5987
5988        // Clean-up disabled broadcast receivers.
5989        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5990            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5991                    packageName, disabledClasses, userId, true);
5992        }
5993
5994    }
5995
5996    final boolean clearBroadcastQueueForUserLocked(int userId) {
5997        boolean didSomething = false;
5998        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5999            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6000                    null, null, userId, true);
6001        }
6002        return didSomething;
6003    }
6004
6005    final boolean forceStopPackageLocked(String packageName, int appId,
6006            boolean callerWillRestart, boolean purgeCache, boolean doit,
6007            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6008        int i;
6009
6010        if (userId == UserHandle.USER_ALL && packageName == null) {
6011            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6012        }
6013
6014        if (appId < 0 && packageName != null) {
6015            try {
6016                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6017                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6018            } catch (RemoteException e) {
6019            }
6020        }
6021
6022        if (doit) {
6023            if (packageName != null) {
6024                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6025                        + " user=" + userId + ": " + reason);
6026            } else {
6027                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6028            }
6029
6030            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6031        }
6032
6033        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6034                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6035                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6036
6037        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6038
6039        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6040                packageName, null, doit, evenPersistent, userId)) {
6041            if (!doit) {
6042                return true;
6043            }
6044            didSomething = true;
6045        }
6046
6047        if (mServices.bringDownDisabledPackageServicesLocked(
6048                packageName, null, userId, evenPersistent, true, doit)) {
6049            if (!doit) {
6050                return true;
6051            }
6052            didSomething = true;
6053        }
6054
6055        if (packageName == null) {
6056            // Remove all sticky broadcasts from this user.
6057            mStickyBroadcasts.remove(userId);
6058        }
6059
6060        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6061        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6062                userId, providers)) {
6063            if (!doit) {
6064                return true;
6065            }
6066            didSomething = true;
6067        }
6068        for (i = providers.size() - 1; i >= 0; i--) {
6069            removeDyingProviderLocked(null, providers.get(i), true);
6070        }
6071
6072        // Remove transient permissions granted from/to this package/user
6073        removeUriPermissionsForPackageLocked(packageName, userId, false);
6074
6075        if (doit) {
6076            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6077                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6078                        packageName, null, userId, doit);
6079            }
6080        }
6081
6082        if (packageName == null || uninstalling) {
6083            // Remove pending intents.  For now we only do this when force
6084            // stopping users, because we have some problems when doing this
6085            // for packages -- app widgets are not currently cleaned up for
6086            // such packages, so they can be left with bad pending intents.
6087            if (mIntentSenderRecords.size() > 0) {
6088                Iterator<WeakReference<PendingIntentRecord>> it
6089                        = mIntentSenderRecords.values().iterator();
6090                while (it.hasNext()) {
6091                    WeakReference<PendingIntentRecord> wpir = it.next();
6092                    if (wpir == null) {
6093                        it.remove();
6094                        continue;
6095                    }
6096                    PendingIntentRecord pir = wpir.get();
6097                    if (pir == null) {
6098                        it.remove();
6099                        continue;
6100                    }
6101                    if (packageName == null) {
6102                        // Stopping user, remove all objects for the user.
6103                        if (pir.key.userId != userId) {
6104                            // Not the same user, skip it.
6105                            continue;
6106                        }
6107                    } else {
6108                        if (UserHandle.getAppId(pir.uid) != appId) {
6109                            // Different app id, skip it.
6110                            continue;
6111                        }
6112                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6113                            // Different user, skip it.
6114                            continue;
6115                        }
6116                        if (!pir.key.packageName.equals(packageName)) {
6117                            // Different package, skip it.
6118                            continue;
6119                        }
6120                    }
6121                    if (!doit) {
6122                        return true;
6123                    }
6124                    didSomething = true;
6125                    it.remove();
6126                    pir.canceled = true;
6127                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6128                        pir.key.activity.pendingResults.remove(pir.ref);
6129                    }
6130                }
6131            }
6132        }
6133
6134        if (doit) {
6135            if (purgeCache && packageName != null) {
6136                AttributeCache ac = AttributeCache.instance();
6137                if (ac != null) {
6138                    ac.removePackage(packageName);
6139                }
6140            }
6141            if (mBooted) {
6142                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6143                mStackSupervisor.scheduleIdleLocked();
6144            }
6145        }
6146
6147        return didSomething;
6148    }
6149
6150    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6151        ProcessRecord old = mProcessNames.remove(name, uid);
6152        if (old != null) {
6153            old.uidRecord.numProcs--;
6154            if (old.uidRecord.numProcs == 0) {
6155                // No more processes using this uid, tell clients it is gone.
6156                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6157                        "No more processes in " + old.uidRecord);
6158                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6159                mActiveUids.remove(uid);
6160                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6161            }
6162            old.uidRecord = null;
6163        }
6164        mIsolatedProcesses.remove(uid);
6165        return old;
6166    }
6167
6168    private final void addProcessNameLocked(ProcessRecord proc) {
6169        // We shouldn't already have a process under this name, but just in case we
6170        // need to clean up whatever may be there now.
6171        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6172        if (old == proc && proc.persistent) {
6173            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6174            Slog.w(TAG, "Re-adding persistent process " + proc);
6175        } else if (old != null) {
6176            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6177        }
6178        UidRecord uidRec = mActiveUids.get(proc.uid);
6179        if (uidRec == null) {
6180            uidRec = new UidRecord(proc.uid);
6181            // This is the first appearance of the uid, report it now!
6182            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6183                    "Creating new process uid: " + uidRec);
6184            mActiveUids.put(proc.uid, uidRec);
6185            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6186            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6187        }
6188        proc.uidRecord = uidRec;
6189
6190        // Reset render thread tid if it was already set, so new process can set it again.
6191        proc.renderThreadTid = 0;
6192        uidRec.numProcs++;
6193        mProcessNames.put(proc.processName, proc.uid, proc);
6194        if (proc.isolated) {
6195            mIsolatedProcesses.put(proc.uid, proc);
6196        }
6197    }
6198
6199    boolean removeProcessLocked(ProcessRecord app,
6200            boolean callerWillRestart, boolean allowRestart, String reason) {
6201        final String name = app.processName;
6202        final int uid = app.uid;
6203        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6204            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6205
6206        ProcessRecord old = mProcessNames.get(name, uid);
6207        if (old != app) {
6208            // This process is no longer active, so nothing to do.
6209            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6210            return false;
6211        }
6212        removeProcessNameLocked(name, uid);
6213        if (mHeavyWeightProcess == app) {
6214            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6215                    mHeavyWeightProcess.userId, 0));
6216            mHeavyWeightProcess = null;
6217        }
6218        boolean needRestart = false;
6219        if (app.pid > 0 && app.pid != MY_PID) {
6220            int pid = app.pid;
6221            synchronized (mPidsSelfLocked) {
6222                mPidsSelfLocked.remove(pid);
6223                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6224            }
6225            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6226            if (app.isolated) {
6227                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6228            }
6229            boolean willRestart = false;
6230            if (app.persistent && !app.isolated) {
6231                if (!callerWillRestart) {
6232                    willRestart = true;
6233                } else {
6234                    needRestart = true;
6235                }
6236            }
6237            app.kill(reason, true);
6238            handleAppDiedLocked(app, willRestart, allowRestart);
6239            if (willRestart) {
6240                removeLruProcessLocked(app);
6241                addAppLocked(app.info, false, null /* ABI override */);
6242            }
6243        } else {
6244            mRemovedProcesses.add(app);
6245        }
6246
6247        return needRestart;
6248    }
6249
6250    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6251        cleanupAppInLaunchingProvidersLocked(app, true);
6252        removeProcessLocked(app, false, true, "timeout publishing content providers");
6253    }
6254
6255    private final void processStartTimedOutLocked(ProcessRecord app) {
6256        final int pid = app.pid;
6257        boolean gone = false;
6258        synchronized (mPidsSelfLocked) {
6259            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6260            if (knownApp != null && knownApp.thread == null) {
6261                mPidsSelfLocked.remove(pid);
6262                gone = true;
6263            }
6264        }
6265
6266        if (gone) {
6267            Slog.w(TAG, "Process " + app + " failed to attach");
6268            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6269                    pid, app.uid, app.processName);
6270            removeProcessNameLocked(app.processName, app.uid);
6271            if (mHeavyWeightProcess == app) {
6272                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6273                        mHeavyWeightProcess.userId, 0));
6274                mHeavyWeightProcess = null;
6275            }
6276            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6277            if (app.isolated) {
6278                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6279            }
6280            // Take care of any launching providers waiting for this process.
6281            cleanupAppInLaunchingProvidersLocked(app, true);
6282            // Take care of any services that are waiting for the process.
6283            mServices.processStartTimedOutLocked(app);
6284            app.kill("start timeout", true);
6285            removeLruProcessLocked(app);
6286            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6287                Slog.w(TAG, "Unattached app died before backup, skipping");
6288                try {
6289                    IBackupManager bm = IBackupManager.Stub.asInterface(
6290                            ServiceManager.getService(Context.BACKUP_SERVICE));
6291                    bm.agentDisconnected(app.info.packageName);
6292                } catch (RemoteException e) {
6293                    // Can't happen; the backup manager is local
6294                }
6295            }
6296            if (isPendingBroadcastProcessLocked(pid)) {
6297                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6298                skipPendingBroadcastLocked(pid);
6299            }
6300        } else {
6301            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6302        }
6303    }
6304
6305    private final boolean attachApplicationLocked(IApplicationThread thread,
6306            int pid) {
6307
6308        // Find the application record that is being attached...  either via
6309        // the pid if we are running in multiple processes, or just pull the
6310        // next app record if we are emulating process with anonymous threads.
6311        ProcessRecord app;
6312        if (pid != MY_PID && pid >= 0) {
6313            synchronized (mPidsSelfLocked) {
6314                app = mPidsSelfLocked.get(pid);
6315            }
6316        } else {
6317            app = null;
6318        }
6319
6320        if (app == null) {
6321            Slog.w(TAG, "No pending application record for pid " + pid
6322                    + " (IApplicationThread " + thread + "); dropping process");
6323            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6324            if (pid > 0 && pid != MY_PID) {
6325                Process.killProcessQuiet(pid);
6326                //TODO: killProcessGroup(app.info.uid, pid);
6327            } else {
6328                try {
6329                    thread.scheduleExit();
6330                } catch (Exception e) {
6331                    // Ignore exceptions.
6332                }
6333            }
6334            return false;
6335        }
6336
6337        // If this application record is still attached to a previous
6338        // process, clean it up now.
6339        if (app.thread != null) {
6340            handleAppDiedLocked(app, true, true);
6341        }
6342
6343        // Tell the process all about itself.
6344
6345        if (DEBUG_ALL) Slog.v(
6346                TAG, "Binding process pid " + pid + " to record " + app);
6347
6348        final String processName = app.processName;
6349        try {
6350            AppDeathRecipient adr = new AppDeathRecipient(
6351                    app, pid, thread);
6352            thread.asBinder().linkToDeath(adr, 0);
6353            app.deathRecipient = adr;
6354        } catch (RemoteException e) {
6355            app.resetPackageList(mProcessStats);
6356            startProcessLocked(app, "link fail", processName);
6357            return false;
6358        }
6359
6360        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6361
6362        app.makeActive(thread, mProcessStats);
6363        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6364        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6365        app.forcingToForeground = null;
6366        updateProcessForegroundLocked(app, false, false);
6367        app.hasShownUi = false;
6368        app.debugging = false;
6369        app.cached = false;
6370        app.killedByAm = false;
6371        app.killed = false;
6372
6373
6374        // We carefully use the same state that PackageManager uses for
6375        // filtering, since we use this flag to decide if we need to install
6376        // providers when user is unlocked later
6377        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6378
6379        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6380
6381        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6382        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6383
6384        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6385            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6386            msg.obj = app;
6387            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6388        }
6389
6390        if (!normalMode) {
6391            Slog.i(TAG, "Launching preboot mode app: " + app);
6392        }
6393
6394        if (DEBUG_ALL) Slog.v(
6395            TAG, "New app record " + app
6396            + " thread=" + thread.asBinder() + " pid=" + pid);
6397        try {
6398            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6399            if (mDebugApp != null && mDebugApp.equals(processName)) {
6400                testMode = mWaitForDebugger
6401                    ? ApplicationThreadConstants.DEBUG_WAIT
6402                    : ApplicationThreadConstants.DEBUG_ON;
6403                app.debugging = true;
6404                if (mDebugTransient) {
6405                    mDebugApp = mOrigDebugApp;
6406                    mWaitForDebugger = mOrigWaitForDebugger;
6407                }
6408            }
6409            String profileFile = app.instrumentationProfileFile;
6410            ParcelFileDescriptor profileFd = null;
6411            int samplingInterval = 0;
6412            boolean profileAutoStop = false;
6413            if (mProfileApp != null && mProfileApp.equals(processName)) {
6414                mProfileProc = app;
6415                profileFile = mProfileFile;
6416                profileFd = mProfileFd;
6417                samplingInterval = mSamplingInterval;
6418                profileAutoStop = mAutoStopProfiler;
6419            }
6420            boolean enableTrackAllocation = false;
6421            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6422                enableTrackAllocation = true;
6423                mTrackAllocationApp = null;
6424            }
6425
6426            // If the app is being launched for restore or full backup, set it up specially
6427            boolean isRestrictedBackupMode = false;
6428            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6429                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6430                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6431                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6432                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6433            }
6434
6435            if (app.instrumentationClass != null) {
6436                notifyPackageUse(app.instrumentationClass.getPackageName(),
6437                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6438            }
6439            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6440                    + processName + " with config " + getGlobalConfiguration());
6441            ApplicationInfo appInfo = app.instrumentationInfo != null
6442                    ? app.instrumentationInfo : app.info;
6443            app.compat = compatibilityInfoForPackageLocked(appInfo);
6444            if (profileFd != null) {
6445                profileFd = profileFd.dup();
6446            }
6447            ProfilerInfo profilerInfo = profileFile == null ? null
6448                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6449
6450            // We deprecated Build.SERIAL and only apps that target pre NMR1
6451            // SDK can see it. Since access to the serial is now behind a
6452            // permission we push down the value.
6453            String buildSerial = Build.UNKNOWN;
6454            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6455                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6456                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6457                        .getSerial();
6458            }
6459
6460            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6461                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6462                    app.instrumentationUiAutomationConnection, testMode,
6463                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6464                    isRestrictedBackupMode || !normalMode, app.persistent,
6465                    new Configuration(getGlobalConfiguration()), app.compat,
6466                    getCommonServicesLocked(app.isolated),
6467                    mCoreSettingsObserver.getCoreSettingsLocked(),
6468                    buildSerial);
6469
6470            updateLruProcessLocked(app, false, null);
6471            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6472        } catch (Exception e) {
6473            // todo: Yikes!  What should we do?  For now we will try to
6474            // start another process, but that could easily get us in
6475            // an infinite loop of restarting processes...
6476            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6477
6478            app.resetPackageList(mProcessStats);
6479            app.unlinkDeathRecipient();
6480            startProcessLocked(app, "bind fail", processName);
6481            return false;
6482        }
6483
6484        // Remove this record from the list of starting applications.
6485        mPersistentStartingProcesses.remove(app);
6486        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6487                "Attach application locked removing on hold: " + app);
6488        mProcessesOnHold.remove(app);
6489
6490        boolean badApp = false;
6491        boolean didSomething = false;
6492
6493        // See if the top visible activity is waiting to run in this process...
6494        if (normalMode) {
6495            try {
6496                if (mStackSupervisor.attachApplicationLocked(app)) {
6497                    didSomething = true;
6498                }
6499            } catch (Exception e) {
6500                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6501                badApp = true;
6502            }
6503        }
6504
6505        // Find any services that should be running in this process...
6506        if (!badApp) {
6507            try {
6508                didSomething |= mServices.attachApplicationLocked(app, processName);
6509            } catch (Exception e) {
6510                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6511                badApp = true;
6512            }
6513        }
6514
6515        // Check if a next-broadcast receiver is in this process...
6516        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6517            try {
6518                didSomething |= sendPendingBroadcastsLocked(app);
6519            } catch (Exception e) {
6520                // If the app died trying to launch the receiver we declare it 'bad'
6521                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6522                badApp = true;
6523            }
6524        }
6525
6526        // Check whether the next backup agent is in this process...
6527        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6528            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6529                    "New app is backup target, launching agent for " + app);
6530            notifyPackageUse(mBackupTarget.appInfo.packageName,
6531                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6532            try {
6533                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6534                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6535                        mBackupTarget.backupMode);
6536            } catch (Exception e) {
6537                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6538                badApp = true;
6539            }
6540        }
6541
6542        if (badApp) {
6543            app.kill("error during init", true);
6544            handleAppDiedLocked(app, false, true);
6545            return false;
6546        }
6547
6548        if (!didSomething) {
6549            updateOomAdjLocked();
6550        }
6551
6552        return true;
6553    }
6554
6555    @Override
6556    public final void attachApplication(IApplicationThread thread) {
6557        synchronized (this) {
6558            int callingPid = Binder.getCallingPid();
6559            final long origId = Binder.clearCallingIdentity();
6560            attachApplicationLocked(thread, callingPid);
6561            Binder.restoreCallingIdentity(origId);
6562        }
6563    }
6564
6565    @Override
6566    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6567        final long origId = Binder.clearCallingIdentity();
6568        synchronized (this) {
6569            ActivityStack stack = ActivityRecord.getStackLocked(token);
6570            if (stack != null) {
6571                ActivityRecord r =
6572                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6573                if (stopProfiling) {
6574                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6575                        try {
6576                            mProfileFd.close();
6577                        } catch (IOException e) {
6578                        }
6579                        clearProfilerLocked();
6580                    }
6581                }
6582            }
6583        }
6584        Binder.restoreCallingIdentity(origId);
6585    }
6586
6587    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6588        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6589                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6590    }
6591
6592    void enableScreenAfterBoot() {
6593        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6594                SystemClock.uptimeMillis());
6595        mWindowManager.enableScreenAfterBoot();
6596
6597        synchronized (this) {
6598            updateEventDispatchingLocked();
6599        }
6600    }
6601
6602    @Override
6603    public void showBootMessage(final CharSequence msg, final boolean always) {
6604        if (Binder.getCallingUid() != Process.myUid()) {
6605            throw new SecurityException();
6606        }
6607        mWindowManager.showBootMessage(msg, always);
6608    }
6609
6610    @Override
6611    public void keyguardWaitingForActivityDrawn() {
6612        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6613        final long token = Binder.clearCallingIdentity();
6614        try {
6615            synchronized (this) {
6616                if (DEBUG_LOCKSCREEN) logLockScreen("");
6617                mWindowManager.keyguardWaitingForActivityDrawn();
6618                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6619                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6620                    updateSleepIfNeededLocked();
6621                }
6622            }
6623        } finally {
6624            Binder.restoreCallingIdentity(token);
6625        }
6626    }
6627
6628    @Override
6629    public void keyguardGoingAway(int flags) {
6630        enforceNotIsolatedCaller("keyguardGoingAway");
6631        final long token = Binder.clearCallingIdentity();
6632        try {
6633            synchronized (this) {
6634                if (DEBUG_LOCKSCREEN) logLockScreen("");
6635                mWindowManager.keyguardGoingAway(flags);
6636                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6637                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6638                    updateSleepIfNeededLocked();
6639
6640                    // Some stack visibility might change (e.g. docked stack)
6641                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6642                    applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(), true);
6643                }
6644            }
6645        } finally {
6646            Binder.restoreCallingIdentity(token);
6647        }
6648    }
6649
6650    final void finishBooting() {
6651        synchronized (this) {
6652            if (!mBootAnimationComplete) {
6653                mCallFinishBooting = true;
6654                return;
6655            }
6656            mCallFinishBooting = false;
6657        }
6658
6659        ArraySet<String> completedIsas = new ArraySet<String>();
6660        for (String abi : Build.SUPPORTED_ABIS) {
6661            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6662            final String instructionSet = VMRuntime.getInstructionSet(abi);
6663            if (!completedIsas.contains(instructionSet)) {
6664                try {
6665                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6666                } catch (InstallerException e) {
6667                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6668                            e.getMessage() +")");
6669                }
6670                completedIsas.add(instructionSet);
6671            }
6672        }
6673
6674        IntentFilter pkgFilter = new IntentFilter();
6675        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6676        pkgFilter.addDataScheme("package");
6677        mContext.registerReceiver(new BroadcastReceiver() {
6678            @Override
6679            public void onReceive(Context context, Intent intent) {
6680                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6681                if (pkgs != null) {
6682                    for (String pkg : pkgs) {
6683                        synchronized (ActivityManagerService.this) {
6684                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6685                                    0, "query restart")) {
6686                                setResultCode(Activity.RESULT_OK);
6687                                return;
6688                            }
6689                        }
6690                    }
6691                }
6692            }
6693        }, pkgFilter);
6694
6695        IntentFilter dumpheapFilter = new IntentFilter();
6696        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6697        mContext.registerReceiver(new BroadcastReceiver() {
6698            @Override
6699            public void onReceive(Context context, Intent intent) {
6700                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6701                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6702                } else {
6703                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6704                }
6705            }
6706        }, dumpheapFilter);
6707
6708        // Let system services know.
6709        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6710
6711        synchronized (this) {
6712            // Ensure that any processes we had put on hold are now started
6713            // up.
6714            final int NP = mProcessesOnHold.size();
6715            if (NP > 0) {
6716                ArrayList<ProcessRecord> procs =
6717                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6718                for (int ip=0; ip<NP; ip++) {
6719                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6720                            + procs.get(ip));
6721                    startProcessLocked(procs.get(ip), "on-hold", null);
6722                }
6723            }
6724
6725            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6726                // Start looking for apps that are abusing wake locks.
6727                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6729                // Tell anyone interested that we are done booting!
6730                SystemProperties.set("sys.boot_completed", "1");
6731
6732                // And trigger dev.bootcomplete if we are not showing encryption progress
6733                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6734                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6735                    SystemProperties.set("dev.bootcomplete", "1");
6736                }
6737                mUserController.sendBootCompletedLocked(
6738                        new IIntentReceiver.Stub() {
6739                            @Override
6740                            public void performReceive(Intent intent, int resultCode,
6741                                    String data, Bundle extras, boolean ordered,
6742                                    boolean sticky, int sendingUser) {
6743                                synchronized (ActivityManagerService.this) {
6744                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6745                                            true, false);
6746                                }
6747                            }
6748                        });
6749                scheduleStartProfilesLocked();
6750            }
6751        }
6752    }
6753
6754    @Override
6755    public void bootAnimationComplete() {
6756        final boolean callFinishBooting;
6757        synchronized (this) {
6758            callFinishBooting = mCallFinishBooting;
6759            mBootAnimationComplete = true;
6760        }
6761        if (callFinishBooting) {
6762            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6763            finishBooting();
6764            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6765        }
6766    }
6767
6768    final void ensureBootCompleted() {
6769        boolean booting;
6770        boolean enableScreen;
6771        synchronized (this) {
6772            booting = mBooting;
6773            mBooting = false;
6774            enableScreen = !mBooted;
6775            mBooted = true;
6776        }
6777
6778        if (booting) {
6779            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6780            finishBooting();
6781            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6782        }
6783
6784        if (enableScreen) {
6785            enableScreenAfterBoot();
6786        }
6787    }
6788
6789    @Override
6790    public final void activityResumed(IBinder token) {
6791        final long origId = Binder.clearCallingIdentity();
6792        synchronized(this) {
6793            ActivityRecord.activityResumedLocked(token);
6794        }
6795        Binder.restoreCallingIdentity(origId);
6796    }
6797
6798    @Override
6799    public final void activityPaused(IBinder token) {
6800        final long origId = Binder.clearCallingIdentity();
6801        synchronized(this) {
6802            ActivityStack stack = ActivityRecord.getStackLocked(token);
6803            if (stack != null) {
6804                stack.activityPausedLocked(token, false);
6805            }
6806        }
6807        Binder.restoreCallingIdentity(origId);
6808    }
6809
6810    @Override
6811    public final void activityStopped(IBinder token, Bundle icicle,
6812            PersistableBundle persistentState, CharSequence description) {
6813        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6814
6815        // Refuse possible leaked file descriptors
6816        if (icicle != null && icicle.hasFileDescriptors()) {
6817            throw new IllegalArgumentException("File descriptors passed in Bundle");
6818        }
6819
6820        final long origId = Binder.clearCallingIdentity();
6821
6822        synchronized (this) {
6823            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6824            if (r != null) {
6825                r.activityStoppedLocked(icicle, persistentState, description);
6826            }
6827        }
6828
6829        trimApplications();
6830
6831        Binder.restoreCallingIdentity(origId);
6832    }
6833
6834    @Override
6835    public final void activityDestroyed(IBinder token) {
6836        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6837        synchronized (this) {
6838            ActivityStack stack = ActivityRecord.getStackLocked(token);
6839            if (stack != null) {
6840                stack.activityDestroyedLocked(token, "activityDestroyed");
6841            }
6842        }
6843    }
6844
6845    @Override
6846    public final void activityRelaunched(IBinder token) {
6847        final long origId = Binder.clearCallingIdentity();
6848        synchronized (this) {
6849            mStackSupervisor.activityRelaunchedLocked(token);
6850        }
6851        Binder.restoreCallingIdentity(origId);
6852    }
6853
6854    @Override
6855    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6856            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6857        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6858                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6859        synchronized (this) {
6860            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6861            if (record == null) {
6862                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6863                        + "found for: " + token);
6864            }
6865            record.setSizeConfigurations(horizontalSizeConfiguration,
6866                    verticalSizeConfigurations, smallestSizeConfigurations);
6867        }
6868    }
6869
6870    @Override
6871    public final void backgroundResourcesReleased(IBinder token) {
6872        final long origId = Binder.clearCallingIdentity();
6873        try {
6874            synchronized (this) {
6875                ActivityStack stack = ActivityRecord.getStackLocked(token);
6876                if (stack != null) {
6877                    stack.backgroundResourcesReleased();
6878                }
6879            }
6880        } finally {
6881            Binder.restoreCallingIdentity(origId);
6882        }
6883    }
6884
6885    @Override
6886    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6887        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6888    }
6889
6890    @Override
6891    public final void notifyEnterAnimationComplete(IBinder token) {
6892        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6893    }
6894
6895    @Override
6896    public String getCallingPackage(IBinder token) {
6897        synchronized (this) {
6898            ActivityRecord r = getCallingRecordLocked(token);
6899            return r != null ? r.info.packageName : null;
6900        }
6901    }
6902
6903    @Override
6904    public ComponentName getCallingActivity(IBinder token) {
6905        synchronized (this) {
6906            ActivityRecord r = getCallingRecordLocked(token);
6907            return r != null ? r.intent.getComponent() : null;
6908        }
6909    }
6910
6911    private ActivityRecord getCallingRecordLocked(IBinder token) {
6912        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6913        if (r == null) {
6914            return null;
6915        }
6916        return r.resultTo;
6917    }
6918
6919    @Override
6920    public ComponentName getActivityClassForToken(IBinder token) {
6921        synchronized(this) {
6922            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6923            if (r == null) {
6924                return null;
6925            }
6926            return r.intent.getComponent();
6927        }
6928    }
6929
6930    @Override
6931    public String getPackageForToken(IBinder token) {
6932        synchronized(this) {
6933            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6934            if (r == null) {
6935                return null;
6936            }
6937            return r.packageName;
6938        }
6939    }
6940
6941    @Override
6942    public boolean isRootVoiceInteraction(IBinder token) {
6943        synchronized(this) {
6944            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6945            if (r == null) {
6946                return false;
6947            }
6948            return r.rootVoiceInteraction;
6949        }
6950    }
6951
6952    @Override
6953    public IIntentSender getIntentSender(int type,
6954            String packageName, IBinder token, String resultWho,
6955            int requestCode, Intent[] intents, String[] resolvedTypes,
6956            int flags, Bundle bOptions, int userId) {
6957        enforceNotIsolatedCaller("getIntentSender");
6958        // Refuse possible leaked file descriptors
6959        if (intents != null) {
6960            if (intents.length < 1) {
6961                throw new IllegalArgumentException("Intents array length must be >= 1");
6962            }
6963            for (int i=0; i<intents.length; i++) {
6964                Intent intent = intents[i];
6965                if (intent != null) {
6966                    if (intent.hasFileDescriptors()) {
6967                        throw new IllegalArgumentException("File descriptors passed in Intent");
6968                    }
6969                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6970                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6971                        throw new IllegalArgumentException(
6972                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6973                    }
6974                    intents[i] = new Intent(intent);
6975                }
6976            }
6977            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6978                throw new IllegalArgumentException(
6979                        "Intent array length does not match resolvedTypes length");
6980            }
6981        }
6982        if (bOptions != null) {
6983            if (bOptions.hasFileDescriptors()) {
6984                throw new IllegalArgumentException("File descriptors passed in options");
6985            }
6986        }
6987
6988        synchronized(this) {
6989            int callingUid = Binder.getCallingUid();
6990            int origUserId = userId;
6991            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6992                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6993                    ALLOW_NON_FULL, "getIntentSender", null);
6994            if (origUserId == UserHandle.USER_CURRENT) {
6995                // We don't want to evaluate this until the pending intent is
6996                // actually executed.  However, we do want to always do the
6997                // security checking for it above.
6998                userId = UserHandle.USER_CURRENT;
6999            }
7000            try {
7001                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7002                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7003                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7004                    if (!UserHandle.isSameApp(callingUid, uid)) {
7005                        String msg = "Permission Denial: getIntentSender() from pid="
7006                            + Binder.getCallingPid()
7007                            + ", uid=" + Binder.getCallingUid()
7008                            + ", (need uid=" + uid + ")"
7009                            + " is not allowed to send as package " + packageName;
7010                        Slog.w(TAG, msg);
7011                        throw new SecurityException(msg);
7012                    }
7013                }
7014
7015                return getIntentSenderLocked(type, packageName, callingUid, userId,
7016                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7017
7018            } catch (RemoteException e) {
7019                throw new SecurityException(e);
7020            }
7021        }
7022    }
7023
7024    IIntentSender getIntentSenderLocked(int type, String packageName,
7025            int callingUid, int userId, IBinder token, String resultWho,
7026            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7027            Bundle bOptions) {
7028        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7029        ActivityRecord activity = null;
7030        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7031            activity = ActivityRecord.isInStackLocked(token);
7032            if (activity == null) {
7033                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7034                return null;
7035            }
7036            if (activity.finishing) {
7037                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7038                return null;
7039            }
7040        }
7041
7042        // We're going to be splicing together extras before sending, so we're
7043        // okay poking into any contained extras.
7044        if (intents != null) {
7045            for (int i = 0; i < intents.length; i++) {
7046                intents[i].setDefusable(true);
7047            }
7048        }
7049        Bundle.setDefusable(bOptions, true);
7050
7051        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7052        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7053        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7054        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7055                |PendingIntent.FLAG_UPDATE_CURRENT);
7056
7057        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7058                type, packageName, activity, resultWho,
7059                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7060        WeakReference<PendingIntentRecord> ref;
7061        ref = mIntentSenderRecords.get(key);
7062        PendingIntentRecord rec = ref != null ? ref.get() : null;
7063        if (rec != null) {
7064            if (!cancelCurrent) {
7065                if (updateCurrent) {
7066                    if (rec.key.requestIntent != null) {
7067                        rec.key.requestIntent.replaceExtras(intents != null ?
7068                                intents[intents.length - 1] : null);
7069                    }
7070                    if (intents != null) {
7071                        intents[intents.length-1] = rec.key.requestIntent;
7072                        rec.key.allIntents = intents;
7073                        rec.key.allResolvedTypes = resolvedTypes;
7074                    } else {
7075                        rec.key.allIntents = null;
7076                        rec.key.allResolvedTypes = null;
7077                    }
7078                }
7079                return rec;
7080            }
7081            rec.canceled = true;
7082            mIntentSenderRecords.remove(key);
7083        }
7084        if (noCreate) {
7085            return rec;
7086        }
7087        rec = new PendingIntentRecord(this, key, callingUid);
7088        mIntentSenderRecords.put(key, rec.ref);
7089        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7090            if (activity.pendingResults == null) {
7091                activity.pendingResults
7092                        = new HashSet<WeakReference<PendingIntentRecord>>();
7093            }
7094            activity.pendingResults.add(rec.ref);
7095        }
7096        return rec;
7097    }
7098
7099    @Override
7100    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7101            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7102        if (target instanceof PendingIntentRecord) {
7103            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7104                    finishedReceiver, requiredPermission, options);
7105        } else {
7106            if (intent == null) {
7107                // Weird case: someone has given us their own custom IIntentSender, and now
7108                // they have someone else trying to send to it but of course this isn't
7109                // really a PendingIntent, so there is no base Intent, and the caller isn't
7110                // supplying an Intent... but we never want to dispatch a null Intent to
7111                // a receiver, so um...  let's make something up.
7112                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7113                intent = new Intent(Intent.ACTION_MAIN);
7114            }
7115            try {
7116                target.send(code, intent, resolvedType, null, requiredPermission, options);
7117            } catch (RemoteException e) {
7118            }
7119            // Platform code can rely on getting a result back when the send is done, but if
7120            // this intent sender is from outside of the system we can't rely on it doing that.
7121            // So instead we don't give it the result receiver, and instead just directly
7122            // report the finish immediately.
7123            if (finishedReceiver != null) {
7124                try {
7125                    finishedReceiver.performReceive(intent, 0,
7126                            null, null, false, false, UserHandle.getCallingUserId());
7127                } catch (RemoteException e) {
7128                }
7129            }
7130            return 0;
7131        }
7132    }
7133
7134    /**
7135     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7136     *
7137     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7138     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7139     */
7140    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7141        if (DEBUG_WHITELISTS) {
7142            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7143                    + targetUid + ", " + duration + ")");
7144        }
7145        synchronized (mPidsSelfLocked) {
7146            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7147            if (pr == null) {
7148                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7149                return;
7150            }
7151            if (!pr.whitelistManager) {
7152                if (DEBUG_WHITELISTS) {
7153                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7154                            + callerPid + " is not allowed");
7155                }
7156                return;
7157            }
7158        }
7159
7160        final long token = Binder.clearCallingIdentity();
7161        try {
7162            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7163                    true, "pe from uid:" + callerUid);
7164        } finally {
7165            Binder.restoreCallingIdentity(token);
7166        }
7167    }
7168
7169    @Override
7170    public void cancelIntentSender(IIntentSender sender) {
7171        if (!(sender instanceof PendingIntentRecord)) {
7172            return;
7173        }
7174        synchronized(this) {
7175            PendingIntentRecord rec = (PendingIntentRecord)sender;
7176            try {
7177                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7178                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7179                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7180                    String msg = "Permission Denial: cancelIntentSender() from pid="
7181                        + Binder.getCallingPid()
7182                        + ", uid=" + Binder.getCallingUid()
7183                        + " is not allowed to cancel packges "
7184                        + rec.key.packageName;
7185                    Slog.w(TAG, msg);
7186                    throw new SecurityException(msg);
7187                }
7188            } catch (RemoteException e) {
7189                throw new SecurityException(e);
7190            }
7191            cancelIntentSenderLocked(rec, true);
7192        }
7193    }
7194
7195    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7196        rec.canceled = true;
7197        mIntentSenderRecords.remove(rec.key);
7198        if (cleanActivity && rec.key.activity != null) {
7199            rec.key.activity.pendingResults.remove(rec.ref);
7200        }
7201    }
7202
7203    @Override
7204    public String getPackageForIntentSender(IIntentSender pendingResult) {
7205        if (!(pendingResult instanceof PendingIntentRecord)) {
7206            return null;
7207        }
7208        try {
7209            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7210            return res.key.packageName;
7211        } catch (ClassCastException e) {
7212        }
7213        return null;
7214    }
7215
7216    @Override
7217    public int getUidForIntentSender(IIntentSender sender) {
7218        if (sender instanceof PendingIntentRecord) {
7219            try {
7220                PendingIntentRecord res = (PendingIntentRecord)sender;
7221                return res.uid;
7222            } catch (ClassCastException e) {
7223            }
7224        }
7225        return -1;
7226    }
7227
7228    @Override
7229    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7230        if (!(pendingResult instanceof PendingIntentRecord)) {
7231            return false;
7232        }
7233        try {
7234            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7235            if (res.key.allIntents == null) {
7236                return false;
7237            }
7238            for (int i=0; i<res.key.allIntents.length; i++) {
7239                Intent intent = res.key.allIntents[i];
7240                if (intent.getPackage() != null && intent.getComponent() != null) {
7241                    return false;
7242                }
7243            }
7244            return true;
7245        } catch (ClassCastException e) {
7246        }
7247        return false;
7248    }
7249
7250    @Override
7251    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7252        if (!(pendingResult instanceof PendingIntentRecord)) {
7253            return false;
7254        }
7255        try {
7256            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7257            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7258                return true;
7259            }
7260            return false;
7261        } catch (ClassCastException e) {
7262        }
7263        return false;
7264    }
7265
7266    @Override
7267    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7268        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7269                "getIntentForIntentSender()");
7270        if (!(pendingResult instanceof PendingIntentRecord)) {
7271            return null;
7272        }
7273        try {
7274            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7275            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7276        } catch (ClassCastException e) {
7277        }
7278        return null;
7279    }
7280
7281    @Override
7282    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7283        if (!(pendingResult instanceof PendingIntentRecord)) {
7284            return null;
7285        }
7286        try {
7287            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7288            synchronized (this) {
7289                return getTagForIntentSenderLocked(res, prefix);
7290            }
7291        } catch (ClassCastException e) {
7292        }
7293        return null;
7294    }
7295
7296    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7297        final Intent intent = res.key.requestIntent;
7298        if (intent != null) {
7299            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7300                    || res.lastTagPrefix.equals(prefix))) {
7301                return res.lastTag;
7302            }
7303            res.lastTagPrefix = prefix;
7304            final StringBuilder sb = new StringBuilder(128);
7305            if (prefix != null) {
7306                sb.append(prefix);
7307            }
7308            if (intent.getAction() != null) {
7309                sb.append(intent.getAction());
7310            } else if (intent.getComponent() != null) {
7311                intent.getComponent().appendShortString(sb);
7312            } else {
7313                sb.append("?");
7314            }
7315            return res.lastTag = sb.toString();
7316        }
7317        return null;
7318    }
7319
7320    @Override
7321    public void setProcessLimit(int max) {
7322        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7323                "setProcessLimit()");
7324        synchronized (this) {
7325            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7326            mProcessLimitOverride = max;
7327        }
7328        trimApplications();
7329    }
7330
7331    @Override
7332    public int getProcessLimit() {
7333        synchronized (this) {
7334            return mProcessLimitOverride;
7335        }
7336    }
7337
7338    void foregroundTokenDied(ForegroundToken token) {
7339        synchronized (ActivityManagerService.this) {
7340            synchronized (mPidsSelfLocked) {
7341                ForegroundToken cur
7342                    = mForegroundProcesses.get(token.pid);
7343                if (cur != token) {
7344                    return;
7345                }
7346                mForegroundProcesses.remove(token.pid);
7347                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7348                if (pr == null) {
7349                    return;
7350                }
7351                pr.forcingToForeground = null;
7352                updateProcessForegroundLocked(pr, false, false);
7353            }
7354            updateOomAdjLocked();
7355        }
7356    }
7357
7358    @Override
7359    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7360        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7361                "setProcessForeground()");
7362        synchronized(this) {
7363            boolean changed = false;
7364
7365            synchronized (mPidsSelfLocked) {
7366                ProcessRecord pr = mPidsSelfLocked.get(pid);
7367                if (pr == null && isForeground) {
7368                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7369                    return;
7370                }
7371                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7372                if (oldToken != null) {
7373                    oldToken.token.unlinkToDeath(oldToken, 0);
7374                    mForegroundProcesses.remove(pid);
7375                    if (pr != null) {
7376                        pr.forcingToForeground = null;
7377                    }
7378                    changed = true;
7379                }
7380                if (isForeground && token != null) {
7381                    ForegroundToken newToken = new ForegroundToken() {
7382                        @Override
7383                        public void binderDied() {
7384                            foregroundTokenDied(this);
7385                        }
7386                    };
7387                    newToken.pid = pid;
7388                    newToken.token = token;
7389                    try {
7390                        token.linkToDeath(newToken, 0);
7391                        mForegroundProcesses.put(pid, newToken);
7392                        pr.forcingToForeground = token;
7393                        changed = true;
7394                    } catch (RemoteException e) {
7395                        // If the process died while doing this, we will later
7396                        // do the cleanup with the process death link.
7397                    }
7398                }
7399            }
7400
7401            if (changed) {
7402                updateOomAdjLocked();
7403            }
7404        }
7405    }
7406
7407    @Override
7408    public boolean isAppForeground(int uid) throws RemoteException {
7409        synchronized (this) {
7410            UidRecord uidRec = mActiveUids.get(uid);
7411            if (uidRec == null || uidRec.idle) {
7412                return false;
7413            }
7414            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7415        }
7416    }
7417
7418    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7419    // be guarded by permission checking.
7420    int getUidState(int uid) {
7421        synchronized (this) {
7422            UidRecord uidRec = mActiveUids.get(uid);
7423            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7424        }
7425    }
7426
7427    @Override
7428    public boolean isInMultiWindowMode(IBinder token) {
7429        final long origId = Binder.clearCallingIdentity();
7430        try {
7431            synchronized(this) {
7432                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7433                if (r == null) {
7434                    return false;
7435                }
7436                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7437                return !r.task.mFullscreen;
7438            }
7439        } finally {
7440            Binder.restoreCallingIdentity(origId);
7441        }
7442    }
7443
7444    @Override
7445    public boolean isInPictureInPictureMode(IBinder token) {
7446        final long origId = Binder.clearCallingIdentity();
7447        try {
7448            synchronized(this) {
7449                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7450                if (stack == null) {
7451                    return false;
7452                }
7453                return stack.mStackId == PINNED_STACK_ID;
7454            }
7455        } finally {
7456            Binder.restoreCallingIdentity(origId);
7457        }
7458    }
7459
7460    @Override
7461    public void enterPictureInPictureMode(IBinder token) {
7462        final long origId = Binder.clearCallingIdentity();
7463        try {
7464            synchronized(this) {
7465                if (!mSupportsPictureInPicture) {
7466                    throw new IllegalStateException("enterPictureInPictureMode: "
7467                            + "Device doesn't support picture-in-picture mode.");
7468                }
7469
7470                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7471
7472                if (r == null) {
7473                    throw new IllegalStateException("enterPictureInPictureMode: "
7474                            + "Can't find activity for token=" + token);
7475                }
7476
7477                if (!r.supportsPictureInPicture()) {
7478                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7479                            + "Picture-In-Picture not supported for r=" + r);
7480                }
7481
7482                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7483                // current bounds.
7484                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7485                final Rect bounds = (pinnedStack != null)
7486                        ? pinnedStack.mBounds : getDefaultPictureInPictureBounds(DEFAULT_DISPLAY);
7487
7488                mStackSupervisor.moveActivityToPinnedStackLocked(
7489                        r, "enterPictureInPictureMode", bounds);
7490            }
7491        } finally {
7492            Binder.restoreCallingIdentity(origId);
7493        }
7494    }
7495
7496    @Override
7497    public Rect getDefaultPictureInPictureBounds(int displayId) {
7498        final long origId = Binder.clearCallingIdentity();
7499        final Rect defaultBounds = new Rect();
7500        try {
7501            synchronized(this) {
7502                if (!mSupportsPictureInPicture) {
7503                    return new Rect();
7504                }
7505
7506                // Convert the sizes to for the current display state
7507                final DisplayMetrics dm = mStackSupervisor.getDisplayRealMetrics(displayId);
7508                final int stackWidth = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7509                        mDefaultPinnedStackSizeDp.getWidth(), dm);
7510                final int stackHeight = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7511                        mDefaultPinnedStackSizeDp.getHeight(), dm);
7512                final Rect maxBounds = new Rect();
7513                getPictureInPictureBounds(displayId, maxBounds);
7514                Gravity.apply(mDefaultPinnedStackGravity, stackWidth, stackHeight,
7515                        maxBounds, 0, 0, defaultBounds);
7516            }
7517        } finally {
7518            Binder.restoreCallingIdentity(origId);
7519        }
7520        return defaultBounds;
7521    }
7522
7523    @Override
7524    public Rect getPictureInPictureMovementBounds(int displayId) {
7525        final long origId = Binder.clearCallingIdentity();
7526        final Rect maxBounds = new Rect();
7527        try {
7528            synchronized(this) {
7529                if (!mSupportsPictureInPicture) {
7530                    return new Rect();
7531                }
7532
7533                getPictureInPictureBounds(displayId, maxBounds);
7534
7535                // Adjust the max bounds by the current stack dimensions
7536                final StackInfo pinnedStackInfo = mStackSupervisor.getStackInfoLocked(
7537                        PINNED_STACK_ID);
7538                if (pinnedStackInfo != null) {
7539                    maxBounds.right = Math.max(maxBounds.left, maxBounds.right -
7540                            pinnedStackInfo.bounds.width());
7541                    maxBounds.bottom = Math.max(maxBounds.top, maxBounds.bottom -
7542                            pinnedStackInfo.bounds.height());
7543                }
7544            }
7545        } finally {
7546            Binder.restoreCallingIdentity(origId);
7547        }
7548        return maxBounds;
7549    }
7550
7551    /**
7552     * Calculate the bounds where the pinned stack can move in the current display state.
7553     */
7554    private void getPictureInPictureBounds(int displayId, Rect outRect) {
7555        // Convert the insets to for the current display state
7556        final DisplayMetrics dm = mStackSupervisor.getDisplayRealMetrics(displayId);
7557        final int insetsLR = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7558                mDefaultPinnedStackScreenEdgeInsetsDp.getWidth(), dm);
7559        final int insetsTB = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7560                mDefaultPinnedStackScreenEdgeInsetsDp.getHeight(), dm);
7561        try {
7562            final Point displaySize = mStackSupervisor.getDisplayRealSize(displayId);
7563            final Rect insets = new Rect();
7564            mWindowManager.getStableInsets(displayId, insets);
7565
7566            // Calculate the insets from the system decorations and apply the gravity
7567            outRect.set(insets.left + insetsLR, insets.top + insetsTB,
7568                    displaySize.x - insets.right - insetsLR,
7569                    displaySize.y - insets.bottom - insetsTB);
7570        } catch (RemoteException e) {
7571            Log.e(TAG, "Failed to calculate PIP movement bounds", e);
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                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8611                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8612            }
8613        }
8614    }
8615
8616    private void schedulePersistUriGrants() {
8617        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8618            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8619                    10 * DateUtils.SECOND_IN_MILLIS);
8620        }
8621    }
8622
8623    private void writeGrantedUriPermissions() {
8624        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8625
8626        // Snapshot permissions so we can persist without lock
8627        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8628        synchronized (this) {
8629            final int size = mGrantedUriPermissions.size();
8630            for (int i = 0; i < size; i++) {
8631                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8632                for (UriPermission perm : perms.values()) {
8633                    if (perm.persistedModeFlags != 0) {
8634                        persist.add(perm.snapshot());
8635                    }
8636                }
8637            }
8638        }
8639
8640        FileOutputStream fos = null;
8641        try {
8642            fos = mGrantFile.startWrite();
8643
8644            XmlSerializer out = new FastXmlSerializer();
8645            out.setOutput(fos, StandardCharsets.UTF_8.name());
8646            out.startDocument(null, true);
8647            out.startTag(null, TAG_URI_GRANTS);
8648            for (UriPermission.Snapshot perm : persist) {
8649                out.startTag(null, TAG_URI_GRANT);
8650                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8651                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8652                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8653                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8654                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8655                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8656                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8657                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8658                out.endTag(null, TAG_URI_GRANT);
8659            }
8660            out.endTag(null, TAG_URI_GRANTS);
8661            out.endDocument();
8662
8663            mGrantFile.finishWrite(fos);
8664        } catch (IOException e) {
8665            if (fos != null) {
8666                mGrantFile.failWrite(fos);
8667            }
8668        }
8669    }
8670
8671    private void readGrantedUriPermissionsLocked() {
8672        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8673
8674        final long now = System.currentTimeMillis();
8675
8676        FileInputStream fis = null;
8677        try {
8678            fis = mGrantFile.openRead();
8679            final XmlPullParser in = Xml.newPullParser();
8680            in.setInput(fis, StandardCharsets.UTF_8.name());
8681
8682            int type;
8683            while ((type = in.next()) != END_DOCUMENT) {
8684                final String tag = in.getName();
8685                if (type == START_TAG) {
8686                    if (TAG_URI_GRANT.equals(tag)) {
8687                        final int sourceUserId;
8688                        final int targetUserId;
8689                        final int userHandle = readIntAttribute(in,
8690                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8691                        if (userHandle != UserHandle.USER_NULL) {
8692                            // For backwards compatibility.
8693                            sourceUserId = userHandle;
8694                            targetUserId = userHandle;
8695                        } else {
8696                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8697                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8698                        }
8699                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8700                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8701                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8702                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8703                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8704                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8705
8706                        // Sanity check that provider still belongs to source package
8707                        // Both direct boot aware and unaware packages are fine as we
8708                        // will do filtering at query time to avoid multiple parsing.
8709                        final ProviderInfo pi = getProviderInfoLocked(
8710                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8711                                        | MATCH_DIRECT_BOOT_UNAWARE);
8712                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8713                            int targetUid = -1;
8714                            try {
8715                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8716                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8717                            } catch (RemoteException e) {
8718                            }
8719                            if (targetUid != -1) {
8720                                final UriPermission perm = findOrCreateUriPermissionLocked(
8721                                        sourcePkg, targetPkg, targetUid,
8722                                        new GrantUri(sourceUserId, uri, prefix));
8723                                perm.initPersistedModes(modeFlags, createdTime);
8724                            }
8725                        } else {
8726                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8727                                    + " but instead found " + pi);
8728                        }
8729                    }
8730                }
8731            }
8732        } catch (FileNotFoundException e) {
8733            // Missing grants is okay
8734        } catch (IOException e) {
8735            Slog.wtf(TAG, "Failed reading Uri grants", e);
8736        } catch (XmlPullParserException e) {
8737            Slog.wtf(TAG, "Failed reading Uri grants", e);
8738        } finally {
8739            IoUtils.closeQuietly(fis);
8740        }
8741    }
8742
8743    /**
8744     * @param uri This uri must NOT contain an embedded userId.
8745     * @param userId The userId in which the uri is to be resolved.
8746     */
8747    @Override
8748    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8749        enforceNotIsolatedCaller("takePersistableUriPermission");
8750
8751        Preconditions.checkFlagsArgument(modeFlags,
8752                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8753
8754        synchronized (this) {
8755            final int callingUid = Binder.getCallingUid();
8756            boolean persistChanged = false;
8757            GrantUri grantUri = new GrantUri(userId, uri, false);
8758
8759            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8760                    new GrantUri(userId, uri, false));
8761            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8762                    new GrantUri(userId, uri, true));
8763
8764            final boolean exactValid = (exactPerm != null)
8765                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8766            final boolean prefixValid = (prefixPerm != null)
8767                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8768
8769            if (!(exactValid || prefixValid)) {
8770                throw new SecurityException("No persistable permission grants found for UID "
8771                        + callingUid + " and Uri " + grantUri.toSafeString());
8772            }
8773
8774            if (exactValid) {
8775                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8776            }
8777            if (prefixValid) {
8778                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8779            }
8780
8781            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8782
8783            if (persistChanged) {
8784                schedulePersistUriGrants();
8785            }
8786        }
8787    }
8788
8789    /**
8790     * @param uri This uri must NOT contain an embedded userId.
8791     * @param userId The userId in which the uri is to be resolved.
8792     */
8793    @Override
8794    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8795        enforceNotIsolatedCaller("releasePersistableUriPermission");
8796
8797        Preconditions.checkFlagsArgument(modeFlags,
8798                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8799
8800        synchronized (this) {
8801            final int callingUid = Binder.getCallingUid();
8802            boolean persistChanged = false;
8803
8804            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8805                    new GrantUri(userId, uri, false));
8806            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8807                    new GrantUri(userId, uri, true));
8808            if (exactPerm == null && prefixPerm == null) {
8809                throw new SecurityException("No permission grants found for UID " + callingUid
8810                        + " and Uri " + uri.toSafeString());
8811            }
8812
8813            if (exactPerm != null) {
8814                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8815                removeUriPermissionIfNeededLocked(exactPerm);
8816            }
8817            if (prefixPerm != null) {
8818                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8819                removeUriPermissionIfNeededLocked(prefixPerm);
8820            }
8821
8822            if (persistChanged) {
8823                schedulePersistUriGrants();
8824            }
8825        }
8826    }
8827
8828    /**
8829     * Prune any older {@link UriPermission} for the given UID until outstanding
8830     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8831     *
8832     * @return if any mutations occured that require persisting.
8833     */
8834    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8835        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8836        if (perms == null) return false;
8837        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8838
8839        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8840        for (UriPermission perm : perms.values()) {
8841            if (perm.persistedModeFlags != 0) {
8842                persisted.add(perm);
8843            }
8844        }
8845
8846        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8847        if (trimCount <= 0) return false;
8848
8849        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8850        for (int i = 0; i < trimCount; i++) {
8851            final UriPermission perm = persisted.get(i);
8852
8853            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8854                    "Trimming grant created at " + perm.persistedCreateTime);
8855
8856            perm.releasePersistableModes(~0);
8857            removeUriPermissionIfNeededLocked(perm);
8858        }
8859
8860        return true;
8861    }
8862
8863    @Override
8864    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8865            String packageName, boolean incoming) {
8866        enforceNotIsolatedCaller("getPersistedUriPermissions");
8867        Preconditions.checkNotNull(packageName, "packageName");
8868
8869        final int callingUid = Binder.getCallingUid();
8870        final int callingUserId = UserHandle.getUserId(callingUid);
8871        final IPackageManager pm = AppGlobals.getPackageManager();
8872        try {
8873            final int packageUid = pm.getPackageUid(packageName,
8874                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8875            if (packageUid != callingUid) {
8876                throw new SecurityException(
8877                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8878            }
8879        } catch (RemoteException e) {
8880            throw new SecurityException("Failed to verify package name ownership");
8881        }
8882
8883        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8884        synchronized (this) {
8885            if (incoming) {
8886                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8887                        callingUid);
8888                if (perms == null) {
8889                    Slog.w(TAG, "No permission grants found for " + packageName);
8890                } else {
8891                    for (UriPermission perm : perms.values()) {
8892                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8893                            result.add(perm.buildPersistedPublicApiObject());
8894                        }
8895                    }
8896                }
8897            } else {
8898                final int size = mGrantedUriPermissions.size();
8899                for (int i = 0; i < size; i++) {
8900                    final ArrayMap<GrantUri, UriPermission> perms =
8901                            mGrantedUriPermissions.valueAt(i);
8902                    for (UriPermission perm : perms.values()) {
8903                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8904                            result.add(perm.buildPersistedPublicApiObject());
8905                        }
8906                    }
8907                }
8908            }
8909        }
8910        return new ParceledListSlice<android.content.UriPermission>(result);
8911    }
8912
8913    @Override
8914    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8915            String packageName, int userId) {
8916        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8917                "getGrantedUriPermissions");
8918
8919        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8920        synchronized (this) {
8921            final int size = mGrantedUriPermissions.size();
8922            for (int i = 0; i < size; i++) {
8923                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8924                for (UriPermission perm : perms.values()) {
8925                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8926                            && perm.persistedModeFlags != 0) {
8927                        result.add(perm.buildPersistedPublicApiObject());
8928                    }
8929                }
8930            }
8931        }
8932        return new ParceledListSlice<android.content.UriPermission>(result);
8933    }
8934
8935    @Override
8936    public void clearGrantedUriPermissions(String packageName, int userId) {
8937        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8938                "clearGrantedUriPermissions");
8939        removeUriPermissionsForPackageLocked(packageName, userId, true);
8940    }
8941
8942    @Override
8943    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8944        synchronized (this) {
8945            ProcessRecord app =
8946                who != null ? getRecordForAppLocked(who) : null;
8947            if (app == null) return;
8948
8949            Message msg = Message.obtain();
8950            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8951            msg.obj = app;
8952            msg.arg1 = waiting ? 1 : 0;
8953            mUiHandler.sendMessage(msg);
8954        }
8955    }
8956
8957    @Override
8958    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8959        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8960        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8961        outInfo.availMem = Process.getFreeMemory();
8962        outInfo.totalMem = Process.getTotalMemory();
8963        outInfo.threshold = homeAppMem;
8964        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8965        outInfo.hiddenAppThreshold = cachedAppMem;
8966        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8967                ProcessList.SERVICE_ADJ);
8968        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8969                ProcessList.VISIBLE_APP_ADJ);
8970        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8971                ProcessList.FOREGROUND_APP_ADJ);
8972    }
8973
8974    // =========================================================
8975    // TASK MANAGEMENT
8976    // =========================================================
8977
8978    @Override
8979    public List<IAppTask> getAppTasks(String callingPackage) {
8980        int callingUid = Binder.getCallingUid();
8981        long ident = Binder.clearCallingIdentity();
8982
8983        synchronized(this) {
8984            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8985            try {
8986                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8987
8988                final int N = mRecentTasks.size();
8989                for (int i = 0; i < N; i++) {
8990                    TaskRecord tr = mRecentTasks.get(i);
8991                    // Skip tasks that do not match the caller.  We don't need to verify
8992                    // callingPackage, because we are also limiting to callingUid and know
8993                    // that will limit to the correct security sandbox.
8994                    if (tr.effectiveUid != callingUid) {
8995                        continue;
8996                    }
8997                    Intent intent = tr.getBaseIntent();
8998                    if (intent == null ||
8999                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9000                        continue;
9001                    }
9002                    ActivityManager.RecentTaskInfo taskInfo =
9003                            createRecentTaskInfoFromTaskRecord(tr);
9004                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9005                    list.add(taskImpl);
9006                }
9007            } finally {
9008                Binder.restoreCallingIdentity(ident);
9009            }
9010            return list;
9011        }
9012    }
9013
9014    @Override
9015    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9016        final int callingUid = Binder.getCallingUid();
9017        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9018
9019        synchronized(this) {
9020            if (DEBUG_ALL) Slog.v(
9021                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9022
9023            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9024                    callingUid);
9025
9026            // TODO: Improve with MRU list from all ActivityStacks.
9027            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9028        }
9029
9030        return list;
9031    }
9032
9033    /**
9034     * Creates a new RecentTaskInfo from a TaskRecord.
9035     */
9036    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9037        // Update the task description to reflect any changes in the task stack
9038        tr.updateTaskDescription();
9039
9040        // Compose the recent task info
9041        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9042        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9043        rti.persistentId = tr.taskId;
9044        rti.baseIntent = new Intent(tr.getBaseIntent());
9045        rti.origActivity = tr.origActivity;
9046        rti.realActivity = tr.realActivity;
9047        rti.description = tr.lastDescription;
9048        rti.stackId = tr.getStackId();
9049        rti.userId = tr.userId;
9050        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9051        rti.firstActiveTime = tr.firstActiveTime;
9052        rti.lastActiveTime = tr.lastActiveTime;
9053        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9054        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9055        rti.numActivities = 0;
9056        if (tr.mBounds != null) {
9057            rti.bounds = new Rect(tr.mBounds);
9058        }
9059        rti.isDockable = tr.canGoInDockedStack();
9060        rti.resizeMode = tr.mResizeMode;
9061
9062        ActivityRecord base = null;
9063        ActivityRecord top = null;
9064        ActivityRecord tmp;
9065
9066        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9067            tmp = tr.mActivities.get(i);
9068            if (tmp.finishing) {
9069                continue;
9070            }
9071            base = tmp;
9072            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9073                top = base;
9074            }
9075            rti.numActivities++;
9076        }
9077
9078        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9079        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9080
9081        return rti;
9082    }
9083
9084    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9085        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9086                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9087        if (!allowed) {
9088            if (checkPermission(android.Manifest.permission.GET_TASKS,
9089                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9090                // Temporary compatibility: some existing apps on the system image may
9091                // still be requesting the old permission and not switched to the new
9092                // one; if so, we'll still allow them full access.  This means we need
9093                // to see if they are holding the old permission and are a system app.
9094                try {
9095                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9096                        allowed = true;
9097                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9098                                + " is using old GET_TASKS but privileged; allowing");
9099                    }
9100                } catch (RemoteException e) {
9101                }
9102            }
9103        }
9104        if (!allowed) {
9105            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9106                    + " does not hold REAL_GET_TASKS; limiting output");
9107        }
9108        return allowed;
9109    }
9110
9111    @Override
9112    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9113            int userId) {
9114        final int callingUid = Binder.getCallingUid();
9115        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9116                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9117
9118        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9119        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9120        synchronized (this) {
9121            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9122                    callingUid);
9123            final boolean detailed = checkCallingPermission(
9124                    android.Manifest.permission.GET_DETAILED_TASKS)
9125                    == PackageManager.PERMISSION_GRANTED;
9126
9127            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9128                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9129                return ParceledListSlice.emptyList();
9130            }
9131            mRecentTasks.loadUserRecentsLocked(userId);
9132
9133            final int recentsCount = mRecentTasks.size();
9134            ArrayList<ActivityManager.RecentTaskInfo> res =
9135                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9136
9137            final Set<Integer> includedUsers;
9138            if (includeProfiles) {
9139                includedUsers = mUserController.getProfileIds(userId);
9140            } else {
9141                includedUsers = new HashSet<>();
9142            }
9143            includedUsers.add(Integer.valueOf(userId));
9144
9145            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9146                TaskRecord tr = mRecentTasks.get(i);
9147                // Only add calling user or related users recent tasks
9148                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9149                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9150                    continue;
9151                }
9152
9153                if (tr.realActivitySuspended) {
9154                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9155                    continue;
9156                }
9157
9158                // Return the entry if desired by the caller.  We always return
9159                // the first entry, because callers always expect this to be the
9160                // foreground app.  We may filter others if the caller has
9161                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9162                // we should exclude the entry.
9163
9164                if (i == 0
9165                        || withExcluded
9166                        || (tr.intent == null)
9167                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9168                                == 0)) {
9169                    if (!allowed) {
9170                        // If the caller doesn't have the GET_TASKS permission, then only
9171                        // allow them to see a small subset of tasks -- their own and home.
9172                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9173                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9174                            continue;
9175                        }
9176                    }
9177                    final ActivityStack stack = tr.getStack();
9178                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9179                        if (stack != null && stack.isHomeStack()) {
9180                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9181                                    "Skipping, home stack task: " + tr);
9182                            continue;
9183                        }
9184                    }
9185                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9186                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9187                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9188                                    "Skipping, top task in docked stack: " + tr);
9189                            continue;
9190                        }
9191                    }
9192                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9193                        if (stack != null && stack.isPinnedStack()) {
9194                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9195                                    "Skipping, pinned stack task: " + tr);
9196                            continue;
9197                        }
9198                    }
9199                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9200                        // Don't include auto remove tasks that are finished or finishing.
9201                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9202                                "Skipping, auto-remove without activity: " + tr);
9203                        continue;
9204                    }
9205                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9206                            && !tr.isAvailable) {
9207                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9208                                "Skipping, unavail real act: " + tr);
9209                        continue;
9210                    }
9211
9212                    if (!tr.mUserSetupComplete) {
9213                        // Don't include task launched while user is not done setting-up.
9214                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9215                                "Skipping, user setup not complete: " + tr);
9216                        continue;
9217                    }
9218
9219                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9220                    if (!detailed) {
9221                        rti.baseIntent.replaceExtras((Bundle)null);
9222                    }
9223
9224                    res.add(rti);
9225                    maxNum--;
9226                }
9227            }
9228            return new ParceledListSlice<>(res);
9229        }
9230    }
9231
9232    @Override
9233    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9234        synchronized (this) {
9235            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9236                    "getTaskThumbnail()");
9237            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9238                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9239            if (tr != null) {
9240                return tr.getTaskThumbnailLocked();
9241            }
9242        }
9243        return null;
9244    }
9245
9246    @Override
9247    public int addAppTask(IBinder activityToken, Intent intent,
9248            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9249        final int callingUid = Binder.getCallingUid();
9250        final long callingIdent = Binder.clearCallingIdentity();
9251
9252        try {
9253            synchronized (this) {
9254                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9255                if (r == null) {
9256                    throw new IllegalArgumentException("Activity does not exist; token="
9257                            + activityToken);
9258                }
9259                ComponentName comp = intent.getComponent();
9260                if (comp == null) {
9261                    throw new IllegalArgumentException("Intent " + intent
9262                            + " must specify explicit component");
9263                }
9264                if (thumbnail.getWidth() != mThumbnailWidth
9265                        || thumbnail.getHeight() != mThumbnailHeight) {
9266                    throw new IllegalArgumentException("Bad thumbnail size: got "
9267                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9268                            + mThumbnailWidth + "x" + mThumbnailHeight);
9269                }
9270                if (intent.getSelector() != null) {
9271                    intent.setSelector(null);
9272                }
9273                if (intent.getSourceBounds() != null) {
9274                    intent.setSourceBounds(null);
9275                }
9276                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9277                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9278                        // The caller has added this as an auto-remove task...  that makes no
9279                        // sense, so turn off auto-remove.
9280                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9281                    }
9282                }
9283                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9284                    mLastAddedTaskActivity = null;
9285                }
9286                ActivityInfo ainfo = mLastAddedTaskActivity;
9287                if (ainfo == null) {
9288                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9289                            comp, 0, UserHandle.getUserId(callingUid));
9290                    if (ainfo.applicationInfo.uid != callingUid) {
9291                        throw new SecurityException(
9292                                "Can't add task for another application: target uid="
9293                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9294                    }
9295                }
9296
9297                TaskRecord task = new TaskRecord(this,
9298                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9299                        ainfo, intent, description, new TaskThumbnailInfo());
9300
9301                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9302                if (trimIdx >= 0) {
9303                    // If this would have caused a trim, then we'll abort because that
9304                    // means it would be added at the end of the list but then just removed.
9305                    return INVALID_TASK_ID;
9306                }
9307
9308                final int N = mRecentTasks.size();
9309                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9310                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9311                    tr.removedFromRecents();
9312                }
9313
9314                task.inRecents = true;
9315                mRecentTasks.add(task);
9316                r.getStack().addTask(task, false, "addAppTask");
9317
9318                task.setLastThumbnailLocked(thumbnail);
9319                task.freeLastThumbnail();
9320                return task.taskId;
9321            }
9322        } finally {
9323            Binder.restoreCallingIdentity(callingIdent);
9324        }
9325    }
9326
9327    @Override
9328    public Point getAppTaskThumbnailSize() {
9329        synchronized (this) {
9330            return new Point(mThumbnailWidth,  mThumbnailHeight);
9331        }
9332    }
9333
9334    @Override
9335    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9336        synchronized (this) {
9337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9338            if (r != null) {
9339                r.setTaskDescription(td);
9340                r.task.updateTaskDescription();
9341                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9342            }
9343        }
9344    }
9345
9346    @Override
9347    public void setTaskResizeable(int taskId, int resizeableMode) {
9348        synchronized (this) {
9349            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351            if (task == null) {
9352                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9353                return;
9354            }
9355            if (task.mResizeMode != resizeableMode) {
9356                task.mResizeMode = resizeableMode;
9357                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9358                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9359                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9360            }
9361        }
9362    }
9363
9364    @Override
9365    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9367        long ident = Binder.clearCallingIdentity();
9368        try {
9369            synchronized (this) {
9370                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9371                if (task == null) {
9372                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9373                    return;
9374                }
9375                // Place the task in the right stack if it isn't there already based on
9376                // the requested bounds.
9377                // The stack transition logic is:
9378                // - a null bounds on a freeform task moves that task to fullscreen
9379                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9380                //   that task to freeform
9381                // - otherwise the task is not moved
9382                int stackId = task.getStackId();
9383                if (!StackId.isTaskResizeAllowed(stackId)) {
9384                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9385                }
9386                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9387                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9388                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9389                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9390                }
9391                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9392                if (stackId != task.getStackId()) {
9393                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9394                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9395                    preserveWindow = false;
9396                }
9397
9398                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9399                        false /* deferResume */);
9400            }
9401        } finally {
9402            Binder.restoreCallingIdentity(ident);
9403        }
9404    }
9405
9406    @Override
9407    public Rect getTaskBounds(int taskId) {
9408        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9409        long ident = Binder.clearCallingIdentity();
9410        Rect rect = new Rect();
9411        try {
9412            synchronized (this) {
9413                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9414                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9415                if (task == null) {
9416                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9417                    return rect;
9418                }
9419                if (task.getStack() != null) {
9420                    // Return the bounds from window manager since it will be adjusted for various
9421                    // things like the presense of a docked stack for tasks that aren't resizeable.
9422                    mWindowManager.getTaskBounds(task.taskId, rect);
9423                } else {
9424                    // Task isn't in window manager yet since it isn't associated with a stack.
9425                    // Return the persist value from activity manager
9426                    if (task.mBounds != null) {
9427                        rect.set(task.mBounds);
9428                    } else if (task.mLastNonFullscreenBounds != null) {
9429                        rect.set(task.mLastNonFullscreenBounds);
9430                    }
9431                }
9432            }
9433        } finally {
9434            Binder.restoreCallingIdentity(ident);
9435        }
9436        return rect;
9437    }
9438
9439    @Override
9440    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9441        if (userId != UserHandle.getCallingUserId()) {
9442            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9443                    "getTaskDescriptionIcon");
9444        }
9445        final File passedIconFile = new File(filePath);
9446        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9447                passedIconFile.getName());
9448        if (!legitIconFile.getPath().equals(filePath)
9449                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9450            throw new IllegalArgumentException("Bad file path: " + filePath
9451                    + " passed for userId " + userId);
9452        }
9453        return mRecentTasks.getTaskDescriptionIcon(filePath);
9454    }
9455
9456    @Override
9457    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9458            throws RemoteException {
9459        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9460                opts.getCustomInPlaceResId() == 0) {
9461            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9462                    "with valid animation");
9463        }
9464        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9465        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9466                opts.getCustomInPlaceResId());
9467        mWindowManager.executeAppTransition();
9468    }
9469
9470    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9471            boolean removeFromRecents) {
9472        if (removeFromRecents) {
9473            mRecentTasks.remove(tr);
9474            tr.removedFromRecents();
9475        }
9476        ComponentName component = tr.getBaseIntent().getComponent();
9477        if (component == null) {
9478            Slog.w(TAG, "No component for base intent of task: " + tr);
9479            return;
9480        }
9481
9482        // Find any running services associated with this app and stop if needed.
9483        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9484
9485        if (!killProcess) {
9486            return;
9487        }
9488
9489        // Determine if the process(es) for this task should be killed.
9490        final String pkg = component.getPackageName();
9491        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9492        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9493        for (int i = 0; i < pmap.size(); i++) {
9494
9495            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9496            for (int j = 0; j < uids.size(); j++) {
9497                ProcessRecord proc = uids.valueAt(j);
9498                if (proc.userId != tr.userId) {
9499                    // Don't kill process for a different user.
9500                    continue;
9501                }
9502                if (proc == mHomeProcess) {
9503                    // Don't kill the home process along with tasks from the same package.
9504                    continue;
9505                }
9506                if (!proc.pkgList.containsKey(pkg)) {
9507                    // Don't kill process that is not associated with this task.
9508                    continue;
9509                }
9510
9511                for (int k = 0; k < proc.activities.size(); k++) {
9512                    TaskRecord otherTask = proc.activities.get(k).task;
9513                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9514                        // Don't kill process(es) that has an activity in a different task that is
9515                        // also in recents.
9516                        return;
9517                    }
9518                }
9519
9520                if (proc.foregroundServices) {
9521                    // Don't kill process(es) with foreground service.
9522                    return;
9523                }
9524
9525                // Add process to kill list.
9526                procsToKill.add(proc);
9527            }
9528        }
9529
9530        // Kill the running processes.
9531        for (int i = 0; i < procsToKill.size(); i++) {
9532            ProcessRecord pr = procsToKill.get(i);
9533            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9534                    && pr.curReceivers.isEmpty()) {
9535                pr.kill("remove task", true);
9536            } else {
9537                // We delay killing processes that are not in the background or running a receiver.
9538                pr.waitingToKill = "remove task";
9539            }
9540        }
9541    }
9542
9543    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9544        // Remove all tasks with activities in the specified package from the list of recent tasks
9545        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9546            TaskRecord tr = mRecentTasks.get(i);
9547            if (tr.userId != userId) continue;
9548
9549            ComponentName cn = tr.intent.getComponent();
9550            if (cn != null && cn.getPackageName().equals(packageName)) {
9551                // If the package name matches, remove the task.
9552                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9553            }
9554        }
9555    }
9556
9557    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9558            int userId) {
9559
9560        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9561            TaskRecord tr = mRecentTasks.get(i);
9562            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9563                continue;
9564            }
9565
9566            ComponentName cn = tr.intent.getComponent();
9567            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9568                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9569            if (sameComponent) {
9570                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9571            }
9572        }
9573    }
9574
9575    /**
9576     * Removes the task with the specified task id.
9577     *
9578     * @param taskId Identifier of the task to be removed.
9579     * @param killProcess Kill any process associated with the task if possible.
9580     * @param removeFromRecents Whether to also remove the task from recents.
9581     * @return Returns true if the given task was found and removed.
9582     */
9583    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9584            boolean removeFromRecents) {
9585        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9586                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9587        if (tr != null) {
9588            tr.removeTaskActivitiesLocked();
9589            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9590            if (tr.isPersistable) {
9591                notifyTaskPersisterLocked(null, true);
9592            }
9593            return true;
9594        }
9595        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9596        return false;
9597    }
9598
9599    @Override
9600    public void removeStack(int stackId) {
9601        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9602        if (stackId == HOME_STACK_ID) {
9603            throw new IllegalArgumentException("Removing home stack is not allowed.");
9604        }
9605
9606        synchronized (this) {
9607            final long ident = Binder.clearCallingIdentity();
9608            try {
9609                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9610                if (stack == null) {
9611                    return;
9612                }
9613                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9614                for (int i = tasks.size() - 1; i >= 0; i--) {
9615                    removeTaskByIdLocked(
9616                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9617                }
9618            } finally {
9619                Binder.restoreCallingIdentity(ident);
9620            }
9621        }
9622    }
9623
9624    @Override
9625    public boolean removeTask(int taskId) {
9626        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9627        synchronized (this) {
9628            final long ident = Binder.clearCallingIdentity();
9629            try {
9630                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9631            } finally {
9632                Binder.restoreCallingIdentity(ident);
9633            }
9634        }
9635    }
9636
9637    /**
9638     * TODO: Add mController hook
9639     */
9640    @Override
9641    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9642        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9643
9644        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9645        synchronized(this) {
9646            moveTaskToFrontLocked(taskId, flags, bOptions);
9647        }
9648    }
9649
9650    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9651        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9652
9653        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9654                Binder.getCallingUid(), -1, -1, "Task to front")) {
9655            ActivityOptions.abort(options);
9656            return;
9657        }
9658        final long origId = Binder.clearCallingIdentity();
9659        try {
9660            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9661            if (task == null) {
9662                Slog.d(TAG, "Could not find task for id: "+ taskId);
9663                return;
9664            }
9665            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9666                mStackSupervisor.showLockTaskToast();
9667                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9668                return;
9669            }
9670            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9671            if (prev != null && prev.isRecentsActivity()) {
9672                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9673            }
9674            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9675                    false /* forceNonResizable */);
9676        } finally {
9677            Binder.restoreCallingIdentity(origId);
9678        }
9679        ActivityOptions.abort(options);
9680    }
9681
9682    /**
9683     * Moves an activity, and all of the other activities within the same task, to the bottom
9684     * of the history stack.  The activity's order within the task is unchanged.
9685     *
9686     * @param token A reference to the activity we wish to move
9687     * @param nonRoot If false then this only works if the activity is the root
9688     *                of a task; if true it will work for any activity in a task.
9689     * @return Returns true if the move completed, false if not.
9690     */
9691    @Override
9692    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9693        enforceNotIsolatedCaller("moveActivityTaskToBack");
9694        synchronized(this) {
9695            final long origId = Binder.clearCallingIdentity();
9696            try {
9697                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9698                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9699                if (task != null) {
9700                    if (mStackSupervisor.isLockedTask(task)) {
9701                        mStackSupervisor.showLockTaskToast();
9702                        return false;
9703                    }
9704                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9705                }
9706            } finally {
9707                Binder.restoreCallingIdentity(origId);
9708            }
9709        }
9710        return false;
9711    }
9712
9713    @Override
9714    public void moveTaskBackwards(int task) {
9715        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9716                "moveTaskBackwards()");
9717
9718        synchronized(this) {
9719            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9720                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9721                return;
9722            }
9723            final long origId = Binder.clearCallingIdentity();
9724            moveTaskBackwardsLocked(task);
9725            Binder.restoreCallingIdentity(origId);
9726        }
9727    }
9728
9729    private final void moveTaskBackwardsLocked(int task) {
9730        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9731    }
9732
9733    @Override
9734    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9735            IActivityContainerCallback callback) throws RemoteException {
9736        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9737        synchronized (this) {
9738            if (parentActivityToken == null) {
9739                throw new IllegalArgumentException("parent token must not be null");
9740            }
9741            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9742            if (r == null) {
9743                return null;
9744            }
9745            if (callback == null) {
9746                throw new IllegalArgumentException("callback must not be null");
9747            }
9748            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9749        }
9750    }
9751
9752    @Override
9753    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9754        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9755        synchronized (this) {
9756            final int stackId = mStackSupervisor.getNextStackId();
9757            final ActivityStack stack =
9758                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9759            if (stack == null) {
9760                return null;
9761            }
9762            return stack.mActivityContainer;
9763        }
9764    }
9765
9766    @Override
9767    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9768        synchronized (this) {
9769            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9770            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9771                return stack.mActivityContainer.getDisplayId();
9772            }
9773            return DEFAULT_DISPLAY;
9774        }
9775    }
9776
9777    @Override
9778    public int getActivityStackId(IBinder token) throws RemoteException {
9779        synchronized (this) {
9780            ActivityStack stack = ActivityRecord.getStackLocked(token);
9781            if (stack == null) {
9782                return INVALID_STACK_ID;
9783            }
9784            return stack.mStackId;
9785        }
9786    }
9787
9788    @Override
9789    public void exitFreeformMode(IBinder token) throws RemoteException {
9790        synchronized (this) {
9791            long ident = Binder.clearCallingIdentity();
9792            try {
9793                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9794                if (r == null) {
9795                    throw new IllegalArgumentException(
9796                            "exitFreeformMode: No activity record matching token=" + token);
9797                }
9798                final ActivityStack stack = r.getStackLocked(token);
9799                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9800                    throw new IllegalStateException(
9801                            "exitFreeformMode: You can only go fullscreen from freeform.");
9802                }
9803                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9804                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9805                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9806            } finally {
9807                Binder.restoreCallingIdentity(ident);
9808            }
9809        }
9810    }
9811
9812    @Override
9813    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9814        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9815        if (stackId == HOME_STACK_ID) {
9816            throw new IllegalArgumentException(
9817                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9818        }
9819        synchronized (this) {
9820            long ident = Binder.clearCallingIdentity();
9821            try {
9822                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9823                        + " to stackId=" + stackId + " toTop=" + toTop);
9824                if (stackId == DOCKED_STACK_ID) {
9825                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9826                            null /* initialBounds */);
9827                }
9828                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9829                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9830                if (result && stackId == DOCKED_STACK_ID) {
9831                    // If task moved to docked stack - show recents if needed.
9832                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9833                            "moveTaskToDockedStack");
9834                }
9835            } finally {
9836                Binder.restoreCallingIdentity(ident);
9837            }
9838        }
9839    }
9840
9841    @Override
9842    public void swapDockedAndFullscreenStack() throws RemoteException {
9843        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9844        synchronized (this) {
9845            long ident = Binder.clearCallingIdentity();
9846            try {
9847                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9848                        FULLSCREEN_WORKSPACE_STACK_ID);
9849                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9850                        : null;
9851                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9852                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9853                        : null;
9854                if (topTask == null || tasks == null || tasks.size() == 0) {
9855                    Slog.w(TAG,
9856                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9857                    return;
9858                }
9859
9860                // TODO: App transition
9861                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9862
9863                // Defer the resume so resume/pausing while moving stacks is dangerous.
9864                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9865                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9866                        ANIMATE, true /* deferResume */);
9867                final int size = tasks.size();
9868                for (int i = 0; i < size; i++) {
9869                    final int id = tasks.get(i).taskId;
9870                    if (id == topTask.taskId) {
9871                        continue;
9872                    }
9873                    mStackSupervisor.moveTaskToStackLocked(id,
9874                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9875                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9876                }
9877
9878                // Because we deferred the resume, to avoid conflicts with stack switches while
9879                // resuming, we need to do it after all the tasks are moved.
9880                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9881                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9882
9883                mWindowManager.executeAppTransition();
9884            } finally {
9885                Binder.restoreCallingIdentity(ident);
9886            }
9887        }
9888    }
9889
9890    /**
9891     * Moves the input task to the docked stack.
9892     *
9893     * @param taskId Id of task to move.
9894     * @param createMode The mode the docked stack should be created in if it doesn't exist
9895     *                   already. See
9896     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9897     *                   and
9898     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9899     * @param toTop If the task and stack should be moved to the top.
9900     * @param animate Whether we should play an animation for the moving the task
9901     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9902     *                      docked stack. Pass {@code null} to use default bounds.
9903     */
9904    @Override
9905    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9906            Rect initialBounds, boolean moveHomeStackFront) {
9907        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9908        synchronized (this) {
9909            long ident = Binder.clearCallingIdentity();
9910            try {
9911                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9912                        + " to createMode=" + createMode + " toTop=" + toTop);
9913                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9914                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9915                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9916                        animate, DEFER_RESUME);
9917                if (moved) {
9918                    if (moveHomeStackFront) {
9919                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9920                    }
9921                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9922                }
9923                return moved;
9924            } finally {
9925                Binder.restoreCallingIdentity(ident);
9926            }
9927        }
9928    }
9929
9930    /**
9931     * Moves the top activity in the input stackId to the pinned stack.
9932     *
9933     * @param stackId Id of stack to move the top activity to pinned stack.
9934     * @param bounds Bounds to use for pinned stack.
9935     *
9936     * @return True if the top activity of the input stack was successfully moved to the pinned
9937     *          stack.
9938     */
9939    @Override
9940    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9941        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9942        synchronized (this) {
9943            if (!mSupportsPictureInPicture) {
9944                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9945                        + "Device doesn't support picture-in-pciture mode");
9946            }
9947
9948            long ident = Binder.clearCallingIdentity();
9949            try {
9950                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9951            } finally {
9952                Binder.restoreCallingIdentity(ident);
9953            }
9954        }
9955    }
9956
9957    @Override
9958    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9959            boolean preserveWindows, boolean animate, int animationDuration) {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9961        long ident = Binder.clearCallingIdentity();
9962        try {
9963            synchronized (this) {
9964                if (animate) {
9965                    if (stackId == PINNED_STACK_ID) {
9966                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9967                    } else {
9968                        throw new IllegalArgumentException("Stack: " + stackId
9969                                + " doesn't support animated resize.");
9970                    }
9971                } else {
9972                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9973                            null /* tempTaskInsetBounds */, preserveWindows,
9974                            allowResizeInDockedMode, !DEFER_RESUME);
9975                }
9976            }
9977        } finally {
9978            Binder.restoreCallingIdentity(ident);
9979        }
9980    }
9981
9982    @Override
9983    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9984            Rect tempDockedTaskInsetBounds,
9985            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9986        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9987                "resizeDockedStack()");
9988        long ident = Binder.clearCallingIdentity();
9989        try {
9990            synchronized (this) {
9991                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9992                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9993                        PRESERVE_WINDOWS);
9994            }
9995        } finally {
9996            Binder.restoreCallingIdentity(ident);
9997        }
9998    }
9999
10000    @Override
10001    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10002        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10003                "resizePinnedStack()");
10004        final long ident = Binder.clearCallingIdentity();
10005        try {
10006            synchronized (this) {
10007                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10008            }
10009        } finally {
10010            Binder.restoreCallingIdentity(ident);
10011        }
10012    }
10013
10014    @Override
10015    public void positionTaskInStack(int taskId, int stackId, int position) {
10016        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10017        if (stackId == HOME_STACK_ID) {
10018            throw new IllegalArgumentException(
10019                    "positionTaskInStack: Attempt to change the position of task "
10020                    + taskId + " in/to home stack");
10021        }
10022        synchronized (this) {
10023            long ident = Binder.clearCallingIdentity();
10024            try {
10025                if (DEBUG_STACK) Slog.d(TAG_STACK,
10026                        "positionTaskInStack: positioning task=" + taskId
10027                        + " in stackId=" + stackId + " at position=" + position);
10028                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10029            } finally {
10030                Binder.restoreCallingIdentity(ident);
10031            }
10032        }
10033    }
10034
10035    @Override
10036    public List<StackInfo> getAllStackInfos() {
10037        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10038        long ident = Binder.clearCallingIdentity();
10039        try {
10040            synchronized (this) {
10041                return mStackSupervisor.getAllStackInfosLocked();
10042            }
10043        } finally {
10044            Binder.restoreCallingIdentity(ident);
10045        }
10046    }
10047
10048    @Override
10049    public StackInfo getStackInfo(int stackId) {
10050        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10051        long ident = Binder.clearCallingIdentity();
10052        try {
10053            synchronized (this) {
10054                return mStackSupervisor.getStackInfoLocked(stackId);
10055            }
10056        } finally {
10057            Binder.restoreCallingIdentity(ident);
10058        }
10059    }
10060
10061    @Override
10062    public boolean isInHomeStack(int taskId) {
10063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10068                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10069                final ActivityStack stack = tr != null ? tr.getStack() : null;
10070                return stack != null && stack.isHomeStack();
10071            }
10072        } finally {
10073            Binder.restoreCallingIdentity(ident);
10074        }
10075    }
10076
10077    @Override
10078    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10079        synchronized(this) {
10080            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10081        }
10082    }
10083
10084    @Override
10085    public void updateDeviceOwner(String packageName) {
10086        final int callingUid = Binder.getCallingUid();
10087        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10088            throw new SecurityException("updateDeviceOwner called from non-system process");
10089        }
10090        synchronized (this) {
10091            mDeviceOwnerName = packageName;
10092        }
10093    }
10094
10095    @Override
10096    public void updateLockTaskPackages(int userId, String[] packages) {
10097        final int callingUid = Binder.getCallingUid();
10098        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10099            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10100                    "updateLockTaskPackages()");
10101        }
10102        synchronized (this) {
10103            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10104                    Arrays.toString(packages));
10105            mLockTaskPackages.put(userId, packages);
10106            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10107        }
10108    }
10109
10110
10111    void startLockTaskModeLocked(TaskRecord task) {
10112        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10113        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10114            return;
10115        }
10116
10117        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10118        // is initiated by system after the pinning request was shown and locked mode is initiated
10119        // by an authorized app directly
10120        final int callingUid = Binder.getCallingUid();
10121        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10122        long ident = Binder.clearCallingIdentity();
10123        try {
10124            if (!isSystemInitiated) {
10125                task.mLockTaskUid = callingUid;
10126                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10127                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10128                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10129                    StatusBarManagerInternal statusBarManager =
10130                            LocalServices.getService(StatusBarManagerInternal.class);
10131                    if (statusBarManager != null) {
10132                        statusBarManager.showScreenPinningRequest(task.taskId);
10133                    }
10134                    return;
10135                }
10136
10137                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10138                if (stack == null || task != stack.topTask()) {
10139                    throw new IllegalArgumentException("Invalid task, not in foreground");
10140                }
10141            }
10142            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10143                    "Locking fully");
10144            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10145                    ActivityManager.LOCK_TASK_MODE_PINNED :
10146                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10147                    "startLockTask", true);
10148        } finally {
10149            Binder.restoreCallingIdentity(ident);
10150        }
10151    }
10152
10153    @Override
10154    public void startLockTaskMode(int taskId) {
10155        synchronized (this) {
10156            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10157            if (task != null) {
10158                startLockTaskModeLocked(task);
10159            }
10160        }
10161    }
10162
10163    @Override
10164    public void startLockTaskMode(IBinder token) {
10165        synchronized (this) {
10166            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10167            if (r == null) {
10168                return;
10169            }
10170            final TaskRecord task = r.task;
10171            if (task != null) {
10172                startLockTaskModeLocked(task);
10173            }
10174        }
10175    }
10176
10177    @Override
10178    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10179        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10180        // This makes inner call to look as if it was initiated by system.
10181        long ident = Binder.clearCallingIdentity();
10182        try {
10183            synchronized (this) {
10184                startLockTaskMode(taskId);
10185            }
10186        } finally {
10187            Binder.restoreCallingIdentity(ident);
10188        }
10189    }
10190
10191    @Override
10192    public void stopLockTaskMode() {
10193        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10194        if (lockTask == null) {
10195            // Our work here is done.
10196            return;
10197        }
10198
10199        final int callingUid = Binder.getCallingUid();
10200        final int lockTaskUid = lockTask.mLockTaskUid;
10201        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10202        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10203            // Done.
10204            return;
10205        } else {
10206            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10207            // It is possible lockTaskMode was started by the system process because
10208            // android:lockTaskMode is set to a locking value in the application manifest
10209            // instead of the app calling startLockTaskMode. In this case
10210            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10211            // {@link TaskRecord.effectiveUid} instead. Also caller with
10212            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10213            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10214                    && callingUid != lockTaskUid
10215                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10216                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10217                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10218            }
10219        }
10220        long ident = Binder.clearCallingIdentity();
10221        try {
10222            Log.d(TAG, "stopLockTaskMode");
10223            // Stop lock task
10224            synchronized (this) {
10225                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10226                        "stopLockTask", true);
10227            }
10228            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10229            if (tm != null) {
10230                tm.showInCallScreen(false);
10231            }
10232        } finally {
10233            Binder.restoreCallingIdentity(ident);
10234        }
10235    }
10236
10237    /**
10238     * This API should be called by SystemUI only when user perform certain action to dismiss
10239     * lock task mode. We should only dismiss pinned lock task mode in this case.
10240     */
10241    @Override
10242    public void stopSystemLockTaskMode() throws RemoteException {
10243        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10244            stopLockTaskMode();
10245        } else {
10246            mStackSupervisor.showLockTaskToast();
10247        }
10248    }
10249
10250    @Override
10251    public boolean isInLockTaskMode() {
10252        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10253    }
10254
10255    @Override
10256    public int getLockTaskModeState() {
10257        synchronized (this) {
10258            return mStackSupervisor.getLockTaskModeState();
10259        }
10260    }
10261
10262    @Override
10263    public void showLockTaskEscapeMessage(IBinder token) {
10264        synchronized (this) {
10265            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10266            if (r == null) {
10267                return;
10268            }
10269            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10270        }
10271    }
10272
10273    // =========================================================
10274    // CONTENT PROVIDERS
10275    // =========================================================
10276
10277    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10278        List<ProviderInfo> providers = null;
10279        try {
10280            providers = AppGlobals.getPackageManager()
10281                    .queryContentProviders(app.processName, app.uid,
10282                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10283                                    | MATCH_DEBUG_TRIAGED_MISSING)
10284                    .getList();
10285        } catch (RemoteException ex) {
10286        }
10287        if (DEBUG_MU) Slog.v(TAG_MU,
10288                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10289        int userId = app.userId;
10290        if (providers != null) {
10291            int N = providers.size();
10292            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10293            for (int i=0; i<N; i++) {
10294                // TODO: keep logic in sync with installEncryptionUnawareProviders
10295                ProviderInfo cpi =
10296                    (ProviderInfo)providers.get(i);
10297                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10298                        cpi.name, cpi.flags);
10299                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10300                    // This is a singleton provider, but a user besides the
10301                    // default user is asking to initialize a process it runs
10302                    // in...  well, no, it doesn't actually run in this process,
10303                    // it runs in the process of the default user.  Get rid of it.
10304                    providers.remove(i);
10305                    N--;
10306                    i--;
10307                    continue;
10308                }
10309
10310                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10311                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10312                if (cpr == null) {
10313                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10314                    mProviderMap.putProviderByClass(comp, cpr);
10315                }
10316                if (DEBUG_MU) Slog.v(TAG_MU,
10317                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10318                app.pubProviders.put(cpi.name, cpr);
10319                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10320                    // Don't add this if it is a platform component that is marked
10321                    // to run in multiple processes, because this is actually
10322                    // part of the framework so doesn't make sense to track as a
10323                    // separate apk in the process.
10324                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10325                            mProcessStats);
10326                }
10327                notifyPackageUse(cpi.applicationInfo.packageName,
10328                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10329            }
10330        }
10331        return providers;
10332    }
10333
10334    /**
10335     * Check if {@link ProcessRecord} has a possible chance at accessing the
10336     * given {@link ProviderInfo}. Final permission checking is always done
10337     * in {@link ContentProvider}.
10338     */
10339    private final String checkContentProviderPermissionLocked(
10340            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10341        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10342        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10343        boolean checkedGrants = false;
10344        if (checkUser) {
10345            // Looking for cross-user grants before enforcing the typical cross-users permissions
10346            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10347            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10348                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10349                    return null;
10350                }
10351                checkedGrants = true;
10352            }
10353            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10354                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10355            if (userId != tmpTargetUserId) {
10356                // When we actually went to determine the final targer user ID, this ended
10357                // up different than our initial check for the authority.  This is because
10358                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10359                // SELF.  So we need to re-check the grants again.
10360                checkedGrants = false;
10361            }
10362        }
10363        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10364                cpi.applicationInfo.uid, cpi.exported)
10365                == PackageManager.PERMISSION_GRANTED) {
10366            return null;
10367        }
10368        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10369                cpi.applicationInfo.uid, cpi.exported)
10370                == PackageManager.PERMISSION_GRANTED) {
10371            return null;
10372        }
10373
10374        PathPermission[] pps = cpi.pathPermissions;
10375        if (pps != null) {
10376            int i = pps.length;
10377            while (i > 0) {
10378                i--;
10379                PathPermission pp = pps[i];
10380                String pprperm = pp.getReadPermission();
10381                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10382                        cpi.applicationInfo.uid, cpi.exported)
10383                        == PackageManager.PERMISSION_GRANTED) {
10384                    return null;
10385                }
10386                String ppwperm = pp.getWritePermission();
10387                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10388                        cpi.applicationInfo.uid, cpi.exported)
10389                        == PackageManager.PERMISSION_GRANTED) {
10390                    return null;
10391                }
10392            }
10393        }
10394        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10395            return null;
10396        }
10397
10398        String msg;
10399        if (!cpi.exported) {
10400            msg = "Permission Denial: opening provider " + cpi.name
10401                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10402                    + ", uid=" + callingUid + ") that is not exported from uid "
10403                    + cpi.applicationInfo.uid;
10404        } else {
10405            msg = "Permission Denial: opening provider " + cpi.name
10406                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10407                    + ", uid=" + callingUid + ") requires "
10408                    + cpi.readPermission + " or " + cpi.writePermission;
10409        }
10410        Slog.w(TAG, msg);
10411        return msg;
10412    }
10413
10414    /**
10415     * Returns if the ContentProvider has granted a uri to callingUid
10416     */
10417    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10418        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10419        if (perms != null) {
10420            for (int i=perms.size()-1; i>=0; i--) {
10421                GrantUri grantUri = perms.keyAt(i);
10422                if (grantUri.sourceUserId == userId || !checkUser) {
10423                    if (matchesProvider(grantUri.uri, cpi)) {
10424                        return true;
10425                    }
10426                }
10427            }
10428        }
10429        return false;
10430    }
10431
10432    /**
10433     * Returns true if the uri authority is one of the authorities specified in the provider.
10434     */
10435    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10436        String uriAuth = uri.getAuthority();
10437        String cpiAuth = cpi.authority;
10438        if (cpiAuth.indexOf(';') == -1) {
10439            return cpiAuth.equals(uriAuth);
10440        }
10441        String[] cpiAuths = cpiAuth.split(";");
10442        int length = cpiAuths.length;
10443        for (int i = 0; i < length; i++) {
10444            if (cpiAuths[i].equals(uriAuth)) return true;
10445        }
10446        return false;
10447    }
10448
10449    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10450            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10451        if (r != null) {
10452            for (int i=0; i<r.conProviders.size(); i++) {
10453                ContentProviderConnection conn = r.conProviders.get(i);
10454                if (conn.provider == cpr) {
10455                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10456                            "Adding provider requested by "
10457                            + r.processName + " from process "
10458                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10459                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10460                    if (stable) {
10461                        conn.stableCount++;
10462                        conn.numStableIncs++;
10463                    } else {
10464                        conn.unstableCount++;
10465                        conn.numUnstableIncs++;
10466                    }
10467                    return conn;
10468                }
10469            }
10470            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10471            if (stable) {
10472                conn.stableCount = 1;
10473                conn.numStableIncs = 1;
10474            } else {
10475                conn.unstableCount = 1;
10476                conn.numUnstableIncs = 1;
10477            }
10478            cpr.connections.add(conn);
10479            r.conProviders.add(conn);
10480            startAssociationLocked(r.uid, r.processName, r.curProcState,
10481                    cpr.uid, cpr.name, cpr.info.processName);
10482            return conn;
10483        }
10484        cpr.addExternalProcessHandleLocked(externalProcessToken);
10485        return null;
10486    }
10487
10488    boolean decProviderCountLocked(ContentProviderConnection conn,
10489            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10490        if (conn != null) {
10491            cpr = conn.provider;
10492            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10493                    "Removing provider requested by "
10494                    + conn.client.processName + " from process "
10495                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10496                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10497            if (stable) {
10498                conn.stableCount--;
10499            } else {
10500                conn.unstableCount--;
10501            }
10502            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10503                cpr.connections.remove(conn);
10504                conn.client.conProviders.remove(conn);
10505                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10506                    // The client is more important than last activity -- note the time this
10507                    // is happening, so we keep the old provider process around a bit as last
10508                    // activity to avoid thrashing it.
10509                    if (cpr.proc != null) {
10510                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10511                    }
10512                }
10513                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10514                return true;
10515            }
10516            return false;
10517        }
10518        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10519        return false;
10520    }
10521
10522    private void checkTime(long startTime, String where) {
10523        long now = SystemClock.uptimeMillis();
10524        if ((now-startTime) > 50) {
10525            // If we are taking more than 50ms, log about it.
10526            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10527        }
10528    }
10529
10530    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10531            PROC_SPACE_TERM,
10532            PROC_SPACE_TERM|PROC_PARENS,
10533            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10534    };
10535
10536    private final long[] mProcessStateStatsLongs = new long[1];
10537
10538    boolean isProcessAliveLocked(ProcessRecord proc) {
10539        if (proc.procStatFile == null) {
10540            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10541        }
10542        mProcessStateStatsLongs[0] = 0;
10543        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10544                mProcessStateStatsLongs, null)) {
10545            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10546            return false;
10547        }
10548        final long state = mProcessStateStatsLongs[0];
10549        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10550                + (char)state);
10551        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10552    }
10553
10554    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10555            String name, IBinder token, boolean stable, int userId) {
10556        ContentProviderRecord cpr;
10557        ContentProviderConnection conn = null;
10558        ProviderInfo cpi = null;
10559
10560        synchronized(this) {
10561            long startTime = SystemClock.uptimeMillis();
10562
10563            ProcessRecord r = null;
10564            if (caller != null) {
10565                r = getRecordForAppLocked(caller);
10566                if (r == null) {
10567                    throw new SecurityException(
10568                            "Unable to find app for caller " + caller
10569                          + " (pid=" + Binder.getCallingPid()
10570                          + ") when getting content provider " + name);
10571                }
10572            }
10573
10574            boolean checkCrossUser = true;
10575
10576            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10577
10578            // First check if this content provider has been published...
10579            cpr = mProviderMap.getProviderByName(name, userId);
10580            // If that didn't work, check if it exists for user 0 and then
10581            // verify that it's a singleton provider before using it.
10582            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10583                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10584                if (cpr != null) {
10585                    cpi = cpr.info;
10586                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10587                            cpi.name, cpi.flags)
10588                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10589                        userId = UserHandle.USER_SYSTEM;
10590                        checkCrossUser = false;
10591                    } else {
10592                        cpr = null;
10593                        cpi = null;
10594                    }
10595                }
10596            }
10597
10598            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10599            if (providerRunning) {
10600                cpi = cpr.info;
10601                String msg;
10602                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10603                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10604                        != null) {
10605                    throw new SecurityException(msg);
10606                }
10607                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10608
10609                if (r != null && cpr.canRunHere(r)) {
10610                    // This provider has been published or is in the process
10611                    // of being published...  but it is also allowed to run
10612                    // in the caller's process, so don't make a connection
10613                    // and just let the caller instantiate its own instance.
10614                    ContentProviderHolder holder = cpr.newHolder(null);
10615                    // don't give caller the provider object, it needs
10616                    // to make its own.
10617                    holder.provider = null;
10618                    return holder;
10619                }
10620
10621                final long origId = Binder.clearCallingIdentity();
10622
10623                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10624
10625                // In this case the provider instance already exists, so we can
10626                // return it right away.
10627                conn = incProviderCountLocked(r, cpr, token, stable);
10628                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10629                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10630                        // If this is a perceptible app accessing the provider,
10631                        // make sure to count it as being accessed and thus
10632                        // back up on the LRU list.  This is good because
10633                        // content providers are often expensive to start.
10634                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10635                        updateLruProcessLocked(cpr.proc, false, null);
10636                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10637                    }
10638                }
10639
10640                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10641                final int verifiedAdj = cpr.proc.verifiedAdj;
10642                boolean success = updateOomAdjLocked(cpr.proc);
10643                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10644                // if the process has been successfully adjusted.  So to reduce races with
10645                // it, we will check whether the process still exists.  Note that this doesn't
10646                // completely get rid of races with LMK killing the process, but should make
10647                // them much smaller.
10648                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10649                    success = false;
10650                }
10651                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10652                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10653                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10654                // NOTE: there is still a race here where a signal could be
10655                // pending on the process even though we managed to update its
10656                // adj level.  Not sure what to do about this, but at least
10657                // the race is now smaller.
10658                if (!success) {
10659                    // Uh oh...  it looks like the provider's process
10660                    // has been killed on us.  We need to wait for a new
10661                    // process to be started, and make sure its death
10662                    // doesn't kill our process.
10663                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10664                            + " is crashing; detaching " + r);
10665                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10666                    checkTime(startTime, "getContentProviderImpl: before appDied");
10667                    appDiedLocked(cpr.proc);
10668                    checkTime(startTime, "getContentProviderImpl: after appDied");
10669                    if (!lastRef) {
10670                        // This wasn't the last ref our process had on
10671                        // the provider...  we have now been killed, bail.
10672                        return null;
10673                    }
10674                    providerRunning = false;
10675                    conn = null;
10676                } else {
10677                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10678                }
10679
10680                Binder.restoreCallingIdentity(origId);
10681            }
10682
10683            if (!providerRunning) {
10684                try {
10685                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10686                    cpi = AppGlobals.getPackageManager().
10687                        resolveContentProvider(name,
10688                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10689                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10690                } catch (RemoteException ex) {
10691                }
10692                if (cpi == null) {
10693                    return null;
10694                }
10695                // If the provider is a singleton AND
10696                // (it's a call within the same user || the provider is a
10697                // privileged app)
10698                // Then allow connecting to the singleton provider
10699                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10700                        cpi.name, cpi.flags)
10701                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10702                if (singleton) {
10703                    userId = UserHandle.USER_SYSTEM;
10704                }
10705                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10706                checkTime(startTime, "getContentProviderImpl: got app info for user");
10707
10708                String msg;
10709                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10710                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10711                        != null) {
10712                    throw new SecurityException(msg);
10713                }
10714                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10715
10716                if (!mProcessesReady
10717                        && !cpi.processName.equals("system")) {
10718                    // If this content provider does not run in the system
10719                    // process, and the system is not yet ready to run other
10720                    // processes, then fail fast instead of hanging.
10721                    throw new IllegalArgumentException(
10722                            "Attempt to launch content provider before system ready");
10723                }
10724
10725                // Make sure that the user who owns this provider is running.  If not,
10726                // we don't want to allow it to run.
10727                if (!mUserController.isUserRunningLocked(userId, 0)) {
10728                    Slog.w(TAG, "Unable to launch app "
10729                            + cpi.applicationInfo.packageName + "/"
10730                            + cpi.applicationInfo.uid + " for provider "
10731                            + name + ": user " + userId + " is stopped");
10732                    return null;
10733                }
10734
10735                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10736                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10737                cpr = mProviderMap.getProviderByClass(comp, userId);
10738                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10739                final boolean firstClass = cpr == null;
10740                if (firstClass) {
10741                    final long ident = Binder.clearCallingIdentity();
10742
10743                    // If permissions need a review before any of the app components can run,
10744                    // we return no provider and launch a review activity if the calling app
10745                    // is in the foreground.
10746                    if (mPermissionReviewRequired) {
10747                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10748                            return null;
10749                        }
10750                    }
10751
10752                    try {
10753                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10754                        ApplicationInfo ai =
10755                            AppGlobals.getPackageManager().
10756                                getApplicationInfo(
10757                                        cpi.applicationInfo.packageName,
10758                                        STOCK_PM_FLAGS, userId);
10759                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10760                        if (ai == null) {
10761                            Slog.w(TAG, "No package info for content provider "
10762                                    + cpi.name);
10763                            return null;
10764                        }
10765                        ai = getAppInfoForUser(ai, userId);
10766                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10767                    } catch (RemoteException ex) {
10768                        // pm is in same process, this will never happen.
10769                    } finally {
10770                        Binder.restoreCallingIdentity(ident);
10771                    }
10772                }
10773
10774                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10775
10776                if (r != null && cpr.canRunHere(r)) {
10777                    // If this is a multiprocess provider, then just return its
10778                    // info and allow the caller to instantiate it.  Only do
10779                    // this if the provider is the same user as the caller's
10780                    // process, or can run as root (so can be in any process).
10781                    return cpr.newHolder(null);
10782                }
10783
10784                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10785                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10786                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10787
10788                // This is single process, and our app is now connecting to it.
10789                // See if we are already in the process of launching this
10790                // provider.
10791                final int N = mLaunchingProviders.size();
10792                int i;
10793                for (i = 0; i < N; i++) {
10794                    if (mLaunchingProviders.get(i) == cpr) {
10795                        break;
10796                    }
10797                }
10798
10799                // If the provider is not already being launched, then get it
10800                // started.
10801                if (i >= N) {
10802                    final long origId = Binder.clearCallingIdentity();
10803
10804                    try {
10805                        // Content provider is now in use, its package can't be stopped.
10806                        try {
10807                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10808                            AppGlobals.getPackageManager().setPackageStoppedState(
10809                                    cpr.appInfo.packageName, false, userId);
10810                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10811                        } catch (RemoteException e) {
10812                        } catch (IllegalArgumentException e) {
10813                            Slog.w(TAG, "Failed trying to unstop package "
10814                                    + cpr.appInfo.packageName + ": " + e);
10815                        }
10816
10817                        // Use existing process if already started
10818                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10819                        ProcessRecord proc = getProcessRecordLocked(
10820                                cpi.processName, cpr.appInfo.uid, false);
10821                        if (proc != null && proc.thread != null && !proc.killed) {
10822                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10823                                    "Installing in existing process " + proc);
10824                            if (!proc.pubProviders.containsKey(cpi.name)) {
10825                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10826                                proc.pubProviders.put(cpi.name, cpr);
10827                                try {
10828                                    proc.thread.scheduleInstallProvider(cpi);
10829                                } catch (RemoteException e) {
10830                                }
10831                            }
10832                        } else {
10833                            checkTime(startTime, "getContentProviderImpl: before start process");
10834                            proc = startProcessLocked(cpi.processName,
10835                                    cpr.appInfo, false, 0, "content provider",
10836                                    new ComponentName(cpi.applicationInfo.packageName,
10837                                            cpi.name), false, false, false);
10838                            checkTime(startTime, "getContentProviderImpl: after start process");
10839                            if (proc == null) {
10840                                Slog.w(TAG, "Unable to launch app "
10841                                        + cpi.applicationInfo.packageName + "/"
10842                                        + cpi.applicationInfo.uid + " for provider "
10843                                        + name + ": process is bad");
10844                                return null;
10845                            }
10846                        }
10847                        cpr.launchingApp = proc;
10848                        mLaunchingProviders.add(cpr);
10849                    } finally {
10850                        Binder.restoreCallingIdentity(origId);
10851                    }
10852                }
10853
10854                checkTime(startTime, "getContentProviderImpl: updating data structures");
10855
10856                // Make sure the provider is published (the same provider class
10857                // may be published under multiple names).
10858                if (firstClass) {
10859                    mProviderMap.putProviderByClass(comp, cpr);
10860                }
10861
10862                mProviderMap.putProviderByName(name, cpr);
10863                conn = incProviderCountLocked(r, cpr, token, stable);
10864                if (conn != null) {
10865                    conn.waiting = true;
10866                }
10867            }
10868            checkTime(startTime, "getContentProviderImpl: done!");
10869        }
10870
10871        // Wait for the provider to be published...
10872        synchronized (cpr) {
10873            while (cpr.provider == null) {
10874                if (cpr.launchingApp == null) {
10875                    Slog.w(TAG, "Unable to launch app "
10876                            + cpi.applicationInfo.packageName + "/"
10877                            + cpi.applicationInfo.uid + " for provider "
10878                            + name + ": launching app became null");
10879                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10880                            UserHandle.getUserId(cpi.applicationInfo.uid),
10881                            cpi.applicationInfo.packageName,
10882                            cpi.applicationInfo.uid, name);
10883                    return null;
10884                }
10885                try {
10886                    if (DEBUG_MU) Slog.v(TAG_MU,
10887                            "Waiting to start provider " + cpr
10888                            + " launchingApp=" + cpr.launchingApp);
10889                    if (conn != null) {
10890                        conn.waiting = true;
10891                    }
10892                    cpr.wait();
10893                } catch (InterruptedException ex) {
10894                } finally {
10895                    if (conn != null) {
10896                        conn.waiting = false;
10897                    }
10898                }
10899            }
10900        }
10901        return cpr != null ? cpr.newHolder(conn) : null;
10902    }
10903
10904    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10905            ProcessRecord r, final int userId) {
10906        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10907                cpi.packageName, userId)) {
10908
10909            final boolean callerForeground = r == null || r.setSchedGroup
10910                    != ProcessList.SCHED_GROUP_BACKGROUND;
10911
10912            // Show a permission review UI only for starting from a foreground app
10913            if (!callerForeground) {
10914                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10915                        + cpi.packageName + " requires a permissions review");
10916                return false;
10917            }
10918
10919            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10920            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10921                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10922            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10923
10924            if (DEBUG_PERMISSIONS_REVIEW) {
10925                Slog.i(TAG, "u" + userId + " Launching permission review "
10926                        + "for package " + cpi.packageName);
10927            }
10928
10929            final UserHandle userHandle = new UserHandle(userId);
10930            mHandler.post(new Runnable() {
10931                @Override
10932                public void run() {
10933                    mContext.startActivityAsUser(intent, userHandle);
10934                }
10935            });
10936
10937            return false;
10938        }
10939
10940        return true;
10941    }
10942
10943    PackageManagerInternal getPackageManagerInternalLocked() {
10944        if (mPackageManagerInt == null) {
10945            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10946        }
10947        return mPackageManagerInt;
10948    }
10949
10950    @Override
10951    public final ContentProviderHolder getContentProvider(
10952            IApplicationThread caller, String name, int userId, boolean stable) {
10953        enforceNotIsolatedCaller("getContentProvider");
10954        if (caller == null) {
10955            String msg = "null IApplicationThread when getting content provider "
10956                    + name;
10957            Slog.w(TAG, msg);
10958            throw new SecurityException(msg);
10959        }
10960        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10961        // with cross-user grant.
10962        return getContentProviderImpl(caller, name, null, stable, userId);
10963    }
10964
10965    public ContentProviderHolder getContentProviderExternal(
10966            String name, int userId, IBinder token) {
10967        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10968            "Do not have permission in call getContentProviderExternal()");
10969        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10970                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10971        return getContentProviderExternalUnchecked(name, token, userId);
10972    }
10973
10974    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10975            IBinder token, int userId) {
10976        return getContentProviderImpl(null, name, token, true, userId);
10977    }
10978
10979    /**
10980     * Drop a content provider from a ProcessRecord's bookkeeping
10981     */
10982    public void removeContentProvider(IBinder connection, boolean stable) {
10983        enforceNotIsolatedCaller("removeContentProvider");
10984        long ident = Binder.clearCallingIdentity();
10985        try {
10986            synchronized (this) {
10987                ContentProviderConnection conn;
10988                try {
10989                    conn = (ContentProviderConnection)connection;
10990                } catch (ClassCastException e) {
10991                    String msg ="removeContentProvider: " + connection
10992                            + " not a ContentProviderConnection";
10993                    Slog.w(TAG, msg);
10994                    throw new IllegalArgumentException(msg);
10995                }
10996                if (conn == null) {
10997                    throw new NullPointerException("connection is null");
10998                }
10999                if (decProviderCountLocked(conn, null, null, stable)) {
11000                    updateOomAdjLocked();
11001                }
11002            }
11003        } finally {
11004            Binder.restoreCallingIdentity(ident);
11005        }
11006    }
11007
11008    public void removeContentProviderExternal(String name, IBinder token) {
11009        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11010            "Do not have permission in call removeContentProviderExternal()");
11011        int userId = UserHandle.getCallingUserId();
11012        long ident = Binder.clearCallingIdentity();
11013        try {
11014            removeContentProviderExternalUnchecked(name, token, userId);
11015        } finally {
11016            Binder.restoreCallingIdentity(ident);
11017        }
11018    }
11019
11020    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11021        synchronized (this) {
11022            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11023            if(cpr == null) {
11024                //remove from mProvidersByClass
11025                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11026                return;
11027            }
11028
11029            //update content provider record entry info
11030            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11031            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11032            if (localCpr.hasExternalProcessHandles()) {
11033                if (localCpr.removeExternalProcessHandleLocked(token)) {
11034                    updateOomAdjLocked();
11035                } else {
11036                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11037                            + " with no external reference for token: "
11038                            + token + ".");
11039                }
11040            } else {
11041                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11042                        + " with no external references.");
11043            }
11044        }
11045    }
11046
11047    public final void publishContentProviders(IApplicationThread caller,
11048            List<ContentProviderHolder> providers) {
11049        if (providers == null) {
11050            return;
11051        }
11052
11053        enforceNotIsolatedCaller("publishContentProviders");
11054        synchronized (this) {
11055            final ProcessRecord r = getRecordForAppLocked(caller);
11056            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11057            if (r == null) {
11058                throw new SecurityException(
11059                        "Unable to find app for caller " + caller
11060                      + " (pid=" + Binder.getCallingPid()
11061                      + ") when publishing content providers");
11062            }
11063
11064            final long origId = Binder.clearCallingIdentity();
11065
11066            final int N = providers.size();
11067            for (int i = 0; i < N; i++) {
11068                ContentProviderHolder src = providers.get(i);
11069                if (src == null || src.info == null || src.provider == null) {
11070                    continue;
11071                }
11072                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11073                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11074                if (dst != null) {
11075                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11076                    mProviderMap.putProviderByClass(comp, dst);
11077                    String names[] = dst.info.authority.split(";");
11078                    for (int j = 0; j < names.length; j++) {
11079                        mProviderMap.putProviderByName(names[j], dst);
11080                    }
11081
11082                    int launchingCount = mLaunchingProviders.size();
11083                    int j;
11084                    boolean wasInLaunchingProviders = false;
11085                    for (j = 0; j < launchingCount; j++) {
11086                        if (mLaunchingProviders.get(j) == dst) {
11087                            mLaunchingProviders.remove(j);
11088                            wasInLaunchingProviders = true;
11089                            j--;
11090                            launchingCount--;
11091                        }
11092                    }
11093                    if (wasInLaunchingProviders) {
11094                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11095                    }
11096                    synchronized (dst) {
11097                        dst.provider = src.provider;
11098                        dst.proc = r;
11099                        dst.notifyAll();
11100                    }
11101                    updateOomAdjLocked(r);
11102                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11103                            src.info.authority);
11104                }
11105            }
11106
11107            Binder.restoreCallingIdentity(origId);
11108        }
11109    }
11110
11111    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11112        ContentProviderConnection conn;
11113        try {
11114            conn = (ContentProviderConnection)connection;
11115        } catch (ClassCastException e) {
11116            String msg ="refContentProvider: " + connection
11117                    + " not a ContentProviderConnection";
11118            Slog.w(TAG, msg);
11119            throw new IllegalArgumentException(msg);
11120        }
11121        if (conn == null) {
11122            throw new NullPointerException("connection is null");
11123        }
11124
11125        synchronized (this) {
11126            if (stable > 0) {
11127                conn.numStableIncs += stable;
11128            }
11129            stable = conn.stableCount + stable;
11130            if (stable < 0) {
11131                throw new IllegalStateException("stableCount < 0: " + stable);
11132            }
11133
11134            if (unstable > 0) {
11135                conn.numUnstableIncs += unstable;
11136            }
11137            unstable = conn.unstableCount + unstable;
11138            if (unstable < 0) {
11139                throw new IllegalStateException("unstableCount < 0: " + unstable);
11140            }
11141
11142            if ((stable+unstable) <= 0) {
11143                throw new IllegalStateException("ref counts can't go to zero here: stable="
11144                        + stable + " unstable=" + unstable);
11145            }
11146            conn.stableCount = stable;
11147            conn.unstableCount = unstable;
11148            return !conn.dead;
11149        }
11150    }
11151
11152    public void unstableProviderDied(IBinder connection) {
11153        ContentProviderConnection conn;
11154        try {
11155            conn = (ContentProviderConnection)connection;
11156        } catch (ClassCastException e) {
11157            String msg ="refContentProvider: " + connection
11158                    + " not a ContentProviderConnection";
11159            Slog.w(TAG, msg);
11160            throw new IllegalArgumentException(msg);
11161        }
11162        if (conn == null) {
11163            throw new NullPointerException("connection is null");
11164        }
11165
11166        // Safely retrieve the content provider associated with the connection.
11167        IContentProvider provider;
11168        synchronized (this) {
11169            provider = conn.provider.provider;
11170        }
11171
11172        if (provider == null) {
11173            // Um, yeah, we're way ahead of you.
11174            return;
11175        }
11176
11177        // Make sure the caller is being honest with us.
11178        if (provider.asBinder().pingBinder()) {
11179            // Er, no, still looks good to us.
11180            synchronized (this) {
11181                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11182                        + " says " + conn + " died, but we don't agree");
11183                return;
11184            }
11185        }
11186
11187        // Well look at that!  It's dead!
11188        synchronized (this) {
11189            if (conn.provider.provider != provider) {
11190                // But something changed...  good enough.
11191                return;
11192            }
11193
11194            ProcessRecord proc = conn.provider.proc;
11195            if (proc == null || proc.thread == null) {
11196                // Seems like the process is already cleaned up.
11197                return;
11198            }
11199
11200            // As far as we're concerned, this is just like receiving a
11201            // death notification...  just a bit prematurely.
11202            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11203                    + ") early provider death");
11204            final long ident = Binder.clearCallingIdentity();
11205            try {
11206                appDiedLocked(proc);
11207            } finally {
11208                Binder.restoreCallingIdentity(ident);
11209            }
11210        }
11211    }
11212
11213    @Override
11214    public void appNotRespondingViaProvider(IBinder connection) {
11215        enforceCallingPermission(
11216                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11217
11218        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11219        if (conn == null) {
11220            Slog.w(TAG, "ContentProviderConnection is null");
11221            return;
11222        }
11223
11224        final ProcessRecord host = conn.provider.proc;
11225        if (host == null) {
11226            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11227            return;
11228        }
11229
11230        mHandler.post(new Runnable() {
11231            @Override
11232            public void run() {
11233                mAppErrors.appNotResponding(host, null, null, false,
11234                        "ContentProvider not responding");
11235            }
11236        });
11237    }
11238
11239    public final void installSystemProviders() {
11240        List<ProviderInfo> providers;
11241        synchronized (this) {
11242            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11243            providers = generateApplicationProvidersLocked(app);
11244            if (providers != null) {
11245                for (int i=providers.size()-1; i>=0; i--) {
11246                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11247                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11248                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11249                                + ": not system .apk");
11250                        providers.remove(i);
11251                    }
11252                }
11253            }
11254        }
11255        if (providers != null) {
11256            mSystemThread.installSystemProviders(providers);
11257        }
11258
11259        mCoreSettingsObserver = new CoreSettingsObserver(this);
11260        mFontScaleSettingObserver = new FontScaleSettingObserver();
11261
11262        //mUsageStatsService.monitorPackages();
11263    }
11264
11265    private void startPersistentApps(int matchFlags) {
11266        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11267
11268        synchronized (this) {
11269            try {
11270                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11271                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11272                for (ApplicationInfo app : apps) {
11273                    if (!"android".equals(app.packageName)) {
11274                        addAppLocked(app, false, null /* ABI override */);
11275                    }
11276                }
11277            } catch (RemoteException ex) {
11278            }
11279        }
11280    }
11281
11282    /**
11283     * When a user is unlocked, we need to install encryption-unaware providers
11284     * belonging to any running apps.
11285     */
11286    private void installEncryptionUnawareProviders(int userId) {
11287        // We're only interested in providers that are encryption unaware, and
11288        // we don't care about uninstalled apps, since there's no way they're
11289        // running at this point.
11290        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11291
11292        synchronized (this) {
11293            final int NP = mProcessNames.getMap().size();
11294            for (int ip = 0; ip < NP; ip++) {
11295                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11296                final int NA = apps.size();
11297                for (int ia = 0; ia < NA; ia++) {
11298                    final ProcessRecord app = apps.valueAt(ia);
11299                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11300
11301                    final int NG = app.pkgList.size();
11302                    for (int ig = 0; ig < NG; ig++) {
11303                        try {
11304                            final String pkgName = app.pkgList.keyAt(ig);
11305                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11306                                    .getPackageInfo(pkgName, matchFlags, userId);
11307                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11308                                for (ProviderInfo pi : pkgInfo.providers) {
11309                                    // TODO: keep in sync with generateApplicationProvidersLocked
11310                                    final boolean processMatch = Objects.equals(pi.processName,
11311                                            app.processName) || pi.multiprocess;
11312                                    final boolean userMatch = isSingleton(pi.processName,
11313                                            pi.applicationInfo, pi.name, pi.flags)
11314                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11315                                    if (processMatch && userMatch) {
11316                                        Log.v(TAG, "Installing " + pi);
11317                                        app.thread.scheduleInstallProvider(pi);
11318                                    } else {
11319                                        Log.v(TAG, "Skipping " + pi);
11320                                    }
11321                                }
11322                            }
11323                        } catch (RemoteException ignored) {
11324                        }
11325                    }
11326                }
11327            }
11328        }
11329    }
11330
11331    /**
11332     * Allows apps to retrieve the MIME type of a URI.
11333     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11334     * users, then it does not need permission to access the ContentProvider.
11335     * Either, it needs cross-user uri grants.
11336     *
11337     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11338     *
11339     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11340     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11341     */
11342    public String getProviderMimeType(Uri uri, int userId) {
11343        enforceNotIsolatedCaller("getProviderMimeType");
11344        final String name = uri.getAuthority();
11345        int callingUid = Binder.getCallingUid();
11346        int callingPid = Binder.getCallingPid();
11347        long ident = 0;
11348        boolean clearedIdentity = false;
11349        synchronized (this) {
11350            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11351        }
11352        if (canClearIdentity(callingPid, callingUid, userId)) {
11353            clearedIdentity = true;
11354            ident = Binder.clearCallingIdentity();
11355        }
11356        ContentProviderHolder holder = null;
11357        try {
11358            holder = getContentProviderExternalUnchecked(name, null, userId);
11359            if (holder != null) {
11360                return holder.provider.getType(uri);
11361            }
11362        } catch (RemoteException e) {
11363            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11364            return null;
11365        } catch (Exception e) {
11366            Log.w(TAG, "Exception while determining type of " + uri, e);
11367            return null;
11368        } finally {
11369            // We need to clear the identity to call removeContentProviderExternalUnchecked
11370            if (!clearedIdentity) {
11371                ident = Binder.clearCallingIdentity();
11372            }
11373            try {
11374                if (holder != null) {
11375                    removeContentProviderExternalUnchecked(name, null, userId);
11376                }
11377            } finally {
11378                Binder.restoreCallingIdentity(ident);
11379            }
11380        }
11381
11382        return null;
11383    }
11384
11385    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11386        if (UserHandle.getUserId(callingUid) == userId) {
11387            return true;
11388        }
11389        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11390                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11391                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11392                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11393                return true;
11394        }
11395        return false;
11396    }
11397
11398    // =========================================================
11399    // GLOBAL MANAGEMENT
11400    // =========================================================
11401
11402    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11403            boolean isolated, int isolatedUid) {
11404        String proc = customProcess != null ? customProcess : info.processName;
11405        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11406        final int userId = UserHandle.getUserId(info.uid);
11407        int uid = info.uid;
11408        if (isolated) {
11409            if (isolatedUid == 0) {
11410                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11411                while (true) {
11412                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11413                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11414                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11415                    }
11416                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11417                    mNextIsolatedProcessUid++;
11418                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11419                        // No process for this uid, use it.
11420                        break;
11421                    }
11422                    stepsLeft--;
11423                    if (stepsLeft <= 0) {
11424                        return null;
11425                    }
11426                }
11427            } else {
11428                // Special case for startIsolatedProcess (internal only), where
11429                // the uid of the isolated process is specified by the caller.
11430                uid = isolatedUid;
11431            }
11432
11433            // Register the isolated UID with this application so BatteryStats knows to
11434            // attribute resource usage to the application.
11435            //
11436            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11437            // about the process state of the isolated UID *before* it is registered with the
11438            // owning application.
11439            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11440        }
11441        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11442        if (!mBooted && !mBooting
11443                && userId == UserHandle.USER_SYSTEM
11444                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11445            r.persistent = true;
11446            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11447        }
11448        addProcessNameLocked(r);
11449        return r;
11450    }
11451
11452    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11453            String abiOverride) {
11454        ProcessRecord app;
11455        if (!isolated) {
11456            app = getProcessRecordLocked(info.processName, info.uid, true);
11457        } else {
11458            app = null;
11459        }
11460
11461        if (app == null) {
11462            app = newProcessRecordLocked(info, null, isolated, 0);
11463            updateLruProcessLocked(app, false, null);
11464            updateOomAdjLocked();
11465        }
11466
11467        // This package really, really can not be stopped.
11468        try {
11469            AppGlobals.getPackageManager().setPackageStoppedState(
11470                    info.packageName, false, UserHandle.getUserId(app.uid));
11471        } catch (RemoteException e) {
11472        } catch (IllegalArgumentException e) {
11473            Slog.w(TAG, "Failed trying to unstop package "
11474                    + info.packageName + ": " + e);
11475        }
11476
11477        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11478            app.persistent = true;
11479            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11480        }
11481        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11482            mPersistentStartingProcesses.add(app);
11483            startProcessLocked(app, "added application", app.processName, abiOverride,
11484                    null /* entryPoint */, null /* entryPointArgs */);
11485        }
11486
11487        return app;
11488    }
11489
11490    public void unhandledBack() {
11491        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11492                "unhandledBack()");
11493
11494        synchronized(this) {
11495            final long origId = Binder.clearCallingIdentity();
11496            try {
11497                getFocusedStack().unhandledBackLocked();
11498            } finally {
11499                Binder.restoreCallingIdentity(origId);
11500            }
11501        }
11502    }
11503
11504    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11505        enforceNotIsolatedCaller("openContentUri");
11506        final int userId = UserHandle.getCallingUserId();
11507        String name = uri.getAuthority();
11508        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11509        ParcelFileDescriptor pfd = null;
11510        if (cph != null) {
11511            // We record the binder invoker's uid in thread-local storage before
11512            // going to the content provider to open the file.  Later, in the code
11513            // that handles all permissions checks, we look for this uid and use
11514            // that rather than the Activity Manager's own uid.  The effect is that
11515            // we do the check against the caller's permissions even though it looks
11516            // to the content provider like the Activity Manager itself is making
11517            // the request.
11518            Binder token = new Binder();
11519            sCallerIdentity.set(new Identity(
11520                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11521            try {
11522                pfd = cph.provider.openFile(null, uri, "r", null, token);
11523            } catch (FileNotFoundException e) {
11524                // do nothing; pfd will be returned null
11525            } finally {
11526                // Ensure that whatever happens, we clean up the identity state
11527                sCallerIdentity.remove();
11528                // Ensure we're done with the provider.
11529                removeContentProviderExternalUnchecked(name, null, userId);
11530            }
11531        } else {
11532            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11533        }
11534        return pfd;
11535    }
11536
11537    // Actually is sleeping or shutting down or whatever else in the future
11538    // is an inactive state.
11539    boolean isSleepingOrShuttingDownLocked() {
11540        return isSleepingLocked() || mShuttingDown;
11541    }
11542
11543    boolean isShuttingDownLocked() {
11544        return mShuttingDown;
11545    }
11546
11547    boolean isSleepingLocked() {
11548        return mSleeping;
11549    }
11550
11551    void onWakefulnessChanged(int wakefulness) {
11552        synchronized(this) {
11553            mWakefulness = wakefulness;
11554            updateSleepIfNeededLocked();
11555        }
11556    }
11557
11558    void finishRunningVoiceLocked() {
11559        if (mRunningVoice != null) {
11560            mRunningVoice = null;
11561            mVoiceWakeLock.release();
11562            updateSleepIfNeededLocked();
11563        }
11564    }
11565
11566    void startTimeTrackingFocusedActivityLocked() {
11567        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11568        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11569            mCurAppTimeTracker.start(resumedActivity.packageName);
11570        }
11571    }
11572
11573    void updateSleepIfNeededLocked() {
11574        if (mSleeping && !shouldSleepLocked()) {
11575            mSleeping = false;
11576            startTimeTrackingFocusedActivityLocked();
11577            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11578            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11579            updateOomAdjLocked();
11580        } else if (!mSleeping && shouldSleepLocked()) {
11581            mSleeping = true;
11582            if (mCurAppTimeTracker != null) {
11583                mCurAppTimeTracker.stop();
11584            }
11585            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11586            mStackSupervisor.goingToSleepLocked();
11587            updateOomAdjLocked();
11588
11589            // Initialize the wake times of all processes.
11590            checkExcessivePowerUsageLocked(false);
11591            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11592            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11593            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11594        }
11595    }
11596
11597    private boolean shouldSleepLocked() {
11598        // Resume applications while running a voice interactor.
11599        if (mRunningVoice != null) {
11600            return false;
11601        }
11602
11603        // TODO: Transform the lock screen state into a sleep token instead.
11604        switch (mWakefulness) {
11605            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11606            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11607            case PowerManagerInternal.WAKEFULNESS_DOZING:
11608                // Pause applications whenever the lock screen is shown or any sleep
11609                // tokens have been acquired.
11610                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11611            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11612            default:
11613                // If we're asleep then pause applications unconditionally.
11614                return true;
11615        }
11616    }
11617
11618    /** Pokes the task persister. */
11619    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11620        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11621    }
11622
11623    /** Notifies all listeners when the pinned stack animation ends. */
11624    @Override
11625    public void notifyPinnedStackAnimationEnded() {
11626        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11627    }
11628
11629    @Override
11630    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11631        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11632    }
11633
11634    @Override
11635    public boolean shutdown(int timeout) {
11636        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11637                != PackageManager.PERMISSION_GRANTED) {
11638            throw new SecurityException("Requires permission "
11639                    + android.Manifest.permission.SHUTDOWN);
11640        }
11641
11642        boolean timedout = false;
11643
11644        synchronized(this) {
11645            mShuttingDown = true;
11646            updateEventDispatchingLocked();
11647            timedout = mStackSupervisor.shutdownLocked(timeout);
11648        }
11649
11650        mAppOpsService.shutdown();
11651        if (mUsageStatsService != null) {
11652            mUsageStatsService.prepareShutdown();
11653        }
11654        mBatteryStatsService.shutdown();
11655        synchronized (this) {
11656            mProcessStats.shutdownLocked();
11657            notifyTaskPersisterLocked(null, true);
11658        }
11659
11660        return timedout;
11661    }
11662
11663    public final void activitySlept(IBinder token) {
11664        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11665
11666        final long origId = Binder.clearCallingIdentity();
11667
11668        synchronized (this) {
11669            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11670            if (r != null) {
11671                mStackSupervisor.activitySleptLocked(r);
11672            }
11673        }
11674
11675        Binder.restoreCallingIdentity(origId);
11676    }
11677
11678    private String lockScreenShownToString() {
11679        switch (mLockScreenShown) {
11680            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11681            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11682            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11683            default: return "Unknown=" + mLockScreenShown;
11684        }
11685    }
11686
11687    void logLockScreen(String msg) {
11688        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11689                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11690                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11691                + " mSleeping=" + mSleeping);
11692    }
11693
11694    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11695        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11696        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11697        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11698            boolean wasRunningVoice = mRunningVoice != null;
11699            mRunningVoice = session;
11700            if (!wasRunningVoice) {
11701                mVoiceWakeLock.acquire();
11702                updateSleepIfNeededLocked();
11703            }
11704        }
11705    }
11706
11707    private void updateEventDispatchingLocked() {
11708        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11709    }
11710
11711    public void setLockScreenShown(boolean showing, boolean occluded) {
11712        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11713                != PackageManager.PERMISSION_GRANTED) {
11714            throw new SecurityException("Requires permission "
11715                    + android.Manifest.permission.DEVICE_POWER);
11716        }
11717
11718        synchronized(this) {
11719            long ident = Binder.clearCallingIdentity();
11720            try {
11721                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11722                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11723                if (showing && occluded) {
11724                    // The lock screen is currently showing, but is occluded by a window that can
11725                    // show on top of the lock screen. In this can we want to dismiss the docked
11726                    // stack since it will be complicated/risky to try to put the activity on top
11727                    // of the lock screen in the right fullscreen configuration.
11728                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11729                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11730                }
11731
11732                updateSleepIfNeededLocked();
11733            } finally {
11734                Binder.restoreCallingIdentity(ident);
11735            }
11736        }
11737    }
11738
11739    @Override
11740    public void notifyLockedProfile(@UserIdInt int userId) {
11741        try {
11742            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11743                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11744            }
11745        } catch (RemoteException ex) {
11746            throw new SecurityException("Fail to check is caller a privileged app", ex);
11747        }
11748
11749        synchronized (this) {
11750            if (mStackSupervisor.isUserLockedProfile(userId)) {
11751                final long ident = Binder.clearCallingIdentity();
11752                try {
11753                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11754                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11755                        // If there is no device lock, we will show the profile's credential page.
11756                        mActivityStarter.showConfirmDeviceCredential(userId);
11757                    } else {
11758                        // Showing launcher to avoid user entering credential twice.
11759                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11760                    }
11761                } finally {
11762                    Binder.restoreCallingIdentity(ident);
11763                }
11764            }
11765        }
11766    }
11767
11768    @Override
11769    public void startConfirmDeviceCredentialIntent(Intent intent) {
11770        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11771        synchronized (this) {
11772            final long ident = Binder.clearCallingIdentity();
11773            try {
11774                mActivityStarter.startConfirmCredentialIntent(intent);
11775            } finally {
11776                Binder.restoreCallingIdentity(ident);
11777            }
11778        }
11779    }
11780
11781    @Override
11782    public void stopAppSwitches() {
11783        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11784                != PackageManager.PERMISSION_GRANTED) {
11785            throw new SecurityException("viewquires permission "
11786                    + android.Manifest.permission.STOP_APP_SWITCHES);
11787        }
11788
11789        synchronized(this) {
11790            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11791                    + APP_SWITCH_DELAY_TIME;
11792            mDidAppSwitch = false;
11793            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11794            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11795            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11796        }
11797    }
11798
11799    public void resumeAppSwitches() {
11800        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11801                != PackageManager.PERMISSION_GRANTED) {
11802            throw new SecurityException("Requires permission "
11803                    + android.Manifest.permission.STOP_APP_SWITCHES);
11804        }
11805
11806        synchronized(this) {
11807            // Note that we don't execute any pending app switches... we will
11808            // let those wait until either the timeout, or the next start
11809            // activity request.
11810            mAppSwitchesAllowedTime = 0;
11811        }
11812    }
11813
11814    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11815            int callingPid, int callingUid, String name) {
11816        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11817            return true;
11818        }
11819
11820        int perm = checkComponentPermission(
11821                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11822                sourceUid, -1, true);
11823        if (perm == PackageManager.PERMISSION_GRANTED) {
11824            return true;
11825        }
11826
11827        // If the actual IPC caller is different from the logical source, then
11828        // also see if they are allowed to control app switches.
11829        if (callingUid != -1 && callingUid != sourceUid) {
11830            perm = checkComponentPermission(
11831                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11832                    callingUid, -1, true);
11833            if (perm == PackageManager.PERMISSION_GRANTED) {
11834                return true;
11835            }
11836        }
11837
11838        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11839        return false;
11840    }
11841
11842    public void setDebugApp(String packageName, boolean waitForDebugger,
11843            boolean persistent) {
11844        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11845                "setDebugApp()");
11846
11847        long ident = Binder.clearCallingIdentity();
11848        try {
11849            // Note that this is not really thread safe if there are multiple
11850            // callers into it at the same time, but that's not a situation we
11851            // care about.
11852            if (persistent) {
11853                final ContentResolver resolver = mContext.getContentResolver();
11854                Settings.Global.putString(
11855                    resolver, Settings.Global.DEBUG_APP,
11856                    packageName);
11857                Settings.Global.putInt(
11858                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11859                    waitForDebugger ? 1 : 0);
11860            }
11861
11862            synchronized (this) {
11863                if (!persistent) {
11864                    mOrigDebugApp = mDebugApp;
11865                    mOrigWaitForDebugger = mWaitForDebugger;
11866                }
11867                mDebugApp = packageName;
11868                mWaitForDebugger = waitForDebugger;
11869                mDebugTransient = !persistent;
11870                if (packageName != null) {
11871                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11872                            false, UserHandle.USER_ALL, "set debug app");
11873                }
11874            }
11875        } finally {
11876            Binder.restoreCallingIdentity(ident);
11877        }
11878    }
11879
11880    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11881        synchronized (this) {
11882            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11883            if (!isDebuggable) {
11884                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11885                    throw new SecurityException("Process not debuggable: " + app.packageName);
11886                }
11887            }
11888
11889            mTrackAllocationApp = processName;
11890        }
11891    }
11892
11893    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11894        synchronized (this) {
11895            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11896            if (!isDebuggable) {
11897                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11898                    throw new SecurityException("Process not debuggable: " + app.packageName);
11899                }
11900            }
11901            mProfileApp = processName;
11902            mProfileFile = profilerInfo.profileFile;
11903            if (mProfileFd != null) {
11904                try {
11905                    mProfileFd.close();
11906                } catch (IOException e) {
11907                }
11908                mProfileFd = null;
11909            }
11910            mProfileFd = profilerInfo.profileFd;
11911            mSamplingInterval = profilerInfo.samplingInterval;
11912            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11913            mProfileType = 0;
11914        }
11915    }
11916
11917    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11918        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11919        if (!isDebuggable) {
11920            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11921                throw new SecurityException("Process not debuggable: " + app.packageName);
11922            }
11923        }
11924        mNativeDebuggingApp = processName;
11925    }
11926
11927    @Override
11928    public void setAlwaysFinish(boolean enabled) {
11929        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11930                "setAlwaysFinish()");
11931
11932        long ident = Binder.clearCallingIdentity();
11933        try {
11934            Settings.Global.putInt(
11935                    mContext.getContentResolver(),
11936                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11937
11938            synchronized (this) {
11939                mAlwaysFinishActivities = enabled;
11940            }
11941        } finally {
11942            Binder.restoreCallingIdentity(ident);
11943        }
11944    }
11945
11946    @Override
11947    public void setLenientBackgroundCheck(boolean enabled) {
11948        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11949                "setLenientBackgroundCheck()");
11950
11951        long ident = Binder.clearCallingIdentity();
11952        try {
11953            Settings.Global.putInt(
11954                    mContext.getContentResolver(),
11955                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11956
11957            synchronized (this) {
11958                mLenientBackgroundCheck = enabled;
11959            }
11960        } finally {
11961            Binder.restoreCallingIdentity(ident);
11962        }
11963    }
11964
11965    @Override
11966    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11967        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11968                "setActivityController()");
11969        synchronized (this) {
11970            mController = controller;
11971            mControllerIsAMonkey = imAMonkey;
11972            Watchdog.getInstance().setActivityController(controller);
11973        }
11974    }
11975
11976    @Override
11977    public void setUserIsMonkey(boolean userIsMonkey) {
11978        synchronized (this) {
11979            synchronized (mPidsSelfLocked) {
11980                final int callingPid = Binder.getCallingPid();
11981                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11982                if (precessRecord == null) {
11983                    throw new SecurityException("Unknown process: " + callingPid);
11984                }
11985                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11986                    throw new SecurityException("Only an instrumentation process "
11987                            + "with a UiAutomation can call setUserIsMonkey");
11988                }
11989            }
11990            mUserIsMonkey = userIsMonkey;
11991        }
11992    }
11993
11994    @Override
11995    public boolean isUserAMonkey() {
11996        synchronized (this) {
11997            // If there is a controller also implies the user is a monkey.
11998            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11999        }
12000    }
12001
12002    public void requestBugReport(int bugreportType) {
12003        String extraOptions = null;
12004        switch (bugreportType) {
12005            case ActivityManager.BUGREPORT_OPTION_FULL:
12006                // Default options.
12007                break;
12008            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12009                extraOptions = "bugreportplus";
12010                break;
12011            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12012                extraOptions = "bugreportremote";
12013                break;
12014            case ActivityManager.BUGREPORT_OPTION_WEAR:
12015                extraOptions = "bugreportwear";
12016                break;
12017            default:
12018                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12019                        + bugreportType);
12020        }
12021        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12022        if (extraOptions != null) {
12023            SystemProperties.set("dumpstate.options", extraOptions);
12024        }
12025        SystemProperties.set("ctl.start", "bugreport");
12026    }
12027
12028    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12029        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12030    }
12031
12032    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12033        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12034            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12035        }
12036        return KEY_DISPATCHING_TIMEOUT;
12037    }
12038
12039    @Override
12040    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12041        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12042                != PackageManager.PERMISSION_GRANTED) {
12043            throw new SecurityException("Requires permission "
12044                    + android.Manifest.permission.FILTER_EVENTS);
12045        }
12046        ProcessRecord proc;
12047        long timeout;
12048        synchronized (this) {
12049            synchronized (mPidsSelfLocked) {
12050                proc = mPidsSelfLocked.get(pid);
12051            }
12052            timeout = getInputDispatchingTimeoutLocked(proc);
12053        }
12054
12055        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12056            return -1;
12057        }
12058
12059        return timeout;
12060    }
12061
12062    /**
12063     * Handle input dispatching timeouts.
12064     * Returns whether input dispatching should be aborted or not.
12065     */
12066    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12067            final ActivityRecord activity, final ActivityRecord parent,
12068            final boolean aboveSystem, String reason) {
12069        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12070                != PackageManager.PERMISSION_GRANTED) {
12071            throw new SecurityException("Requires permission "
12072                    + android.Manifest.permission.FILTER_EVENTS);
12073        }
12074
12075        final String annotation;
12076        if (reason == null) {
12077            annotation = "Input dispatching timed out";
12078        } else {
12079            annotation = "Input dispatching timed out (" + reason + ")";
12080        }
12081
12082        if (proc != null) {
12083            synchronized (this) {
12084                if (proc.debugging) {
12085                    return false;
12086                }
12087
12088                if (mDidDexOpt) {
12089                    // Give more time since we were dexopting.
12090                    mDidDexOpt = false;
12091                    return false;
12092                }
12093
12094                if (proc.instrumentationClass != null) {
12095                    Bundle info = new Bundle();
12096                    info.putString("shortMsg", "keyDispatchingTimedOut");
12097                    info.putString("longMsg", annotation);
12098                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12099                    return true;
12100                }
12101            }
12102            mHandler.post(new Runnable() {
12103                @Override
12104                public void run() {
12105                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12106                }
12107            });
12108        }
12109
12110        return true;
12111    }
12112
12113    @Override
12114    public Bundle getAssistContextExtras(int requestType) {
12115        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12116                null, null, true /* focused */, true /* newSessionId */,
12117                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12118        if (pae == null) {
12119            return null;
12120        }
12121        synchronized (pae) {
12122            while (!pae.haveResult) {
12123                try {
12124                    pae.wait();
12125                } catch (InterruptedException e) {
12126                }
12127            }
12128        }
12129        synchronized (this) {
12130            buildAssistBundleLocked(pae, pae.result);
12131            mPendingAssistExtras.remove(pae);
12132            mUiHandler.removeCallbacks(pae);
12133        }
12134        return pae.extras;
12135    }
12136
12137    @Override
12138    public boolean isAssistDataAllowedOnCurrentActivity() {
12139        int userId;
12140        synchronized (this) {
12141            userId = mUserController.getCurrentUserIdLocked();
12142            ActivityRecord activity = getFocusedStack().topActivity();
12143            if (activity == null) {
12144                return false;
12145            }
12146            userId = activity.userId;
12147        }
12148        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12149                Context.DEVICE_POLICY_SERVICE);
12150        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12151    }
12152
12153    @Override
12154    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12155        long ident = Binder.clearCallingIdentity();
12156        try {
12157            synchronized (this) {
12158                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12159                ActivityRecord top = getFocusedStack().topActivity();
12160                if (top != caller) {
12161                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12162                            + " is not current top " + top);
12163                    return false;
12164                }
12165                if (!top.nowVisible) {
12166                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12167                            + " is not visible");
12168                    return false;
12169                }
12170            }
12171            AssistUtils utils = new AssistUtils(mContext);
12172            return utils.showSessionForActiveService(args,
12173                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12174        } finally {
12175            Binder.restoreCallingIdentity(ident);
12176        }
12177    }
12178
12179    @Override
12180    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12181            Bundle receiverExtras,
12182            IBinder activityToken, boolean focused, boolean newSessionId) {
12183        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12184                activityToken, focused, newSessionId,
12185                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12186                != null;
12187    }
12188
12189    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12190            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12191            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12192        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12193                "enqueueAssistContext()");
12194        synchronized (this) {
12195            ActivityRecord activity = getFocusedStack().topActivity();
12196            if (activity == null) {
12197                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12198                return null;
12199            }
12200            if (activity.app == null || activity.app.thread == null) {
12201                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12202                return null;
12203            }
12204            if (focused) {
12205                if (activityToken != null) {
12206                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12207                    if (activity != caller) {
12208                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12209                                + " is not current top " + activity);
12210                        return null;
12211                    }
12212                }
12213            } else {
12214                activity = ActivityRecord.forTokenLocked(activityToken);
12215                if (activity == null) {
12216                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12217                            + " couldn't be found");
12218                    return null;
12219                }
12220            }
12221
12222            PendingAssistExtras pae;
12223            Bundle extras = new Bundle();
12224            if (args != null) {
12225                extras.putAll(args);
12226            }
12227            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12228            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12229            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12230                    userHandle);
12231            // Increment the sessionId if necessary
12232            if (newSessionId) {
12233                mViSessionId++;
12234            }
12235            try {
12236                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12237                        requestType, mViSessionId);
12238                mPendingAssistExtras.add(pae);
12239                mUiHandler.postDelayed(pae, timeout);
12240            } catch (RemoteException e) {
12241                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12242                return null;
12243            }
12244            return pae;
12245        }
12246    }
12247
12248    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12249        IResultReceiver receiver;
12250        synchronized (this) {
12251            mPendingAssistExtras.remove(pae);
12252            receiver = pae.receiver;
12253        }
12254        if (receiver != null) {
12255            // Caller wants result sent back to them.
12256            Bundle sendBundle = new Bundle();
12257            // At least return the receiver extras
12258            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12259                    pae.receiverExtras);
12260            try {
12261                pae.receiver.send(0, sendBundle);
12262            } catch (RemoteException e) {
12263            }
12264        }
12265    }
12266
12267    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12268        if (result != null) {
12269            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12270        }
12271        if (pae.hint != null) {
12272            pae.extras.putBoolean(pae.hint, true);
12273        }
12274    }
12275
12276    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12277            AssistContent content, Uri referrer) {
12278        PendingAssistExtras pae = (PendingAssistExtras)token;
12279        synchronized (pae) {
12280            pae.result = extras;
12281            pae.structure = structure;
12282            pae.content = content;
12283            if (referrer != null) {
12284                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12285            }
12286            pae.haveResult = true;
12287            pae.notifyAll();
12288            if (pae.intent == null && pae.receiver == null) {
12289                // Caller is just waiting for the result.
12290                return;
12291            }
12292        }
12293
12294        // We are now ready to launch the assist activity.
12295        IResultReceiver sendReceiver = null;
12296        Bundle sendBundle = null;
12297        synchronized (this) {
12298            buildAssistBundleLocked(pae, extras);
12299            boolean exists = mPendingAssistExtras.remove(pae);
12300            mUiHandler.removeCallbacks(pae);
12301            if (!exists) {
12302                // Timed out.
12303                return;
12304            }
12305            if ((sendReceiver=pae.receiver) != null) {
12306                // Caller wants result sent back to them.
12307                sendBundle = new Bundle();
12308                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12309                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12310                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12311                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12312                        pae.receiverExtras);
12313            }
12314        }
12315        if (sendReceiver != null) {
12316            try {
12317                sendReceiver.send(0, sendBundle);
12318            } catch (RemoteException e) {
12319            }
12320            return;
12321        }
12322
12323        long ident = Binder.clearCallingIdentity();
12324        try {
12325            pae.intent.replaceExtras(pae.extras);
12326            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12327                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12328                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12329            closeSystemDialogs("assist");
12330            try {
12331                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12332            } catch (ActivityNotFoundException e) {
12333                Slog.w(TAG, "No activity to handle assist action.", e);
12334            }
12335        } finally {
12336            Binder.restoreCallingIdentity(ident);
12337        }
12338    }
12339
12340    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12341            Bundle args) {
12342        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12343                true /* focused */, true /* newSessionId */,
12344                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12345    }
12346
12347    public void registerProcessObserver(IProcessObserver observer) {
12348        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12349                "registerProcessObserver()");
12350        synchronized (this) {
12351            mProcessObservers.register(observer);
12352        }
12353    }
12354
12355    @Override
12356    public void unregisterProcessObserver(IProcessObserver observer) {
12357        synchronized (this) {
12358            mProcessObservers.unregister(observer);
12359        }
12360    }
12361
12362    @Override
12363    public void registerUidObserver(IUidObserver observer, int which) {
12364        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12365                "registerUidObserver()");
12366        synchronized (this) {
12367            mUidObservers.register(observer, which);
12368        }
12369    }
12370
12371    @Override
12372    public void unregisterUidObserver(IUidObserver observer) {
12373        synchronized (this) {
12374            mUidObservers.unregister(observer);
12375        }
12376    }
12377
12378    @Override
12379    public boolean convertFromTranslucent(IBinder token) {
12380        final long origId = Binder.clearCallingIdentity();
12381        try {
12382            synchronized (this) {
12383                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12384                if (r == null) {
12385                    return false;
12386                }
12387                final boolean translucentChanged = r.changeWindowTranslucency(true);
12388                if (translucentChanged) {
12389                    r.getStack().releaseBackgroundResources(r);
12390                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12391                }
12392                mWindowManager.setAppFullscreen(token, true);
12393                return translucentChanged;
12394            }
12395        } finally {
12396            Binder.restoreCallingIdentity(origId);
12397        }
12398    }
12399
12400    @Override
12401    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12402        final long origId = Binder.clearCallingIdentity();
12403        try {
12404            synchronized (this) {
12405                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12406                if (r == null) {
12407                    return false;
12408                }
12409                int index = r.task.mActivities.lastIndexOf(r);
12410                if (index > 0) {
12411                    ActivityRecord under = r.task.mActivities.get(index - 1);
12412                    under.returningOptions = options;
12413                }
12414                final boolean translucentChanged = r.changeWindowTranslucency(false);
12415                if (translucentChanged) {
12416                    r.getStack().convertActivityToTranslucent(r);
12417                }
12418                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12419                mWindowManager.setAppFullscreen(token, false);
12420                return translucentChanged;
12421            }
12422        } finally {
12423            Binder.restoreCallingIdentity(origId);
12424        }
12425    }
12426
12427    @Override
12428    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12429        final long origId = Binder.clearCallingIdentity();
12430        try {
12431            synchronized (this) {
12432                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12433                if (r != null) {
12434                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12435                }
12436            }
12437            return false;
12438        } finally {
12439            Binder.restoreCallingIdentity(origId);
12440        }
12441    }
12442
12443    @Override
12444    public boolean isBackgroundVisibleBehind(IBinder token) {
12445        final long origId = Binder.clearCallingIdentity();
12446        try {
12447            synchronized (this) {
12448                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12449                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12450                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12451                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12452                return visible;
12453            }
12454        } finally {
12455            Binder.restoreCallingIdentity(origId);
12456        }
12457    }
12458
12459    @Override
12460    public ActivityOptions getActivityOptions(IBinder token) {
12461        final long origId = Binder.clearCallingIdentity();
12462        try {
12463            synchronized (this) {
12464                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12465                if (r != null) {
12466                    final ActivityOptions activityOptions = r.pendingOptions;
12467                    r.pendingOptions = null;
12468                    return activityOptions;
12469                }
12470                return null;
12471            }
12472        } finally {
12473            Binder.restoreCallingIdentity(origId);
12474        }
12475    }
12476
12477    @Override
12478    public void setImmersive(IBinder token, boolean immersive) {
12479        synchronized(this) {
12480            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12481            if (r == null) {
12482                throw new IllegalArgumentException();
12483            }
12484            r.immersive = immersive;
12485
12486            // update associated state if we're frontmost
12487            if (r == mStackSupervisor.getResumedActivityLocked()) {
12488                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12489                applyUpdateLockStateLocked(r);
12490            }
12491        }
12492    }
12493
12494    @Override
12495    public boolean isImmersive(IBinder token) {
12496        synchronized (this) {
12497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12498            if (r == null) {
12499                throw new IllegalArgumentException();
12500            }
12501            return r.immersive;
12502        }
12503    }
12504
12505    public void setVrThread(int tid) {
12506        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12507            throw new UnsupportedOperationException("VR mode not supported on this device!");
12508        }
12509
12510        synchronized (this) {
12511            ProcessRecord proc;
12512            synchronized (mPidsSelfLocked) {
12513                final int pid = Binder.getCallingPid();
12514                proc = mPidsSelfLocked.get(pid);
12515
12516                if (proc != null && mInVrMode && tid >= 0) {
12517                    // ensure the tid belongs to the process
12518                    if (!Process.isThreadInProcess(pid, tid)) {
12519                        throw new IllegalArgumentException("VR thread does not belong to process");
12520                    }
12521
12522                    // reset existing VR thread to CFS if this thread still exists and belongs to
12523                    // the calling process
12524                    if (proc.vrThreadTid != 0
12525                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12526                        try {
12527                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12528                        } catch (IllegalArgumentException e) {
12529                            // Ignore this.  Only occurs in race condition where previous VR thread
12530                            // was destroyed during this method call.
12531                        }
12532                    }
12533
12534                    proc.vrThreadTid = tid;
12535
12536                    // promote to FIFO now if the tid is non-zero
12537                    try {
12538                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12539                            proc.vrThreadTid > 0) {
12540                            Process.setThreadScheduler(proc.vrThreadTid,
12541                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12542                        }
12543                    } catch (IllegalArgumentException e) {
12544                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12545                               + " not exist:\n" + e);
12546                    }
12547                }
12548            }
12549        }
12550    }
12551
12552    @Override
12553    public void setRenderThread(int tid) {
12554        synchronized (this) {
12555            ProcessRecord proc;
12556            synchronized (mPidsSelfLocked) {
12557                int pid = Binder.getCallingPid();
12558                proc = mPidsSelfLocked.get(pid);
12559                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12560                    // ensure the tid belongs to the process
12561                    if (!Process.isThreadInProcess(pid, tid)) {
12562                        throw new IllegalArgumentException(
12563                            "Render thread does not belong to process");
12564                    }
12565                    proc.renderThreadTid = tid;
12566                    if (DEBUG_OOM_ADJ) {
12567                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12568                    }
12569                    // promote to FIFO now
12570                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12571                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12572                        if (mUseFifoUiScheduling) {
12573                            Process.setThreadScheduler(proc.renderThreadTid,
12574                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12575                        } else {
12576                            Process.setThreadPriority(proc.renderThreadTid, -10);
12577                        }
12578                    }
12579                } else {
12580                    if (DEBUG_OOM_ADJ) {
12581                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12582                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12583                               mUseFifoUiScheduling);
12584                    }
12585                }
12586            }
12587        }
12588    }
12589
12590    @Override
12591    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12592        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12593            throw new UnsupportedOperationException("VR mode not supported on this device!");
12594        }
12595
12596        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12597
12598        ActivityRecord r;
12599        synchronized (this) {
12600            r = ActivityRecord.isInStackLocked(token);
12601        }
12602
12603        if (r == null) {
12604            throw new IllegalArgumentException();
12605        }
12606
12607        int err;
12608        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12609                VrManagerInternal.NO_ERROR) {
12610            return err;
12611        }
12612
12613        synchronized(this) {
12614            r.requestedVrComponent = (enabled) ? packageName : null;
12615
12616            // Update associated state if this activity is currently focused
12617            if (r == mStackSupervisor.getResumedActivityLocked()) {
12618                applyUpdateVrModeLocked(r);
12619            }
12620            return 0;
12621        }
12622    }
12623
12624    @Override
12625    public boolean isVrModePackageEnabled(ComponentName packageName) {
12626        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12627            throw new UnsupportedOperationException("VR mode not supported on this device!");
12628        }
12629
12630        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12631
12632        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12633                VrManagerInternal.NO_ERROR;
12634    }
12635
12636    public boolean isTopActivityImmersive() {
12637        enforceNotIsolatedCaller("startActivity");
12638        synchronized (this) {
12639            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12640            return (r != null) ? r.immersive : false;
12641        }
12642    }
12643
12644    @Override
12645    public boolean isTopOfTask(IBinder token) {
12646        synchronized (this) {
12647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12648            if (r == null) {
12649                throw new IllegalArgumentException();
12650            }
12651            return r.task.getTopActivity() == r;
12652        }
12653    }
12654
12655    @Override
12656    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12657        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12658            String msg = "Permission Denial: setHasTopUi() from pid="
12659                    + Binder.getCallingPid()
12660                    + ", uid=" + Binder.getCallingUid()
12661                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12662            Slog.w(TAG, msg);
12663            throw new SecurityException(msg);
12664        }
12665        final int pid = Binder.getCallingPid();
12666        final long origId = Binder.clearCallingIdentity();
12667        try {
12668            synchronized (this) {
12669                boolean changed = false;
12670                ProcessRecord pr;
12671                synchronized (mPidsSelfLocked) {
12672                    pr = mPidsSelfLocked.get(pid);
12673                    if (pr == null) {
12674                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12675                        return;
12676                    }
12677                    if (pr.hasTopUi != hasTopUi) {
12678                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12679                        pr.hasTopUi = hasTopUi;
12680                        changed = true;
12681                    }
12682                }
12683                if (changed) {
12684                    updateOomAdjLocked(pr);
12685                }
12686            }
12687        } finally {
12688            Binder.restoreCallingIdentity(origId);
12689        }
12690    }
12691
12692    public final void enterSafeMode() {
12693        synchronized(this) {
12694            // It only makes sense to do this before the system is ready
12695            // and started launching other packages.
12696            if (!mSystemReady) {
12697                try {
12698                    AppGlobals.getPackageManager().enterSafeMode();
12699                } catch (RemoteException e) {
12700                }
12701            }
12702
12703            mSafeMode = true;
12704        }
12705    }
12706
12707    public final void showSafeModeOverlay() {
12708        View v = LayoutInflater.from(mContext).inflate(
12709                com.android.internal.R.layout.safe_mode, null);
12710        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12711        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12712        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12713        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12714        lp.gravity = Gravity.BOTTOM | Gravity.START;
12715        lp.format = v.getBackground().getOpacity();
12716        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12717                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12718        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12719        ((WindowManager)mContext.getSystemService(
12720                Context.WINDOW_SERVICE)).addView(v, lp);
12721    }
12722
12723    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12724        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12725            return;
12726        }
12727        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12728        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12729        synchronized (stats) {
12730            if (mBatteryStatsService.isOnBattery()) {
12731                mBatteryStatsService.enforceCallingPermission();
12732                int MY_UID = Binder.getCallingUid();
12733                final int uid;
12734                if (sender == null) {
12735                    uid = sourceUid;
12736                } else {
12737                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12738                }
12739                BatteryStatsImpl.Uid.Pkg pkg =
12740                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12741                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12742                pkg.noteWakeupAlarmLocked(tag);
12743            }
12744        }
12745    }
12746
12747    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12748        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12749            return;
12750        }
12751        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12752        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12753        synchronized (stats) {
12754            mBatteryStatsService.enforceCallingPermission();
12755            int MY_UID = Binder.getCallingUid();
12756            final int uid;
12757            if (sender == null) {
12758                uid = sourceUid;
12759            } else {
12760                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12761            }
12762            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12763        }
12764    }
12765
12766    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12767        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12768            return;
12769        }
12770        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12771        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12772        synchronized (stats) {
12773            mBatteryStatsService.enforceCallingPermission();
12774            int MY_UID = Binder.getCallingUid();
12775            final int uid;
12776            if (sender == null) {
12777                uid = sourceUid;
12778            } else {
12779                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12780            }
12781            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12782        }
12783    }
12784
12785    public boolean killPids(int[] pids, String pReason, boolean secure) {
12786        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12787            throw new SecurityException("killPids only available to the system");
12788        }
12789        String reason = (pReason == null) ? "Unknown" : pReason;
12790        // XXX Note: don't acquire main activity lock here, because the window
12791        // manager calls in with its locks held.
12792
12793        boolean killed = false;
12794        synchronized (mPidsSelfLocked) {
12795            int worstType = 0;
12796            for (int i=0; i<pids.length; i++) {
12797                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12798                if (proc != null) {
12799                    int type = proc.setAdj;
12800                    if (type > worstType) {
12801                        worstType = type;
12802                    }
12803                }
12804            }
12805
12806            // If the worst oom_adj is somewhere in the cached proc LRU range,
12807            // then constrain it so we will kill all cached procs.
12808            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12809                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12810                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12811            }
12812
12813            // If this is not a secure call, don't let it kill processes that
12814            // are important.
12815            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12816                worstType = ProcessList.SERVICE_ADJ;
12817            }
12818
12819            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12820            for (int i=0; i<pids.length; i++) {
12821                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12822                if (proc == null) {
12823                    continue;
12824                }
12825                int adj = proc.setAdj;
12826                if (adj >= worstType && !proc.killedByAm) {
12827                    proc.kill(reason, true);
12828                    killed = true;
12829                }
12830            }
12831        }
12832        return killed;
12833    }
12834
12835    @Override
12836    public void killUid(int appId, int userId, String reason) {
12837        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12838        synchronized (this) {
12839            final long identity = Binder.clearCallingIdentity();
12840            try {
12841                killPackageProcessesLocked(null, appId, userId,
12842                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12843                        reason != null ? reason : "kill uid");
12844            } finally {
12845                Binder.restoreCallingIdentity(identity);
12846            }
12847        }
12848    }
12849
12850    @Override
12851    public boolean killProcessesBelowForeground(String reason) {
12852        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12853            throw new SecurityException("killProcessesBelowForeground() only available to system");
12854        }
12855
12856        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12857    }
12858
12859    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12860        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12861            throw new SecurityException("killProcessesBelowAdj() only available to system");
12862        }
12863
12864        boolean killed = false;
12865        synchronized (mPidsSelfLocked) {
12866            final int size = mPidsSelfLocked.size();
12867            for (int i = 0; i < size; i++) {
12868                final int pid = mPidsSelfLocked.keyAt(i);
12869                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12870                if (proc == null) continue;
12871
12872                final int adj = proc.setAdj;
12873                if (adj > belowAdj && !proc.killedByAm) {
12874                    proc.kill(reason, true);
12875                    killed = true;
12876                }
12877            }
12878        }
12879        return killed;
12880    }
12881
12882    @Override
12883    public void hang(final IBinder who, boolean allowRestart) {
12884        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12885                != PackageManager.PERMISSION_GRANTED) {
12886            throw new SecurityException("Requires permission "
12887                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12888        }
12889
12890        final IBinder.DeathRecipient death = new DeathRecipient() {
12891            @Override
12892            public void binderDied() {
12893                synchronized (this) {
12894                    notifyAll();
12895                }
12896            }
12897        };
12898
12899        try {
12900            who.linkToDeath(death, 0);
12901        } catch (RemoteException e) {
12902            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12903            return;
12904        }
12905
12906        synchronized (this) {
12907            Watchdog.getInstance().setAllowRestart(allowRestart);
12908            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12909            synchronized (death) {
12910                while (who.isBinderAlive()) {
12911                    try {
12912                        death.wait();
12913                    } catch (InterruptedException e) {
12914                    }
12915                }
12916            }
12917            Watchdog.getInstance().setAllowRestart(true);
12918        }
12919    }
12920
12921    @Override
12922    public void restart() {
12923        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12924                != PackageManager.PERMISSION_GRANTED) {
12925            throw new SecurityException("Requires permission "
12926                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12927        }
12928
12929        Log.i(TAG, "Sending shutdown broadcast...");
12930
12931        BroadcastReceiver br = new BroadcastReceiver() {
12932            @Override public void onReceive(Context context, Intent intent) {
12933                // Now the broadcast is done, finish up the low-level shutdown.
12934                Log.i(TAG, "Shutting down activity manager...");
12935                shutdown(10000);
12936                Log.i(TAG, "Shutdown complete, restarting!");
12937                Process.killProcess(Process.myPid());
12938                System.exit(10);
12939            }
12940        };
12941
12942        // First send the high-level shut down broadcast.
12943        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12944        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12945        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12946        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12947        mContext.sendOrderedBroadcastAsUser(intent,
12948                UserHandle.ALL, null, br, mHandler, 0, null, null);
12949        */
12950        br.onReceive(mContext, intent);
12951    }
12952
12953    private long getLowRamTimeSinceIdle(long now) {
12954        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12955    }
12956
12957    @Override
12958    public void performIdleMaintenance() {
12959        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12960                != PackageManager.PERMISSION_GRANTED) {
12961            throw new SecurityException("Requires permission "
12962                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12963        }
12964
12965        synchronized (this) {
12966            final long now = SystemClock.uptimeMillis();
12967            final long timeSinceLastIdle = now - mLastIdleTime;
12968            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12969            mLastIdleTime = now;
12970            mLowRamTimeSinceLastIdle = 0;
12971            if (mLowRamStartTime != 0) {
12972                mLowRamStartTime = now;
12973            }
12974
12975            StringBuilder sb = new StringBuilder(128);
12976            sb.append("Idle maintenance over ");
12977            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12978            sb.append(" low RAM for ");
12979            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12980            Slog.i(TAG, sb.toString());
12981
12982            // If at least 1/3 of our time since the last idle period has been spent
12983            // with RAM low, then we want to kill processes.
12984            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12985
12986            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12987                ProcessRecord proc = mLruProcesses.get(i);
12988                if (proc.notCachedSinceIdle) {
12989                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12990                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12991                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12992                        if (doKilling && proc.initialIdlePss != 0
12993                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12994                            sb = new StringBuilder(128);
12995                            sb.append("Kill");
12996                            sb.append(proc.processName);
12997                            sb.append(" in idle maint: pss=");
12998                            sb.append(proc.lastPss);
12999                            sb.append(", swapPss=");
13000                            sb.append(proc.lastSwapPss);
13001                            sb.append(", initialPss=");
13002                            sb.append(proc.initialIdlePss);
13003                            sb.append(", period=");
13004                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13005                            sb.append(", lowRamPeriod=");
13006                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13007                            Slog.wtfQuiet(TAG, sb.toString());
13008                            proc.kill("idle maint (pss " + proc.lastPss
13009                                    + " from " + proc.initialIdlePss + ")", true);
13010                        }
13011                    }
13012                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13013                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13014                    proc.notCachedSinceIdle = true;
13015                    proc.initialIdlePss = 0;
13016                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13017                            mTestPssMode, isSleepingLocked(), now);
13018                }
13019            }
13020
13021            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13022            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13023        }
13024    }
13025
13026    @Override
13027    public void sendIdleJobTrigger() {
13028        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13029                != PackageManager.PERMISSION_GRANTED) {
13030            throw new SecurityException("Requires permission "
13031                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13032        }
13033
13034        final long ident = Binder.clearCallingIdentity();
13035        try {
13036            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13037                    .setPackage("android")
13038                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13039            broadcastIntent(null, intent, null, null, 0, null, null, null,
13040                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13041        } finally {
13042            Binder.restoreCallingIdentity(ident);
13043        }
13044    }
13045
13046    private void retrieveSettings() {
13047        final ContentResolver resolver = mContext.getContentResolver();
13048        final boolean freeformWindowManagement =
13049                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13050                        || Settings.Global.getInt(
13051                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13052        final boolean supportsPictureInPicture =
13053                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13054
13055        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13056        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13057        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13058        final boolean alwaysFinishActivities =
13059                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13060        final boolean lenientBackgroundCheck =
13061                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13062        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13063        final boolean forceResizable = Settings.Global.getInt(
13064                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13065        final boolean supportsLeanbackOnly =
13066                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13067
13068        // Transfer any global setting for forcing RTL layout, into a System Property
13069        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13070
13071        final Configuration configuration = new Configuration();
13072        Settings.System.getConfiguration(resolver, configuration);
13073        if (forceRtl) {
13074            // This will take care of setting the correct layout direction flags
13075            configuration.setLayoutDirection(configuration.locale);
13076        }
13077
13078        synchronized (this) {
13079            mDebugApp = mOrigDebugApp = debugApp;
13080            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13081            mAlwaysFinishActivities = alwaysFinishActivities;
13082            mLenientBackgroundCheck = lenientBackgroundCheck;
13083            mSupportsLeanbackOnly = supportsLeanbackOnly;
13084            mForceResizableActivities = forceResizable;
13085            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13086            if (supportsMultiWindow || forceResizable) {
13087                mSupportsMultiWindow = true;
13088                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13089                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13090            } else {
13091                mSupportsMultiWindow = false;
13092                mSupportsFreeformWindowManagement = false;
13093                mSupportsPictureInPicture = false;
13094            }
13095            // This happens before any activities are started, so we can change global configuration
13096            // in-place.
13097            updateConfigurationLocked(configuration, null, true);
13098            final Configuration globalConfig = getGlobalConfiguration();
13099            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13100
13101            // Load resources only after the current configuration has been set.
13102            final Resources res = mContext.getResources();
13103            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13104            mThumbnailWidth = res.getDimensionPixelSize(
13105                    com.android.internal.R.dimen.thumbnail_width);
13106            mThumbnailHeight = res.getDimensionPixelSize(
13107                    com.android.internal.R.dimen.thumbnail_height);
13108            mDefaultPinnedStackSizeDp = Size.parseSize(res.getString(
13109                    com.android.internal.R.string.config_defaultPictureInPictureSize));
13110            mDefaultPinnedStackScreenEdgeInsetsDp = Size.parseSize(res.getString(
13111                    com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets));
13112            mDefaultPinnedStackGravity = res.getInteger(
13113                    com.android.internal.R.integer.config_defaultPictureInPictureGravity);
13114            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13115                    com.android.internal.R.string.config_appsNotReportingCrashes));
13116            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13117                    com.android.internal.R.bool.config_customUserSwitchUi);
13118            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13119                mFullscreenThumbnailScale = (float) res
13120                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13121                    (float) globalConfig.screenWidthDp;
13122            } else {
13123                mFullscreenThumbnailScale = res.getFraction(
13124                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13125            }
13126        }
13127    }
13128
13129    public boolean testIsSystemReady() {
13130        // no need to synchronize(this) just to read & return the value
13131        return mSystemReady;
13132    }
13133
13134    public void systemReady(final Runnable goingCallback) {
13135        synchronized(this) {
13136            if (mSystemReady) {
13137                // If we're done calling all the receivers, run the next "boot phase" passed in
13138                // by the SystemServer
13139                if (goingCallback != null) {
13140                    goingCallback.run();
13141                }
13142                return;
13143            }
13144
13145            mLocalDeviceIdleController
13146                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13147
13148            // Make sure we have the current profile info, since it is needed for security checks.
13149            mUserController.onSystemReady();
13150            mRecentTasks.onSystemReadyLocked();
13151            mAppOpsService.systemReady();
13152            mSystemReady = true;
13153        }
13154
13155        ArrayList<ProcessRecord> procsToKill = null;
13156        synchronized(mPidsSelfLocked) {
13157            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13158                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13159                if (!isAllowedWhileBooting(proc.info)){
13160                    if (procsToKill == null) {
13161                        procsToKill = new ArrayList<ProcessRecord>();
13162                    }
13163                    procsToKill.add(proc);
13164                }
13165            }
13166        }
13167
13168        synchronized(this) {
13169            if (procsToKill != null) {
13170                for (int i=procsToKill.size()-1; i>=0; i--) {
13171                    ProcessRecord proc = procsToKill.get(i);
13172                    Slog.i(TAG, "Removing system update proc: " + proc);
13173                    removeProcessLocked(proc, true, false, "system update done");
13174                }
13175            }
13176
13177            // Now that we have cleaned up any update processes, we
13178            // are ready to start launching real processes and know that
13179            // we won't trample on them any more.
13180            mProcessesReady = true;
13181        }
13182
13183        Slog.i(TAG, "System now ready");
13184        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13185            SystemClock.uptimeMillis());
13186
13187        synchronized(this) {
13188            // Make sure we have no pre-ready processes sitting around.
13189
13190            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13191                ResolveInfo ri = mContext.getPackageManager()
13192                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13193                                STOCK_PM_FLAGS);
13194                CharSequence errorMsg = null;
13195                if (ri != null) {
13196                    ActivityInfo ai = ri.activityInfo;
13197                    ApplicationInfo app = ai.applicationInfo;
13198                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13199                        mTopAction = Intent.ACTION_FACTORY_TEST;
13200                        mTopData = null;
13201                        mTopComponent = new ComponentName(app.packageName,
13202                                ai.name);
13203                    } else {
13204                        errorMsg = mContext.getResources().getText(
13205                                com.android.internal.R.string.factorytest_not_system);
13206                    }
13207                } else {
13208                    errorMsg = mContext.getResources().getText(
13209                            com.android.internal.R.string.factorytest_no_action);
13210                }
13211                if (errorMsg != null) {
13212                    mTopAction = null;
13213                    mTopData = null;
13214                    mTopComponent = null;
13215                    Message msg = Message.obtain();
13216                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13217                    msg.getData().putCharSequence("msg", errorMsg);
13218                    mUiHandler.sendMessage(msg);
13219                }
13220            }
13221        }
13222
13223        retrieveSettings();
13224        final int currentUserId;
13225        synchronized (this) {
13226            currentUserId = mUserController.getCurrentUserIdLocked();
13227            readGrantedUriPermissionsLocked();
13228        }
13229
13230        if (goingCallback != null) goingCallback.run();
13231
13232        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13233                Integer.toString(currentUserId), currentUserId);
13234        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13235                Integer.toString(currentUserId), currentUserId);
13236        mSystemServiceManager.startUser(currentUserId);
13237
13238        synchronized (this) {
13239            // Only start up encryption-aware persistent apps; once user is
13240            // unlocked we'll come back around and start unaware apps
13241            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13242
13243            // Start up initial activity.
13244            mBooting = true;
13245            // Enable home activity for system user, so that the system can always boot. We don't
13246            // do this when the system user is not setup since the setup wizard should be the one
13247            // to handle home activity in this case.
13248            if (UserManager.isSplitSystemUser() &&
13249                    Settings.Secure.getInt(mContext.getContentResolver(),
13250                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13251                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13252                try {
13253                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13254                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13255                            UserHandle.USER_SYSTEM);
13256                } catch (RemoteException e) {
13257                    throw e.rethrowAsRuntimeException();
13258                }
13259            }
13260            startHomeActivityLocked(currentUserId, "systemReady");
13261
13262            try {
13263                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13264                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13265                            + " data partition or your device will be unstable.");
13266                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13267                }
13268            } catch (RemoteException e) {
13269            }
13270
13271            if (!Build.isBuildConsistent()) {
13272                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13273                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13274            }
13275
13276            long ident = Binder.clearCallingIdentity();
13277            try {
13278                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13279                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13280                        | Intent.FLAG_RECEIVER_FOREGROUND);
13281                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13282                broadcastIntentLocked(null, null, intent,
13283                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13284                        null, false, false, MY_PID, Process.SYSTEM_UID,
13285                        currentUserId);
13286                intent = new Intent(Intent.ACTION_USER_STARTING);
13287                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13288                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13289                broadcastIntentLocked(null, null, intent,
13290                        null, new IIntentReceiver.Stub() {
13291                            @Override
13292                            public void performReceive(Intent intent, int resultCode, String data,
13293                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13294                                    throws RemoteException {
13295                            }
13296                        }, 0, null, null,
13297                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13298                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13299            } catch (Throwable t) {
13300                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13301            } finally {
13302                Binder.restoreCallingIdentity(ident);
13303            }
13304            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13305            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13306        }
13307    }
13308
13309    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13310        synchronized (this) {
13311            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13312        }
13313    }
13314
13315    void skipCurrentReceiverLocked(ProcessRecord app) {
13316        for (BroadcastQueue queue : mBroadcastQueues) {
13317            queue.skipCurrentReceiverLocked(app);
13318        }
13319    }
13320
13321    /**
13322     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13323     * The application process will exit immediately after this call returns.
13324     * @param app object of the crashing app, null for the system server
13325     * @param crashInfo describing the exception
13326     */
13327    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13328        ProcessRecord r = findAppProcess(app, "Crash");
13329        final String processName = app == null ? "system_server"
13330                : (r == null ? "unknown" : r.processName);
13331
13332        handleApplicationCrashInner("crash", r, processName, crashInfo);
13333    }
13334
13335    /* Native crash reporting uses this inner version because it needs to be somewhat
13336     * decoupled from the AM-managed cleanup lifecycle
13337     */
13338    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13339            ApplicationErrorReport.CrashInfo crashInfo) {
13340        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13341                UserHandle.getUserId(Binder.getCallingUid()), processName,
13342                r == null ? -1 : r.info.flags,
13343                crashInfo.exceptionClassName,
13344                crashInfo.exceptionMessage,
13345                crashInfo.throwFileName,
13346                crashInfo.throwLineNumber);
13347
13348        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13349
13350        mAppErrors.crashApplication(r, crashInfo);
13351    }
13352
13353    public void handleApplicationStrictModeViolation(
13354            IBinder app,
13355            int violationMask,
13356            StrictMode.ViolationInfo info) {
13357        ProcessRecord r = findAppProcess(app, "StrictMode");
13358        if (r == null) {
13359            return;
13360        }
13361
13362        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13363            Integer stackFingerprint = info.hashCode();
13364            boolean logIt = true;
13365            synchronized (mAlreadyLoggedViolatedStacks) {
13366                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13367                    logIt = false;
13368                    // TODO: sub-sample into EventLog for these, with
13369                    // the info.durationMillis?  Then we'd get
13370                    // the relative pain numbers, without logging all
13371                    // the stack traces repeatedly.  We'd want to do
13372                    // likewise in the client code, which also does
13373                    // dup suppression, before the Binder call.
13374                } else {
13375                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13376                        mAlreadyLoggedViolatedStacks.clear();
13377                    }
13378                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13379                }
13380            }
13381            if (logIt) {
13382                logStrictModeViolationToDropBox(r, info);
13383            }
13384        }
13385
13386        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13387            AppErrorResult result = new AppErrorResult();
13388            synchronized (this) {
13389                final long origId = Binder.clearCallingIdentity();
13390
13391                Message msg = Message.obtain();
13392                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13393                HashMap<String, Object> data = new HashMap<String, Object>();
13394                data.put("result", result);
13395                data.put("app", r);
13396                data.put("violationMask", violationMask);
13397                data.put("info", info);
13398                msg.obj = data;
13399                mUiHandler.sendMessage(msg);
13400
13401                Binder.restoreCallingIdentity(origId);
13402            }
13403            int res = result.get();
13404            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13405        }
13406    }
13407
13408    // Depending on the policy in effect, there could be a bunch of
13409    // these in quick succession so we try to batch these together to
13410    // minimize disk writes, number of dropbox entries, and maximize
13411    // compression, by having more fewer, larger records.
13412    private void logStrictModeViolationToDropBox(
13413            ProcessRecord process,
13414            StrictMode.ViolationInfo info) {
13415        if (info == null) {
13416            return;
13417        }
13418        final boolean isSystemApp = process == null ||
13419                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13420                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13421        final String processName = process == null ? "unknown" : process.processName;
13422        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13423        final DropBoxManager dbox = (DropBoxManager)
13424                mContext.getSystemService(Context.DROPBOX_SERVICE);
13425
13426        // Exit early if the dropbox isn't configured to accept this report type.
13427        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13428
13429        boolean bufferWasEmpty;
13430        boolean needsFlush;
13431        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13432        synchronized (sb) {
13433            bufferWasEmpty = sb.length() == 0;
13434            appendDropBoxProcessHeaders(process, processName, sb);
13435            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13436            sb.append("System-App: ").append(isSystemApp).append("\n");
13437            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13438            if (info.violationNumThisLoop != 0) {
13439                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13440            }
13441            if (info.numAnimationsRunning != 0) {
13442                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13443            }
13444            if (info.broadcastIntentAction != null) {
13445                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13446            }
13447            if (info.durationMillis != -1) {
13448                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13449            }
13450            if (info.numInstances != -1) {
13451                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13452            }
13453            if (info.tags != null) {
13454                for (String tag : info.tags) {
13455                    sb.append("Span-Tag: ").append(tag).append("\n");
13456                }
13457            }
13458            sb.append("\n");
13459            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13460                sb.append(info.crashInfo.stackTrace);
13461                sb.append("\n");
13462            }
13463            if (info.message != null) {
13464                sb.append(info.message);
13465                sb.append("\n");
13466            }
13467
13468            // Only buffer up to ~64k.  Various logging bits truncate
13469            // things at 128k.
13470            needsFlush = (sb.length() > 64 * 1024);
13471        }
13472
13473        // Flush immediately if the buffer's grown too large, or this
13474        // is a non-system app.  Non-system apps are isolated with a
13475        // different tag & policy and not batched.
13476        //
13477        // Batching is useful during internal testing with
13478        // StrictMode settings turned up high.  Without batching,
13479        // thousands of separate files could be created on boot.
13480        if (!isSystemApp || needsFlush) {
13481            new Thread("Error dump: " + dropboxTag) {
13482                @Override
13483                public void run() {
13484                    String report;
13485                    synchronized (sb) {
13486                        report = sb.toString();
13487                        sb.delete(0, sb.length());
13488                        sb.trimToSize();
13489                    }
13490                    if (report.length() != 0) {
13491                        dbox.addText(dropboxTag, report);
13492                    }
13493                }
13494            }.start();
13495            return;
13496        }
13497
13498        // System app batching:
13499        if (!bufferWasEmpty) {
13500            // An existing dropbox-writing thread is outstanding, so
13501            // we don't need to start it up.  The existing thread will
13502            // catch the buffer appends we just did.
13503            return;
13504        }
13505
13506        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13507        // (After this point, we shouldn't access AMS internal data structures.)
13508        new Thread("Error dump: " + dropboxTag) {
13509            @Override
13510            public void run() {
13511                // 5 second sleep to let stacks arrive and be batched together
13512                try {
13513                    Thread.sleep(5000);  // 5 seconds
13514                } catch (InterruptedException e) {}
13515
13516                String errorReport;
13517                synchronized (mStrictModeBuffer) {
13518                    errorReport = mStrictModeBuffer.toString();
13519                    if (errorReport.length() == 0) {
13520                        return;
13521                    }
13522                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13523                    mStrictModeBuffer.trimToSize();
13524                }
13525                dbox.addText(dropboxTag, errorReport);
13526            }
13527        }.start();
13528    }
13529
13530    /**
13531     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13532     * @param app object of the crashing app, null for the system server
13533     * @param tag reported by the caller
13534     * @param system whether this wtf is coming from the system
13535     * @param crashInfo describing the context of the error
13536     * @return true if the process should exit immediately (WTF is fatal)
13537     */
13538    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13539            final ApplicationErrorReport.CrashInfo crashInfo) {
13540        final int callingUid = Binder.getCallingUid();
13541        final int callingPid = Binder.getCallingPid();
13542
13543        if (system) {
13544            // If this is coming from the system, we could very well have low-level
13545            // system locks held, so we want to do this all asynchronously.  And we
13546            // never want this to become fatal, so there is that too.
13547            mHandler.post(new Runnable() {
13548                @Override public void run() {
13549                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13550                }
13551            });
13552            return false;
13553        }
13554
13555        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13556                crashInfo);
13557
13558        if (r != null && r.pid != Process.myPid() &&
13559                Settings.Global.getInt(mContext.getContentResolver(),
13560                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13561            mAppErrors.crashApplication(r, crashInfo);
13562            return true;
13563        } else {
13564            return false;
13565        }
13566    }
13567
13568    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13569            final ApplicationErrorReport.CrashInfo crashInfo) {
13570        final ProcessRecord r = findAppProcess(app, "WTF");
13571        final String processName = app == null ? "system_server"
13572                : (r == null ? "unknown" : r.processName);
13573
13574        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13575                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13576
13577        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13578
13579        return r;
13580    }
13581
13582    /**
13583     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13584     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13585     */
13586    private ProcessRecord findAppProcess(IBinder app, String reason) {
13587        if (app == null) {
13588            return null;
13589        }
13590
13591        synchronized (this) {
13592            final int NP = mProcessNames.getMap().size();
13593            for (int ip=0; ip<NP; ip++) {
13594                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13595                final int NA = apps.size();
13596                for (int ia=0; ia<NA; ia++) {
13597                    ProcessRecord p = apps.valueAt(ia);
13598                    if (p.thread != null && p.thread.asBinder() == app) {
13599                        return p;
13600                    }
13601                }
13602            }
13603
13604            Slog.w(TAG, "Can't find mystery application for " + reason
13605                    + " from pid=" + Binder.getCallingPid()
13606                    + " uid=" + Binder.getCallingUid() + ": " + app);
13607            return null;
13608        }
13609    }
13610
13611    /**
13612     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13613     * to append various headers to the dropbox log text.
13614     */
13615    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13616            StringBuilder sb) {
13617        // Watchdog thread ends up invoking this function (with
13618        // a null ProcessRecord) to add the stack file to dropbox.
13619        // Do not acquire a lock on this (am) in such cases, as it
13620        // could cause a potential deadlock, if and when watchdog
13621        // is invoked due to unavailability of lock on am and it
13622        // would prevent watchdog from killing system_server.
13623        if (process == null) {
13624            sb.append("Process: ").append(processName).append("\n");
13625            return;
13626        }
13627        // Note: ProcessRecord 'process' is guarded by the service
13628        // instance.  (notably process.pkgList, which could otherwise change
13629        // concurrently during execution of this method)
13630        synchronized (this) {
13631            sb.append("Process: ").append(processName).append("\n");
13632            int flags = process.info.flags;
13633            IPackageManager pm = AppGlobals.getPackageManager();
13634            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13635            for (int ip=0; ip<process.pkgList.size(); ip++) {
13636                String pkg = process.pkgList.keyAt(ip);
13637                sb.append("Package: ").append(pkg);
13638                try {
13639                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13640                    if (pi != null) {
13641                        sb.append(" v").append(pi.versionCode);
13642                        if (pi.versionName != null) {
13643                            sb.append(" (").append(pi.versionName).append(")");
13644                        }
13645                    }
13646                } catch (RemoteException e) {
13647                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13648                }
13649                sb.append("\n");
13650            }
13651        }
13652    }
13653
13654    private static String processClass(ProcessRecord process) {
13655        if (process == null || process.pid == MY_PID) {
13656            return "system_server";
13657        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13658            return "system_app";
13659        } else {
13660            return "data_app";
13661        }
13662    }
13663
13664    private volatile long mWtfClusterStart;
13665    private volatile int mWtfClusterCount;
13666
13667    /**
13668     * Write a description of an error (crash, WTF, ANR) to the drop box.
13669     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13670     * @param process which caused the error, null means the system server
13671     * @param activity which triggered the error, null if unknown
13672     * @param parent activity related to the error, null if unknown
13673     * @param subject line related to the error, null if absent
13674     * @param report in long form describing the error, null if absent
13675     * @param dataFile text file to include in the report, null if none
13676     * @param crashInfo giving an application stack trace, null if absent
13677     */
13678    public void addErrorToDropBox(String eventType,
13679            ProcessRecord process, String processName, ActivityRecord activity,
13680            ActivityRecord parent, String subject,
13681            final String report, final File dataFile,
13682            final ApplicationErrorReport.CrashInfo crashInfo) {
13683        // NOTE -- this must never acquire the ActivityManagerService lock,
13684        // otherwise the watchdog may be prevented from resetting the system.
13685
13686        // Bail early if not published yet
13687        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13688        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13689
13690        // Exit early if the dropbox isn't configured to accept this report type.
13691        final String dropboxTag = processClass(process) + "_" + eventType;
13692        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13693
13694        // Rate-limit how often we're willing to do the heavy lifting below to
13695        // collect and record logs; currently 5 logs per 10 second period.
13696        final long now = SystemClock.elapsedRealtime();
13697        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13698            mWtfClusterStart = now;
13699            mWtfClusterCount = 1;
13700        } else {
13701            if (mWtfClusterCount++ >= 5) return;
13702        }
13703
13704        final StringBuilder sb = new StringBuilder(1024);
13705        appendDropBoxProcessHeaders(process, processName, sb);
13706        if (process != null) {
13707            sb.append("Foreground: ")
13708                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13709                    .append("\n");
13710        }
13711        if (activity != null) {
13712            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13713        }
13714        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13715            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13716        }
13717        if (parent != null && parent != activity) {
13718            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13719        }
13720        if (subject != null) {
13721            sb.append("Subject: ").append(subject).append("\n");
13722        }
13723        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13724        if (Debug.isDebuggerConnected()) {
13725            sb.append("Debugger: Connected\n");
13726        }
13727        sb.append("\n");
13728
13729        // Do the rest in a worker thread to avoid blocking the caller on I/O
13730        // (After this point, we shouldn't access AMS internal data structures.)
13731        Thread worker = new Thread("Error dump: " + dropboxTag) {
13732            @Override
13733            public void run() {
13734                if (report != null) {
13735                    sb.append(report);
13736                }
13737
13738                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13739                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13740                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13741                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13742
13743                if (dataFile != null && maxDataFileSize > 0) {
13744                    try {
13745                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13746                                    "\n\n[[TRUNCATED]]"));
13747                    } catch (IOException e) {
13748                        Slog.e(TAG, "Error reading " + dataFile, e);
13749                    }
13750                }
13751                if (crashInfo != null && crashInfo.stackTrace != null) {
13752                    sb.append(crashInfo.stackTrace);
13753                }
13754
13755                if (lines > 0) {
13756                    sb.append("\n");
13757
13758                    // Merge several logcat streams, and take the last N lines
13759                    InputStreamReader input = null;
13760                    try {
13761                        java.lang.Process logcat = new ProcessBuilder(
13762                                "/system/bin/timeout", "-k", "15s", "10s",
13763                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13764                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13765                                        .redirectErrorStream(true).start();
13766
13767                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13768                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13769                        input = new InputStreamReader(logcat.getInputStream());
13770
13771                        int num;
13772                        char[] buf = new char[8192];
13773                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13774                    } catch (IOException e) {
13775                        Slog.e(TAG, "Error running logcat", e);
13776                    } finally {
13777                        if (input != null) try { input.close(); } catch (IOException e) {}
13778                    }
13779                }
13780
13781                dbox.addText(dropboxTag, sb.toString());
13782            }
13783        };
13784
13785        if (process == null) {
13786            // If process is null, we are being called from some internal code
13787            // and may be about to die -- run this synchronously.
13788            worker.run();
13789        } else {
13790            worker.start();
13791        }
13792    }
13793
13794    @Override
13795    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13796        enforceNotIsolatedCaller("getProcessesInErrorState");
13797        // assume our apps are happy - lazy create the list
13798        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13799
13800        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13801                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13802        int userId = UserHandle.getUserId(Binder.getCallingUid());
13803
13804        synchronized (this) {
13805
13806            // iterate across all processes
13807            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13808                ProcessRecord app = mLruProcesses.get(i);
13809                if (!allUsers && app.userId != userId) {
13810                    continue;
13811                }
13812                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13813                    // This one's in trouble, so we'll generate a report for it
13814                    // crashes are higher priority (in case there's a crash *and* an anr)
13815                    ActivityManager.ProcessErrorStateInfo report = null;
13816                    if (app.crashing) {
13817                        report = app.crashingReport;
13818                    } else if (app.notResponding) {
13819                        report = app.notRespondingReport;
13820                    }
13821
13822                    if (report != null) {
13823                        if (errList == null) {
13824                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13825                        }
13826                        errList.add(report);
13827                    } else {
13828                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13829                                " crashing = " + app.crashing +
13830                                " notResponding = " + app.notResponding);
13831                    }
13832                }
13833            }
13834        }
13835
13836        return errList;
13837    }
13838
13839    static int procStateToImportance(int procState, int memAdj,
13840            ActivityManager.RunningAppProcessInfo currApp) {
13841        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13842        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13843            currApp.lru = memAdj;
13844        } else {
13845            currApp.lru = 0;
13846        }
13847        return imp;
13848    }
13849
13850    private void fillInProcMemInfo(ProcessRecord app,
13851            ActivityManager.RunningAppProcessInfo outInfo) {
13852        outInfo.pid = app.pid;
13853        outInfo.uid = app.info.uid;
13854        if (mHeavyWeightProcess == app) {
13855            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13856        }
13857        if (app.persistent) {
13858            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13859        }
13860        if (app.activities.size() > 0) {
13861            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13862        }
13863        outInfo.lastTrimLevel = app.trimMemoryLevel;
13864        int adj = app.curAdj;
13865        int procState = app.curProcState;
13866        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13867        outInfo.importanceReasonCode = app.adjTypeCode;
13868        outInfo.processState = app.curProcState;
13869    }
13870
13871    @Override
13872    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13873        enforceNotIsolatedCaller("getRunningAppProcesses");
13874
13875        final int callingUid = Binder.getCallingUid();
13876
13877        // Lazy instantiation of list
13878        List<ActivityManager.RunningAppProcessInfo> runList = null;
13879        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13880                callingUid) == PackageManager.PERMISSION_GRANTED;
13881        final int userId = UserHandle.getUserId(callingUid);
13882        final boolean allUids = isGetTasksAllowed(
13883                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13884
13885        synchronized (this) {
13886            // Iterate across all processes
13887            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13888                ProcessRecord app = mLruProcesses.get(i);
13889                if ((!allUsers && app.userId != userId)
13890                        || (!allUids && app.uid != callingUid)) {
13891                    continue;
13892                }
13893                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13894                    // Generate process state info for running application
13895                    ActivityManager.RunningAppProcessInfo currApp =
13896                        new ActivityManager.RunningAppProcessInfo(app.processName,
13897                                app.pid, app.getPackageList());
13898                    fillInProcMemInfo(app, currApp);
13899                    if (app.adjSource instanceof ProcessRecord) {
13900                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13901                        currApp.importanceReasonImportance =
13902                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13903                                        app.adjSourceProcState);
13904                    } else if (app.adjSource instanceof ActivityRecord) {
13905                        ActivityRecord r = (ActivityRecord)app.adjSource;
13906                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13907                    }
13908                    if (app.adjTarget instanceof ComponentName) {
13909                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13910                    }
13911                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13912                    //        + " lru=" + currApp.lru);
13913                    if (runList == null) {
13914                        runList = new ArrayList<>();
13915                    }
13916                    runList.add(currApp);
13917                }
13918            }
13919        }
13920        return runList;
13921    }
13922
13923    @Override
13924    public List<ApplicationInfo> getRunningExternalApplications() {
13925        enforceNotIsolatedCaller("getRunningExternalApplications");
13926        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13927        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13928        if (runningApps != null && runningApps.size() > 0) {
13929            Set<String> extList = new HashSet<String>();
13930            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13931                if (app.pkgList != null) {
13932                    for (String pkg : app.pkgList) {
13933                        extList.add(pkg);
13934                    }
13935                }
13936            }
13937            IPackageManager pm = AppGlobals.getPackageManager();
13938            for (String pkg : extList) {
13939                try {
13940                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13941                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13942                        retList.add(info);
13943                    }
13944                } catch (RemoteException e) {
13945                }
13946            }
13947        }
13948        return retList;
13949    }
13950
13951    @Override
13952    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13953        enforceNotIsolatedCaller("getMyMemoryState");
13954        synchronized (this) {
13955            ProcessRecord proc;
13956            synchronized (mPidsSelfLocked) {
13957                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13958            }
13959            fillInProcMemInfo(proc, outInfo);
13960        }
13961    }
13962
13963    @Override
13964    public int getMemoryTrimLevel() {
13965        enforceNotIsolatedCaller("getMyMemoryState");
13966        synchronized (this) {
13967            return mLastMemoryLevel;
13968        }
13969    }
13970
13971    @Override
13972    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13973            FileDescriptor err, String[] args, ShellCallback callback,
13974            ResultReceiver resultReceiver) {
13975        (new ActivityManagerShellCommand(this, false)).exec(
13976                this, in, out, err, args, callback, resultReceiver);
13977    }
13978
13979    @Override
13980    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13981        if (checkCallingPermission(android.Manifest.permission.DUMP)
13982                != PackageManager.PERMISSION_GRANTED) {
13983            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13984                    + Binder.getCallingPid()
13985                    + ", uid=" + Binder.getCallingUid()
13986                    + " without permission "
13987                    + android.Manifest.permission.DUMP);
13988            return;
13989        }
13990
13991        boolean dumpAll = false;
13992        boolean dumpClient = false;
13993        boolean dumpCheckin = false;
13994        boolean dumpCheckinFormat = false;
13995        boolean dumpVisibleStacks = false;
13996        String dumpPackage = null;
13997
13998        int opti = 0;
13999        while (opti < args.length) {
14000            String opt = args[opti];
14001            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14002                break;
14003            }
14004            opti++;
14005            if ("-a".equals(opt)) {
14006                dumpAll = true;
14007            } else if ("-c".equals(opt)) {
14008                dumpClient = true;
14009            } else if ("-v".equals(opt)) {
14010                dumpVisibleStacks = true;
14011            } else if ("-p".equals(opt)) {
14012                if (opti < args.length) {
14013                    dumpPackage = args[opti];
14014                    opti++;
14015                } else {
14016                    pw.println("Error: -p option requires package argument");
14017                    return;
14018                }
14019                dumpClient = true;
14020            } else if ("--checkin".equals(opt)) {
14021                dumpCheckin = dumpCheckinFormat = true;
14022            } else if ("-C".equals(opt)) {
14023                dumpCheckinFormat = true;
14024            } else if ("-h".equals(opt)) {
14025                ActivityManagerShellCommand.dumpHelp(pw, true);
14026                return;
14027            } else {
14028                pw.println("Unknown argument: " + opt + "; use -h for help");
14029            }
14030        }
14031
14032        long origId = Binder.clearCallingIdentity();
14033        boolean more = false;
14034        // Is the caller requesting to dump a particular piece of data?
14035        if (opti < args.length) {
14036            String cmd = args[opti];
14037            opti++;
14038            if ("activities".equals(cmd) || "a".equals(cmd)) {
14039                synchronized (this) {
14040                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14041                }
14042            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14043                synchronized (this) {
14044                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14045                }
14046            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14047                String[] newArgs;
14048                String name;
14049                if (opti >= args.length) {
14050                    name = null;
14051                    newArgs = EMPTY_STRING_ARRAY;
14052                } else {
14053                    dumpPackage = args[opti];
14054                    opti++;
14055                    newArgs = new String[args.length - opti];
14056                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14057                            args.length - opti);
14058                }
14059                synchronized (this) {
14060                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14061                }
14062            } else if ("broadcast-stats".equals(cmd)) {
14063                String[] newArgs;
14064                String name;
14065                if (opti >= args.length) {
14066                    name = null;
14067                    newArgs = EMPTY_STRING_ARRAY;
14068                } else {
14069                    dumpPackage = args[opti];
14070                    opti++;
14071                    newArgs = new String[args.length - opti];
14072                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14073                            args.length - opti);
14074                }
14075                synchronized (this) {
14076                    if (dumpCheckinFormat) {
14077                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14078                                dumpPackage);
14079                    } else {
14080                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14081                    }
14082                }
14083            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14084                String[] newArgs;
14085                String name;
14086                if (opti >= args.length) {
14087                    name = null;
14088                    newArgs = EMPTY_STRING_ARRAY;
14089                } else {
14090                    dumpPackage = args[opti];
14091                    opti++;
14092                    newArgs = new String[args.length - opti];
14093                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14094                            args.length - opti);
14095                }
14096                synchronized (this) {
14097                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14098                }
14099            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14100                String[] newArgs;
14101                String name;
14102                if (opti >= args.length) {
14103                    name = null;
14104                    newArgs = EMPTY_STRING_ARRAY;
14105                } else {
14106                    dumpPackage = args[opti];
14107                    opti++;
14108                    newArgs = new String[args.length - opti];
14109                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14110                            args.length - opti);
14111                }
14112                synchronized (this) {
14113                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14114                }
14115            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14116                synchronized (this) {
14117                    dumpOomLocked(fd, pw, args, opti, true);
14118                }
14119            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14120                synchronized (this) {
14121                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14122                }
14123            } else if ("provider".equals(cmd)) {
14124                String[] newArgs;
14125                String name;
14126                if (opti >= args.length) {
14127                    name = null;
14128                    newArgs = EMPTY_STRING_ARRAY;
14129                } else {
14130                    name = args[opti];
14131                    opti++;
14132                    newArgs = new String[args.length - opti];
14133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14134                }
14135                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14136                    pw.println("No providers match: " + name);
14137                    pw.println("Use -h for help.");
14138                }
14139            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14140                synchronized (this) {
14141                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14142                }
14143            } else if ("service".equals(cmd)) {
14144                String[] newArgs;
14145                String name;
14146                if (opti >= args.length) {
14147                    name = null;
14148                    newArgs = EMPTY_STRING_ARRAY;
14149                } else {
14150                    name = args[opti];
14151                    opti++;
14152                    newArgs = new String[args.length - opti];
14153                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14154                            args.length - opti);
14155                }
14156                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14157                    pw.println("No services match: " + name);
14158                    pw.println("Use -h for help.");
14159                }
14160            } else if ("package".equals(cmd)) {
14161                String[] newArgs;
14162                if (opti >= args.length) {
14163                    pw.println("package: no package name specified");
14164                    pw.println("Use -h for help.");
14165                } else {
14166                    dumpPackage = args[opti];
14167                    opti++;
14168                    newArgs = new String[args.length - opti];
14169                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14170                            args.length - opti);
14171                    args = newArgs;
14172                    opti = 0;
14173                    more = true;
14174                }
14175            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14176                synchronized (this) {
14177                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14178                }
14179            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14180                if (dumpClient) {
14181                    ActiveServices.ServiceDumper dumper;
14182                    synchronized (this) {
14183                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14184                                dumpPackage);
14185                    }
14186                    dumper.dumpWithClient();
14187                } else {
14188                    synchronized (this) {
14189                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14190                                dumpPackage).dumpLocked();
14191                    }
14192                }
14193            } else if ("locks".equals(cmd)) {
14194                LockGuard.dump(fd, pw, args);
14195            } else if ("pip".equals(cmd)) {
14196                Rect bounds = getDefaultPictureInPictureBounds(DEFAULT_DISPLAY);
14197                pw.print("defaultBounds="); bounds.printShortString(pw);
14198                pw.println();
14199                bounds = getPictureInPictureMovementBounds(DEFAULT_DISPLAY);
14200                pw.print("movementBounds="); bounds.printShortString(pw);
14201                pw.println();
14202            } else {
14203                // Dumping a single activity?
14204                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14205                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14206                    int res = shell.exec(this, null, fd, null, args, null,
14207                            new ResultReceiver(null));
14208                    if (res < 0) {
14209                        pw.println("Bad activity command, or no activities match: " + cmd);
14210                        pw.println("Use -h for help.");
14211                    }
14212                }
14213            }
14214            if (!more) {
14215                Binder.restoreCallingIdentity(origId);
14216                return;
14217            }
14218        }
14219
14220        // No piece of data specified, dump everything.
14221        if (dumpCheckinFormat) {
14222            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14223        } else if (dumpClient) {
14224            ActiveServices.ServiceDumper sdumper;
14225            synchronized (this) {
14226                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14227                pw.println();
14228                if (dumpAll) {
14229                    pw.println("-------------------------------------------------------------------------------");
14230                }
14231                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14232                pw.println();
14233                if (dumpAll) {
14234                    pw.println("-------------------------------------------------------------------------------");
14235                }
14236                if (dumpAll || dumpPackage != null) {
14237                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14238                    pw.println();
14239                    if (dumpAll) {
14240                        pw.println("-------------------------------------------------------------------------------");
14241                    }
14242                }
14243                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14244                pw.println();
14245                if (dumpAll) {
14246                    pw.println("-------------------------------------------------------------------------------");
14247                }
14248                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14249                pw.println();
14250                if (dumpAll) {
14251                    pw.println("-------------------------------------------------------------------------------");
14252                }
14253                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14254                        dumpPackage);
14255            }
14256            sdumper.dumpWithClient();
14257            pw.println();
14258            synchronized (this) {
14259                if (dumpAll) {
14260                    pw.println("-------------------------------------------------------------------------------");
14261                }
14262                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14263                pw.println();
14264                if (dumpAll) {
14265                    pw.println("-------------------------------------------------------------------------------");
14266                }
14267                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14268                if (mAssociations.size() > 0) {
14269                    pw.println();
14270                    if (dumpAll) {
14271                        pw.println("-------------------------------------------------------------------------------");
14272                    }
14273                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14274                }
14275                pw.println();
14276                if (dumpAll) {
14277                    pw.println("-------------------------------------------------------------------------------");
14278                }
14279                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14280            }
14281
14282        } else {
14283            synchronized (this) {
14284                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14285                pw.println();
14286                if (dumpAll) {
14287                    pw.println("-------------------------------------------------------------------------------");
14288                }
14289                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14290                pw.println();
14291                if (dumpAll) {
14292                    pw.println("-------------------------------------------------------------------------------");
14293                }
14294                if (dumpAll || dumpPackage != null) {
14295                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14296                    pw.println();
14297                    if (dumpAll) {
14298                        pw.println("-------------------------------------------------------------------------------");
14299                    }
14300                }
14301                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14302                pw.println();
14303                if (dumpAll) {
14304                    pw.println("-------------------------------------------------------------------------------");
14305                }
14306                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14307                pw.println();
14308                if (dumpAll) {
14309                    pw.println("-------------------------------------------------------------------------------");
14310                }
14311                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14312                        .dumpLocked();
14313                pw.println();
14314                if (dumpAll) {
14315                    pw.println("-------------------------------------------------------------------------------");
14316                }
14317                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14318                pw.println();
14319                if (dumpAll) {
14320                    pw.println("-------------------------------------------------------------------------------");
14321                }
14322                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14323                if (mAssociations.size() > 0) {
14324                    pw.println();
14325                    if (dumpAll) {
14326                        pw.println("-------------------------------------------------------------------------------");
14327                    }
14328                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14329                }
14330                pw.println();
14331                if (dumpAll) {
14332                    pw.println("-------------------------------------------------------------------------------");
14333                }
14334                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14335            }
14336        }
14337        Binder.restoreCallingIdentity(origId);
14338    }
14339
14340    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14341            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14342        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14343
14344        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14345                dumpPackage);
14346        boolean needSep = printedAnything;
14347
14348        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14349                mStackSupervisor.getResumedActivityLocked(),
14350                dumpPackage, needSep, "  ResumedActivity: ");
14351        if (printed) {
14352            printedAnything = true;
14353            needSep = false;
14354        }
14355
14356        if (dumpPackage == null) {
14357            if (needSep) {
14358                pw.println();
14359            }
14360            needSep = true;
14361            printedAnything = true;
14362            mStackSupervisor.dump(pw, "  ");
14363        }
14364
14365        if (!printedAnything) {
14366            pw.println("  (nothing)");
14367        }
14368    }
14369
14370    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14371            int opti, boolean dumpAll, String dumpPackage) {
14372        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14373
14374        boolean printedAnything = false;
14375
14376        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14377            boolean printedHeader = false;
14378
14379            final int N = mRecentTasks.size();
14380            for (int i=0; i<N; i++) {
14381                TaskRecord tr = mRecentTasks.get(i);
14382                if (dumpPackage != null) {
14383                    if (tr.realActivity == null ||
14384                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14385                        continue;
14386                    }
14387                }
14388                if (!printedHeader) {
14389                    pw.println("  Recent tasks:");
14390                    printedHeader = true;
14391                    printedAnything = true;
14392                }
14393                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14394                        pw.println(tr);
14395                if (dumpAll) {
14396                    mRecentTasks.get(i).dump(pw, "    ");
14397                }
14398            }
14399        }
14400
14401        if (!printedAnything) {
14402            pw.println("  (nothing)");
14403        }
14404    }
14405
14406    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14407            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14408        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14409
14410        int dumpUid = 0;
14411        if (dumpPackage != null) {
14412            IPackageManager pm = AppGlobals.getPackageManager();
14413            try {
14414                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14415            } catch (RemoteException e) {
14416            }
14417        }
14418
14419        boolean printedAnything = false;
14420
14421        final long now = SystemClock.uptimeMillis();
14422
14423        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14424            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14425                    = mAssociations.valueAt(i1);
14426            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14427                SparseArray<ArrayMap<String, Association>> sourceUids
14428                        = targetComponents.valueAt(i2);
14429                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14430                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14431                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14432                        Association ass = sourceProcesses.valueAt(i4);
14433                        if (dumpPackage != null) {
14434                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14435                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14436                                continue;
14437                            }
14438                        }
14439                        printedAnything = true;
14440                        pw.print("  ");
14441                        pw.print(ass.mTargetProcess);
14442                        pw.print("/");
14443                        UserHandle.formatUid(pw, ass.mTargetUid);
14444                        pw.print(" <- ");
14445                        pw.print(ass.mSourceProcess);
14446                        pw.print("/");
14447                        UserHandle.formatUid(pw, ass.mSourceUid);
14448                        pw.println();
14449                        pw.print("    via ");
14450                        pw.print(ass.mTargetComponent.flattenToShortString());
14451                        pw.println();
14452                        pw.print("    ");
14453                        long dur = ass.mTime;
14454                        if (ass.mNesting > 0) {
14455                            dur += now - ass.mStartTime;
14456                        }
14457                        TimeUtils.formatDuration(dur, pw);
14458                        pw.print(" (");
14459                        pw.print(ass.mCount);
14460                        pw.print(" times)");
14461                        pw.print("  ");
14462                        for (int i=0; i<ass.mStateTimes.length; i++) {
14463                            long amt = ass.mStateTimes[i];
14464                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14465                                amt += now - ass.mLastStateUptime;
14466                            }
14467                            if (amt != 0) {
14468                                pw.print(" ");
14469                                pw.print(ProcessList.makeProcStateString(
14470                                            i + ActivityManager.MIN_PROCESS_STATE));
14471                                pw.print("=");
14472                                TimeUtils.formatDuration(amt, pw);
14473                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14474                                    pw.print("*");
14475                                }
14476                            }
14477                        }
14478                        pw.println();
14479                        if (ass.mNesting > 0) {
14480                            pw.print("    Currently active: ");
14481                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14482                            pw.println();
14483                        }
14484                    }
14485                }
14486            }
14487
14488        }
14489
14490        if (!printedAnything) {
14491            pw.println("  (nothing)");
14492        }
14493    }
14494
14495    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14496            String header, boolean needSep) {
14497        boolean printed = false;
14498        int whichAppId = -1;
14499        if (dumpPackage != null) {
14500            try {
14501                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14502                        dumpPackage, 0);
14503                whichAppId = UserHandle.getAppId(info.uid);
14504            } catch (NameNotFoundException e) {
14505                e.printStackTrace();
14506            }
14507        }
14508        for (int i=0; i<uids.size(); i++) {
14509            UidRecord uidRec = uids.valueAt(i);
14510            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14511                continue;
14512            }
14513            if (!printed) {
14514                printed = true;
14515                if (needSep) {
14516                    pw.println();
14517                }
14518                pw.print("  ");
14519                pw.println(header);
14520                needSep = true;
14521            }
14522            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14523            pw.print(": "); pw.println(uidRec);
14524        }
14525        return printed;
14526    }
14527
14528    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14529            int opti, boolean dumpAll, String dumpPackage) {
14530        boolean needSep = false;
14531        boolean printedAnything = false;
14532        int numPers = 0;
14533
14534        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14535
14536        if (dumpAll) {
14537            final int NP = mProcessNames.getMap().size();
14538            for (int ip=0; ip<NP; ip++) {
14539                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14540                final int NA = procs.size();
14541                for (int ia=0; ia<NA; ia++) {
14542                    ProcessRecord r = procs.valueAt(ia);
14543                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14544                        continue;
14545                    }
14546                    if (!needSep) {
14547                        pw.println("  All known processes:");
14548                        needSep = true;
14549                        printedAnything = true;
14550                    }
14551                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14552                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14553                        pw.print(" "); pw.println(r);
14554                    r.dump(pw, "    ");
14555                    if (r.persistent) {
14556                        numPers++;
14557                    }
14558                }
14559            }
14560        }
14561
14562        if (mIsolatedProcesses.size() > 0) {
14563            boolean printed = false;
14564            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14565                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14566                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14567                    continue;
14568                }
14569                if (!printed) {
14570                    if (needSep) {
14571                        pw.println();
14572                    }
14573                    pw.println("  Isolated process list (sorted by uid):");
14574                    printedAnything = true;
14575                    printed = true;
14576                    needSep = true;
14577                }
14578                pw.println(String.format("%sIsolated #%2d: %s",
14579                        "    ", i, r.toString()));
14580            }
14581        }
14582
14583        if (mActiveUids.size() > 0) {
14584            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14585                printedAnything = needSep = true;
14586            }
14587        }
14588        if (mValidateUids.size() > 0) {
14589            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14590                printedAnything = needSep = true;
14591            }
14592        }
14593
14594        if (mLruProcesses.size() > 0) {
14595            if (needSep) {
14596                pw.println();
14597            }
14598            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14599                    pw.print(" total, non-act at ");
14600                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14601                    pw.print(", non-svc at ");
14602                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14603                    pw.println("):");
14604            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14605            needSep = true;
14606            printedAnything = true;
14607        }
14608
14609        if (dumpAll || dumpPackage != null) {
14610            synchronized (mPidsSelfLocked) {
14611                boolean printed = false;
14612                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14613                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14614                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14615                        continue;
14616                    }
14617                    if (!printed) {
14618                        if (needSep) pw.println();
14619                        needSep = true;
14620                        pw.println("  PID mappings:");
14621                        printed = true;
14622                        printedAnything = true;
14623                    }
14624                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14625                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14626                }
14627            }
14628        }
14629
14630        if (mForegroundProcesses.size() > 0) {
14631            synchronized (mPidsSelfLocked) {
14632                boolean printed = false;
14633                for (int i=0; i<mForegroundProcesses.size(); i++) {
14634                    ProcessRecord r = mPidsSelfLocked.get(
14635                            mForegroundProcesses.valueAt(i).pid);
14636                    if (dumpPackage != null && (r == null
14637                            || !r.pkgList.containsKey(dumpPackage))) {
14638                        continue;
14639                    }
14640                    if (!printed) {
14641                        if (needSep) pw.println();
14642                        needSep = true;
14643                        pw.println("  Foreground Processes:");
14644                        printed = true;
14645                        printedAnything = true;
14646                    }
14647                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14648                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14649                }
14650            }
14651        }
14652
14653        if (mPersistentStartingProcesses.size() > 0) {
14654            if (needSep) pw.println();
14655            needSep = true;
14656            printedAnything = true;
14657            pw.println("  Persisent processes that are starting:");
14658            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14659                    "Starting Norm", "Restarting PERS", dumpPackage);
14660        }
14661
14662        if (mRemovedProcesses.size() > 0) {
14663            if (needSep) pw.println();
14664            needSep = true;
14665            printedAnything = true;
14666            pw.println("  Processes that are being removed:");
14667            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14668                    "Removed Norm", "Removed PERS", dumpPackage);
14669        }
14670
14671        if (mProcessesOnHold.size() > 0) {
14672            if (needSep) pw.println();
14673            needSep = true;
14674            printedAnything = true;
14675            pw.println("  Processes that are on old until the system is ready:");
14676            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14677                    "OnHold Norm", "OnHold PERS", dumpPackage);
14678        }
14679
14680        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14681
14682        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14683        if (needSep) {
14684            printedAnything = true;
14685        }
14686
14687        if (dumpPackage == null) {
14688            pw.println();
14689            needSep = false;
14690            mUserController.dump(pw, dumpAll);
14691        }
14692        if (mHomeProcess != null && (dumpPackage == null
14693                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14694            if (needSep) {
14695                pw.println();
14696                needSep = false;
14697            }
14698            pw.println("  mHomeProcess: " + mHomeProcess);
14699        }
14700        if (mPreviousProcess != null && (dumpPackage == null
14701                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14702            if (needSep) {
14703                pw.println();
14704                needSep = false;
14705            }
14706            pw.println("  mPreviousProcess: " + mPreviousProcess);
14707        }
14708        if (dumpAll) {
14709            StringBuilder sb = new StringBuilder(128);
14710            sb.append("  mPreviousProcessVisibleTime: ");
14711            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14712            pw.println(sb);
14713        }
14714        if (mHeavyWeightProcess != null && (dumpPackage == null
14715                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14716            if (needSep) {
14717                pw.println();
14718                needSep = false;
14719            }
14720            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14721        }
14722        if (dumpPackage == null) {
14723            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14724            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14725        }
14726        if (dumpAll) {
14727            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14728            if (mCompatModePackages.getPackages().size() > 0) {
14729                boolean printed = false;
14730                for (Map.Entry<String, Integer> entry
14731                        : mCompatModePackages.getPackages().entrySet()) {
14732                    String pkg = entry.getKey();
14733                    int mode = entry.getValue();
14734                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14735                        continue;
14736                    }
14737                    if (!printed) {
14738                        pw.println("  mScreenCompatPackages:");
14739                        printed = true;
14740                    }
14741                    pw.print("    "); pw.print(pkg); pw.print(": ");
14742                            pw.print(mode); pw.println();
14743                }
14744            }
14745        }
14746        if (dumpPackage == null) {
14747            pw.println("  mWakefulness="
14748                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14749            pw.println("  mSleepTokens=" + mSleepTokens);
14750            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14751                    + lockScreenShownToString());
14752            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14753            if (mRunningVoice != null) {
14754                pw.println("  mRunningVoice=" + mRunningVoice);
14755                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14756            }
14757        }
14758        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14759                || mOrigWaitForDebugger) {
14760            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14761                    || dumpPackage.equals(mOrigDebugApp)) {
14762                if (needSep) {
14763                    pw.println();
14764                    needSep = false;
14765                }
14766                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14767                        + " mDebugTransient=" + mDebugTransient
14768                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14769            }
14770        }
14771        if (mCurAppTimeTracker != null) {
14772            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14773        }
14774        if (mMemWatchProcesses.getMap().size() > 0) {
14775            pw.println("  Mem watch processes:");
14776            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14777                    = mMemWatchProcesses.getMap();
14778            for (int i=0; i<procs.size(); i++) {
14779                final String proc = procs.keyAt(i);
14780                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14781                for (int j=0; j<uids.size(); j++) {
14782                    if (needSep) {
14783                        pw.println();
14784                        needSep = false;
14785                    }
14786                    StringBuilder sb = new StringBuilder();
14787                    sb.append("    ").append(proc).append('/');
14788                    UserHandle.formatUid(sb, uids.keyAt(j));
14789                    Pair<Long, String> val = uids.valueAt(j);
14790                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14791                    if (val.second != null) {
14792                        sb.append(", report to ").append(val.second);
14793                    }
14794                    pw.println(sb.toString());
14795                }
14796            }
14797            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14798            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14799            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14800                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14801        }
14802        if (mTrackAllocationApp != null) {
14803            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14804                if (needSep) {
14805                    pw.println();
14806                    needSep = false;
14807                }
14808                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14809            }
14810        }
14811        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14812                || mProfileFd != null) {
14813            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14814                if (needSep) {
14815                    pw.println();
14816                    needSep = false;
14817                }
14818                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14819                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14820                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14821                        + mAutoStopProfiler);
14822                pw.println("  mProfileType=" + mProfileType);
14823            }
14824        }
14825        if (mNativeDebuggingApp != null) {
14826            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14827                if (needSep) {
14828                    pw.println();
14829                    needSep = false;
14830                }
14831                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14832            }
14833        }
14834        if (dumpPackage == null) {
14835            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14836                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14837                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14838            }
14839            if (mController != null) {
14840                pw.println("  mController=" + mController
14841                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14842            }
14843            if (dumpAll) {
14844                pw.println("  Total persistent processes: " + numPers);
14845                pw.println("  mProcessesReady=" + mProcessesReady
14846                        + " mSystemReady=" + mSystemReady
14847                        + " mBooted=" + mBooted
14848                        + " mFactoryTest=" + mFactoryTest);
14849                pw.println("  mBooting=" + mBooting
14850                        + " mCallFinishBooting=" + mCallFinishBooting
14851                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14852                pw.print("  mLastPowerCheckRealtime=");
14853                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14854                        pw.println("");
14855                pw.print("  mLastPowerCheckUptime=");
14856                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14857                        pw.println("");
14858                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14859                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14860                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14861                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14862                        + " (" + mLruProcesses.size() + " total)"
14863                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14864                        + " mNumServiceProcs=" + mNumServiceProcs
14865                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14866                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14867                        + " mLastMemoryLevel=" + mLastMemoryLevel
14868                        + " mLastNumProcesses=" + mLastNumProcesses);
14869                long now = SystemClock.uptimeMillis();
14870                pw.print("  mLastIdleTime=");
14871                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14872                        pw.print(" mLowRamSinceLastIdle=");
14873                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14874                        pw.println();
14875            }
14876        }
14877
14878        if (!printedAnything) {
14879            pw.println("  (nothing)");
14880        }
14881    }
14882
14883    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14884            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14885        if (mProcessesToGc.size() > 0) {
14886            boolean printed = false;
14887            long now = SystemClock.uptimeMillis();
14888            for (int i=0; i<mProcessesToGc.size(); i++) {
14889                ProcessRecord proc = mProcessesToGc.get(i);
14890                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14891                    continue;
14892                }
14893                if (!printed) {
14894                    if (needSep) pw.println();
14895                    needSep = true;
14896                    pw.println("  Processes that are waiting to GC:");
14897                    printed = true;
14898                }
14899                pw.print("    Process "); pw.println(proc);
14900                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14901                        pw.print(", last gced=");
14902                        pw.print(now-proc.lastRequestedGc);
14903                        pw.print(" ms ago, last lowMem=");
14904                        pw.print(now-proc.lastLowMemory);
14905                        pw.println(" ms ago");
14906
14907            }
14908        }
14909        return needSep;
14910    }
14911
14912    void printOomLevel(PrintWriter pw, String name, int adj) {
14913        pw.print("    ");
14914        if (adj >= 0) {
14915            pw.print(' ');
14916            if (adj < 10) pw.print(' ');
14917        } else {
14918            if (adj > -10) pw.print(' ');
14919        }
14920        pw.print(adj);
14921        pw.print(": ");
14922        pw.print(name);
14923        pw.print(" (");
14924        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14925        pw.println(")");
14926    }
14927
14928    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14929            int opti, boolean dumpAll) {
14930        boolean needSep = false;
14931
14932        if (mLruProcesses.size() > 0) {
14933            if (needSep) pw.println();
14934            needSep = true;
14935            pw.println("  OOM levels:");
14936            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14937            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14938            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14939            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14940            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14941            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14942            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14943            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14944            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14945            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14946            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14947            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14948            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14949            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14950
14951            if (needSep) pw.println();
14952            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14953                    pw.print(" total, non-act at ");
14954                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14955                    pw.print(", non-svc at ");
14956                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14957                    pw.println("):");
14958            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14959            needSep = true;
14960        }
14961
14962        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14963
14964        pw.println();
14965        pw.println("  mHomeProcess: " + mHomeProcess);
14966        pw.println("  mPreviousProcess: " + mPreviousProcess);
14967        if (mHeavyWeightProcess != null) {
14968            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14969        }
14970
14971        return true;
14972    }
14973
14974    /**
14975     * There are three ways to call this:
14976     *  - no provider specified: dump all the providers
14977     *  - a flattened component name that matched an existing provider was specified as the
14978     *    first arg: dump that one provider
14979     *  - the first arg isn't the flattened component name of an existing provider:
14980     *    dump all providers whose component contains the first arg as a substring
14981     */
14982    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14983            int opti, boolean dumpAll) {
14984        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14985    }
14986
14987    static class ItemMatcher {
14988        ArrayList<ComponentName> components;
14989        ArrayList<String> strings;
14990        ArrayList<Integer> objects;
14991        boolean all;
14992
14993        ItemMatcher() {
14994            all = true;
14995        }
14996
14997        void build(String name) {
14998            ComponentName componentName = ComponentName.unflattenFromString(name);
14999            if (componentName != null) {
15000                if (components == null) {
15001                    components = new ArrayList<ComponentName>();
15002                }
15003                components.add(componentName);
15004                all = false;
15005            } else {
15006                int objectId = 0;
15007                // Not a '/' separated full component name; maybe an object ID?
15008                try {
15009                    objectId = Integer.parseInt(name, 16);
15010                    if (objects == null) {
15011                        objects = new ArrayList<Integer>();
15012                    }
15013                    objects.add(objectId);
15014                    all = false;
15015                } catch (RuntimeException e) {
15016                    // Not an integer; just do string match.
15017                    if (strings == null) {
15018                        strings = new ArrayList<String>();
15019                    }
15020                    strings.add(name);
15021                    all = false;
15022                }
15023            }
15024        }
15025
15026        int build(String[] args, int opti) {
15027            for (; opti<args.length; opti++) {
15028                String name = args[opti];
15029                if ("--".equals(name)) {
15030                    return opti+1;
15031                }
15032                build(name);
15033            }
15034            return opti;
15035        }
15036
15037        boolean match(Object object, ComponentName comp) {
15038            if (all) {
15039                return true;
15040            }
15041            if (components != null) {
15042                for (int i=0; i<components.size(); i++) {
15043                    if (components.get(i).equals(comp)) {
15044                        return true;
15045                    }
15046                }
15047            }
15048            if (objects != null) {
15049                for (int i=0; i<objects.size(); i++) {
15050                    if (System.identityHashCode(object) == objects.get(i)) {
15051                        return true;
15052                    }
15053                }
15054            }
15055            if (strings != null) {
15056                String flat = comp.flattenToString();
15057                for (int i=0; i<strings.size(); i++) {
15058                    if (flat.contains(strings.get(i))) {
15059                        return true;
15060                    }
15061                }
15062            }
15063            return false;
15064        }
15065    }
15066
15067    /**
15068     * There are three things that cmd can be:
15069     *  - a flattened component name that matches an existing activity
15070     *  - the cmd arg isn't the flattened component name of an existing activity:
15071     *    dump all activity whose component contains the cmd as a substring
15072     *  - A hex number of the ActivityRecord object instance.
15073     */
15074    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15075            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15076        ArrayList<ActivityRecord> activities;
15077
15078        synchronized (this) {
15079            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15080        }
15081
15082        if (activities.size() <= 0) {
15083            return false;
15084        }
15085
15086        String[] newArgs = new String[args.length - opti];
15087        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15088
15089        TaskRecord lastTask = null;
15090        boolean needSep = false;
15091        for (int i=activities.size()-1; i>=0; i--) {
15092            ActivityRecord r = activities.get(i);
15093            if (needSep) {
15094                pw.println();
15095            }
15096            needSep = true;
15097            synchronized (this) {
15098                if (lastTask != r.task) {
15099                    lastTask = r.task;
15100                    pw.print("TASK "); pw.print(lastTask.affinity);
15101                            pw.print(" id="); pw.print(lastTask.taskId);
15102                            pw.print(" userId="); pw.println(lastTask.userId);
15103                    if (dumpAll) {
15104                        lastTask.dump(pw, "  ");
15105                    }
15106                }
15107            }
15108            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15109        }
15110        return true;
15111    }
15112
15113    /**
15114     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15115     * there is a thread associated with the activity.
15116     */
15117    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15118            final ActivityRecord r, String[] args, boolean dumpAll) {
15119        String innerPrefix = prefix + "  ";
15120        synchronized (this) {
15121            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15122                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15123                    pw.print(" pid=");
15124                    if (r.app != null) pw.println(r.app.pid);
15125                    else pw.println("(not running)");
15126            if (dumpAll) {
15127                r.dump(pw, innerPrefix);
15128            }
15129        }
15130        if (r.app != null && r.app.thread != null) {
15131            // flush anything that is already in the PrintWriter since the thread is going
15132            // to write to the file descriptor directly
15133            pw.flush();
15134            try {
15135                TransferPipe tp = new TransferPipe();
15136                try {
15137                    r.app.thread.dumpActivity(tp.getWriteFd(),
15138                            r.appToken, innerPrefix, args);
15139                    tp.go(fd);
15140                } finally {
15141                    tp.kill();
15142                }
15143            } catch (IOException e) {
15144                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15145            } catch (RemoteException e) {
15146                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15147            }
15148        }
15149    }
15150
15151    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15152            int opti, boolean dumpAll, String dumpPackage) {
15153        boolean needSep = false;
15154        boolean onlyHistory = false;
15155        boolean printedAnything = false;
15156
15157        if ("history".equals(dumpPackage)) {
15158            if (opti < args.length && "-s".equals(args[opti])) {
15159                dumpAll = false;
15160            }
15161            onlyHistory = true;
15162            dumpPackage = null;
15163        }
15164
15165        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15166        if (!onlyHistory && dumpAll) {
15167            if (mRegisteredReceivers.size() > 0) {
15168                boolean printed = false;
15169                Iterator it = mRegisteredReceivers.values().iterator();
15170                while (it.hasNext()) {
15171                    ReceiverList r = (ReceiverList)it.next();
15172                    if (dumpPackage != null && (r.app == null ||
15173                            !dumpPackage.equals(r.app.info.packageName))) {
15174                        continue;
15175                    }
15176                    if (!printed) {
15177                        pw.println("  Registered Receivers:");
15178                        needSep = true;
15179                        printed = true;
15180                        printedAnything = true;
15181                    }
15182                    pw.print("  * "); pw.println(r);
15183                    r.dump(pw, "    ");
15184                }
15185            }
15186
15187            if (mReceiverResolver.dump(pw, needSep ?
15188                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15189                    "    ", dumpPackage, false, false)) {
15190                needSep = true;
15191                printedAnything = true;
15192            }
15193        }
15194
15195        for (BroadcastQueue q : mBroadcastQueues) {
15196            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15197            printedAnything |= needSep;
15198        }
15199
15200        needSep = true;
15201
15202        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15203            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15204                if (needSep) {
15205                    pw.println();
15206                }
15207                needSep = true;
15208                printedAnything = true;
15209                pw.print("  Sticky broadcasts for user ");
15210                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15211                StringBuilder sb = new StringBuilder(128);
15212                for (Map.Entry<String, ArrayList<Intent>> ent
15213                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15214                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15215                    if (dumpAll) {
15216                        pw.println(":");
15217                        ArrayList<Intent> intents = ent.getValue();
15218                        final int N = intents.size();
15219                        for (int i=0; i<N; i++) {
15220                            sb.setLength(0);
15221                            sb.append("    Intent: ");
15222                            intents.get(i).toShortString(sb, false, true, false, false);
15223                            pw.println(sb.toString());
15224                            Bundle bundle = intents.get(i).getExtras();
15225                            if (bundle != null) {
15226                                pw.print("      ");
15227                                pw.println(bundle.toString());
15228                            }
15229                        }
15230                    } else {
15231                        pw.println("");
15232                    }
15233                }
15234            }
15235        }
15236
15237        if (!onlyHistory && dumpAll) {
15238            pw.println();
15239            for (BroadcastQueue queue : mBroadcastQueues) {
15240                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15241                        + queue.mBroadcastsScheduled);
15242            }
15243            pw.println("  mHandler:");
15244            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15245            needSep = true;
15246            printedAnything = true;
15247        }
15248
15249        if (!printedAnything) {
15250            pw.println("  (nothing)");
15251        }
15252    }
15253
15254    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15255            int opti, boolean dumpAll, String dumpPackage) {
15256        if (mCurBroadcastStats == null) {
15257            return;
15258        }
15259
15260        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15261        final long now = SystemClock.elapsedRealtime();
15262        if (mLastBroadcastStats != null) {
15263            pw.print("  Last stats (from ");
15264            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15265            pw.print(" to ");
15266            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15267            pw.print(", ");
15268            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15269                    - mLastBroadcastStats.mStartUptime, pw);
15270            pw.println(" uptime):");
15271            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15272                pw.println("    (nothing)");
15273            }
15274            pw.println();
15275        }
15276        pw.print("  Current stats (from ");
15277        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15278        pw.print(" to now, ");
15279        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15280                - mCurBroadcastStats.mStartUptime, pw);
15281        pw.println(" uptime):");
15282        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15283            pw.println("    (nothing)");
15284        }
15285    }
15286
15287    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15288            int opti, boolean fullCheckin, String dumpPackage) {
15289        if (mCurBroadcastStats == null) {
15290            return;
15291        }
15292
15293        if (mLastBroadcastStats != null) {
15294            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15295            if (fullCheckin) {
15296                mLastBroadcastStats = null;
15297                return;
15298            }
15299        }
15300        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15301        if (fullCheckin) {
15302            mCurBroadcastStats = null;
15303        }
15304    }
15305
15306    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15307            int opti, boolean dumpAll, String dumpPackage) {
15308        boolean needSep;
15309        boolean printedAnything = false;
15310
15311        ItemMatcher matcher = new ItemMatcher();
15312        matcher.build(args, opti);
15313
15314        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15315
15316        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15317        printedAnything |= needSep;
15318
15319        if (mLaunchingProviders.size() > 0) {
15320            boolean printed = false;
15321            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15322                ContentProviderRecord r = mLaunchingProviders.get(i);
15323                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15324                    continue;
15325                }
15326                if (!printed) {
15327                    if (needSep) pw.println();
15328                    needSep = true;
15329                    pw.println("  Launching content providers:");
15330                    printed = true;
15331                    printedAnything = true;
15332                }
15333                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15334                        pw.println(r);
15335            }
15336        }
15337
15338        if (!printedAnything) {
15339            pw.println("  (nothing)");
15340        }
15341    }
15342
15343    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15344            int opti, boolean dumpAll, String dumpPackage) {
15345        boolean needSep = false;
15346        boolean printedAnything = false;
15347
15348        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15349
15350        if (mGrantedUriPermissions.size() > 0) {
15351            boolean printed = false;
15352            int dumpUid = -2;
15353            if (dumpPackage != null) {
15354                try {
15355                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15356                            MATCH_UNINSTALLED_PACKAGES, 0);
15357                } catch (NameNotFoundException e) {
15358                    dumpUid = -1;
15359                }
15360            }
15361            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15362                int uid = mGrantedUriPermissions.keyAt(i);
15363                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15364                    continue;
15365                }
15366                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15367                if (!printed) {
15368                    if (needSep) pw.println();
15369                    needSep = true;
15370                    pw.println("  Granted Uri Permissions:");
15371                    printed = true;
15372                    printedAnything = true;
15373                }
15374                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15375                for (UriPermission perm : perms.values()) {
15376                    pw.print("    "); pw.println(perm);
15377                    if (dumpAll) {
15378                        perm.dump(pw, "      ");
15379                    }
15380                }
15381            }
15382        }
15383
15384        if (!printedAnything) {
15385            pw.println("  (nothing)");
15386        }
15387    }
15388
15389    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15390            int opti, boolean dumpAll, String dumpPackage) {
15391        boolean printed = false;
15392
15393        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15394
15395        if (mIntentSenderRecords.size() > 0) {
15396            Iterator<WeakReference<PendingIntentRecord>> it
15397                    = mIntentSenderRecords.values().iterator();
15398            while (it.hasNext()) {
15399                WeakReference<PendingIntentRecord> ref = it.next();
15400                PendingIntentRecord rec = ref != null ? ref.get(): null;
15401                if (dumpPackage != null && (rec == null
15402                        || !dumpPackage.equals(rec.key.packageName))) {
15403                    continue;
15404                }
15405                printed = true;
15406                if (rec != null) {
15407                    pw.print("  * "); pw.println(rec);
15408                    if (dumpAll) {
15409                        rec.dump(pw, "    ");
15410                    }
15411                } else {
15412                    pw.print("  * "); pw.println(ref);
15413                }
15414            }
15415        }
15416
15417        if (!printed) {
15418            pw.println("  (nothing)");
15419        }
15420    }
15421
15422    private static final int dumpProcessList(PrintWriter pw,
15423            ActivityManagerService service, List list,
15424            String prefix, String normalLabel, String persistentLabel,
15425            String dumpPackage) {
15426        int numPers = 0;
15427        final int N = list.size()-1;
15428        for (int i=N; i>=0; i--) {
15429            ProcessRecord r = (ProcessRecord)list.get(i);
15430            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15431                continue;
15432            }
15433            pw.println(String.format("%s%s #%2d: %s",
15434                    prefix, (r.persistent ? persistentLabel : normalLabel),
15435                    i, r.toString()));
15436            if (r.persistent) {
15437                numPers++;
15438            }
15439        }
15440        return numPers;
15441    }
15442
15443    private static final boolean dumpProcessOomList(PrintWriter pw,
15444            ActivityManagerService service, List<ProcessRecord> origList,
15445            String prefix, String normalLabel, String persistentLabel,
15446            boolean inclDetails, String dumpPackage) {
15447
15448        ArrayList<Pair<ProcessRecord, Integer>> list
15449                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15450        for (int i=0; i<origList.size(); i++) {
15451            ProcessRecord r = origList.get(i);
15452            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15453                continue;
15454            }
15455            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15456        }
15457
15458        if (list.size() <= 0) {
15459            return false;
15460        }
15461
15462        Comparator<Pair<ProcessRecord, Integer>> comparator
15463                = new Comparator<Pair<ProcessRecord, Integer>>() {
15464            @Override
15465            public int compare(Pair<ProcessRecord, Integer> object1,
15466                    Pair<ProcessRecord, Integer> object2) {
15467                if (object1.first.setAdj != object2.first.setAdj) {
15468                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15469                }
15470                if (object1.first.setProcState != object2.first.setProcState) {
15471                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15472                }
15473                if (object1.second.intValue() != object2.second.intValue()) {
15474                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15475                }
15476                return 0;
15477            }
15478        };
15479
15480        Collections.sort(list, comparator);
15481
15482        final long curRealtime = SystemClock.elapsedRealtime();
15483        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15484        final long curUptime = SystemClock.uptimeMillis();
15485        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15486
15487        for (int i=list.size()-1; i>=0; i--) {
15488            ProcessRecord r = list.get(i).first;
15489            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15490            char schedGroup;
15491            switch (r.setSchedGroup) {
15492                case ProcessList.SCHED_GROUP_BACKGROUND:
15493                    schedGroup = 'B';
15494                    break;
15495                case ProcessList.SCHED_GROUP_DEFAULT:
15496                    schedGroup = 'F';
15497                    break;
15498                case ProcessList.SCHED_GROUP_TOP_APP:
15499                    schedGroup = 'T';
15500                    break;
15501                default:
15502                    schedGroup = '?';
15503                    break;
15504            }
15505            char foreground;
15506            if (r.foregroundActivities) {
15507                foreground = 'A';
15508            } else if (r.foregroundServices) {
15509                foreground = 'S';
15510            } else {
15511                foreground = ' ';
15512            }
15513            String procState = ProcessList.makeProcStateString(r.curProcState);
15514            pw.print(prefix);
15515            pw.print(r.persistent ? persistentLabel : normalLabel);
15516            pw.print(" #");
15517            int num = (origList.size()-1)-list.get(i).second;
15518            if (num < 10) pw.print(' ');
15519            pw.print(num);
15520            pw.print(": ");
15521            pw.print(oomAdj);
15522            pw.print(' ');
15523            pw.print(schedGroup);
15524            pw.print('/');
15525            pw.print(foreground);
15526            pw.print('/');
15527            pw.print(procState);
15528            pw.print(" trm:");
15529            if (r.trimMemoryLevel < 10) pw.print(' ');
15530            pw.print(r.trimMemoryLevel);
15531            pw.print(' ');
15532            pw.print(r.toShortString());
15533            pw.print(" (");
15534            pw.print(r.adjType);
15535            pw.println(')');
15536            if (r.adjSource != null || r.adjTarget != null) {
15537                pw.print(prefix);
15538                pw.print("    ");
15539                if (r.adjTarget instanceof ComponentName) {
15540                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15541                } else if (r.adjTarget != null) {
15542                    pw.print(r.adjTarget.toString());
15543                } else {
15544                    pw.print("{null}");
15545                }
15546                pw.print("<=");
15547                if (r.adjSource instanceof ProcessRecord) {
15548                    pw.print("Proc{");
15549                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15550                    pw.println("}");
15551                } else if (r.adjSource != null) {
15552                    pw.println(r.adjSource.toString());
15553                } else {
15554                    pw.println("{null}");
15555                }
15556            }
15557            if (inclDetails) {
15558                pw.print(prefix);
15559                pw.print("    ");
15560                pw.print("oom: max="); pw.print(r.maxAdj);
15561                pw.print(" curRaw="); pw.print(r.curRawAdj);
15562                pw.print(" setRaw="); pw.print(r.setRawAdj);
15563                pw.print(" cur="); pw.print(r.curAdj);
15564                pw.print(" set="); pw.println(r.setAdj);
15565                pw.print(prefix);
15566                pw.print("    ");
15567                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15568                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15569                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15570                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15571                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15572                pw.println();
15573                pw.print(prefix);
15574                pw.print("    ");
15575                pw.print("cached="); pw.print(r.cached);
15576                pw.print(" empty="); pw.print(r.empty);
15577                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15578
15579                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15580                    if (r.lastWakeTime != 0) {
15581                        long wtime;
15582                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15583                        synchronized (stats) {
15584                            wtime = stats.getProcessWakeTime(r.info.uid,
15585                                    r.pid, curRealtime);
15586                        }
15587                        long timeUsed = wtime - r.lastWakeTime;
15588                        pw.print(prefix);
15589                        pw.print("    ");
15590                        pw.print("keep awake over ");
15591                        TimeUtils.formatDuration(realtimeSince, pw);
15592                        pw.print(" used ");
15593                        TimeUtils.formatDuration(timeUsed, pw);
15594                        pw.print(" (");
15595                        pw.print((timeUsed*100)/realtimeSince);
15596                        pw.println("%)");
15597                    }
15598                    if (r.lastCpuTime != 0) {
15599                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15600                        pw.print(prefix);
15601                        pw.print("    ");
15602                        pw.print("run cpu over ");
15603                        TimeUtils.formatDuration(uptimeSince, pw);
15604                        pw.print(" used ");
15605                        TimeUtils.formatDuration(timeUsed, pw);
15606                        pw.print(" (");
15607                        pw.print((timeUsed*100)/uptimeSince);
15608                        pw.println("%)");
15609                    }
15610                }
15611            }
15612        }
15613        return true;
15614    }
15615
15616    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15617            String[] args) {
15618        ArrayList<ProcessRecord> procs;
15619        synchronized (this) {
15620            if (args != null && args.length > start
15621                    && args[start].charAt(0) != '-') {
15622                procs = new ArrayList<ProcessRecord>();
15623                int pid = -1;
15624                try {
15625                    pid = Integer.parseInt(args[start]);
15626                } catch (NumberFormatException e) {
15627                }
15628                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15629                    ProcessRecord proc = mLruProcesses.get(i);
15630                    if (proc.pid == pid) {
15631                        procs.add(proc);
15632                    } else if (allPkgs && proc.pkgList != null
15633                            && proc.pkgList.containsKey(args[start])) {
15634                        procs.add(proc);
15635                    } else if (proc.processName.equals(args[start])) {
15636                        procs.add(proc);
15637                    }
15638                }
15639                if (procs.size() <= 0) {
15640                    return null;
15641                }
15642            } else {
15643                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15644            }
15645        }
15646        return procs;
15647    }
15648
15649    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15650            PrintWriter pw, String[] args) {
15651        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15652        if (procs == null) {
15653            pw.println("No process found for: " + args[0]);
15654            return;
15655        }
15656
15657        long uptime = SystemClock.uptimeMillis();
15658        long realtime = SystemClock.elapsedRealtime();
15659        pw.println("Applications Graphics Acceleration Info:");
15660        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15661
15662        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15663            ProcessRecord r = procs.get(i);
15664            if (r.thread != null) {
15665                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15666                pw.flush();
15667                try {
15668                    TransferPipe tp = new TransferPipe();
15669                    try {
15670                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15671                        tp.go(fd);
15672                    } finally {
15673                        tp.kill();
15674                    }
15675                } catch (IOException e) {
15676                    pw.println("Failure while dumping the app: " + r);
15677                    pw.flush();
15678                } catch (RemoteException e) {
15679                    pw.println("Got a RemoteException while dumping the app " + r);
15680                    pw.flush();
15681                }
15682            }
15683        }
15684    }
15685
15686    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15687        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15688        if (procs == null) {
15689            pw.println("No process found for: " + args[0]);
15690            return;
15691        }
15692
15693        pw.println("Applications Database Info:");
15694
15695        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15696            ProcessRecord r = procs.get(i);
15697            if (r.thread != null) {
15698                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15699                pw.flush();
15700                try {
15701                    TransferPipe tp = new TransferPipe();
15702                    try {
15703                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15704                        tp.go(fd);
15705                    } finally {
15706                        tp.kill();
15707                    }
15708                } catch (IOException e) {
15709                    pw.println("Failure while dumping the app: " + r);
15710                    pw.flush();
15711                } catch (RemoteException e) {
15712                    pw.println("Got a RemoteException while dumping the app " + r);
15713                    pw.flush();
15714                }
15715            }
15716        }
15717    }
15718
15719    final static class MemItem {
15720        final boolean isProc;
15721        final String label;
15722        final String shortLabel;
15723        final long pss;
15724        final long swapPss;
15725        final int id;
15726        final boolean hasActivities;
15727        ArrayList<MemItem> subitems;
15728
15729        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15730                boolean _hasActivities) {
15731            isProc = true;
15732            label = _label;
15733            shortLabel = _shortLabel;
15734            pss = _pss;
15735            swapPss = _swapPss;
15736            id = _id;
15737            hasActivities = _hasActivities;
15738        }
15739
15740        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15741            isProc = false;
15742            label = _label;
15743            shortLabel = _shortLabel;
15744            pss = _pss;
15745            swapPss = _swapPss;
15746            id = _id;
15747            hasActivities = false;
15748        }
15749    }
15750
15751    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15752            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15753        if (sort && !isCompact) {
15754            Collections.sort(items, new Comparator<MemItem>() {
15755                @Override
15756                public int compare(MemItem lhs, MemItem rhs) {
15757                    if (lhs.pss < rhs.pss) {
15758                        return 1;
15759                    } else if (lhs.pss > rhs.pss) {
15760                        return -1;
15761                    }
15762                    return 0;
15763                }
15764            });
15765        }
15766
15767        for (int i=0; i<items.size(); i++) {
15768            MemItem mi = items.get(i);
15769            if (!isCompact) {
15770                if (dumpSwapPss) {
15771                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15772                            mi.label, stringifyKBSize(mi.swapPss));
15773                } else {
15774                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15775                }
15776            } else if (mi.isProc) {
15777                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15778                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15779                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15780                pw.println(mi.hasActivities ? ",a" : ",e");
15781            } else {
15782                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15783                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15784            }
15785            if (mi.subitems != null) {
15786                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15787                        true, isCompact, dumpSwapPss);
15788            }
15789        }
15790    }
15791
15792    // These are in KB.
15793    static final long[] DUMP_MEM_BUCKETS = new long[] {
15794        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15795        120*1024, 160*1024, 200*1024,
15796        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15797        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15798    };
15799
15800    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15801            boolean stackLike) {
15802        int start = label.lastIndexOf('.');
15803        if (start >= 0) start++;
15804        else start = 0;
15805        int end = label.length();
15806        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15807            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15808                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15809                out.append(bucket);
15810                out.append(stackLike ? "MB." : "MB ");
15811                out.append(label, start, end);
15812                return;
15813            }
15814        }
15815        out.append(memKB/1024);
15816        out.append(stackLike ? "MB." : "MB ");
15817        out.append(label, start, end);
15818    }
15819
15820    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15821            ProcessList.NATIVE_ADJ,
15822            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15823            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15824            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15825            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15826            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15827            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15828    };
15829    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15830            "Native",
15831            "System", "Persistent", "Persistent Service", "Foreground",
15832            "Visible", "Perceptible",
15833            "Heavy Weight", "Backup",
15834            "A Services", "Home",
15835            "Previous", "B Services", "Cached"
15836    };
15837    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15838            "native",
15839            "sys", "pers", "persvc", "fore",
15840            "vis", "percept",
15841            "heavy", "backup",
15842            "servicea", "home",
15843            "prev", "serviceb", "cached"
15844    };
15845
15846    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15847            long realtime, boolean isCheckinRequest, boolean isCompact) {
15848        if (isCompact) {
15849            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15850        }
15851        if (isCheckinRequest || isCompact) {
15852            // short checkin version
15853            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15854        } else {
15855            pw.println("Applications Memory Usage (in Kilobytes):");
15856            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15857        }
15858    }
15859
15860    private static final int KSM_SHARED = 0;
15861    private static final int KSM_SHARING = 1;
15862    private static final int KSM_UNSHARED = 2;
15863    private static final int KSM_VOLATILE = 3;
15864
15865    private final long[] getKsmInfo() {
15866        long[] longOut = new long[4];
15867        final int[] SINGLE_LONG_FORMAT = new int[] {
15868            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15869        };
15870        long[] longTmp = new long[1];
15871        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15872                SINGLE_LONG_FORMAT, null, longTmp, null);
15873        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15874        longTmp[0] = 0;
15875        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15876                SINGLE_LONG_FORMAT, null, longTmp, null);
15877        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15878        longTmp[0] = 0;
15879        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15880                SINGLE_LONG_FORMAT, null, longTmp, null);
15881        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15882        longTmp[0] = 0;
15883        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15884                SINGLE_LONG_FORMAT, null, longTmp, null);
15885        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15886        return longOut;
15887    }
15888
15889    private static String stringifySize(long size, int order) {
15890        Locale locale = Locale.US;
15891        switch (order) {
15892            case 1:
15893                return String.format(locale, "%,13d", size);
15894            case 1024:
15895                return String.format(locale, "%,9dK", size / 1024);
15896            case 1024 * 1024:
15897                return String.format(locale, "%,5dM", size / 1024 / 1024);
15898            case 1024 * 1024 * 1024:
15899                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15900            default:
15901                throw new IllegalArgumentException("Invalid size order");
15902        }
15903    }
15904
15905    private static String stringifyKBSize(long size) {
15906        return stringifySize(size * 1024, 1024);
15907    }
15908
15909    // Update this version number in case you change the 'compact' format
15910    private static final int MEMINFO_COMPACT_VERSION = 1;
15911
15912    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15913            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15914        boolean dumpDetails = false;
15915        boolean dumpFullDetails = false;
15916        boolean dumpDalvik = false;
15917        boolean dumpSummaryOnly = false;
15918        boolean dumpUnreachable = false;
15919        boolean oomOnly = false;
15920        boolean isCompact = false;
15921        boolean localOnly = false;
15922        boolean packages = false;
15923        boolean isCheckinRequest = false;
15924        boolean dumpSwapPss = false;
15925
15926        int opti = 0;
15927        while (opti < args.length) {
15928            String opt = args[opti];
15929            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15930                break;
15931            }
15932            opti++;
15933            if ("-a".equals(opt)) {
15934                dumpDetails = true;
15935                dumpFullDetails = true;
15936                dumpDalvik = true;
15937                dumpSwapPss = true;
15938            } else if ("-d".equals(opt)) {
15939                dumpDalvik = true;
15940            } else if ("-c".equals(opt)) {
15941                isCompact = true;
15942            } else if ("-s".equals(opt)) {
15943                dumpDetails = true;
15944                dumpSummaryOnly = true;
15945            } else if ("-S".equals(opt)) {
15946                dumpSwapPss = true;
15947            } else if ("--unreachable".equals(opt)) {
15948                dumpUnreachable = true;
15949            } else if ("--oom".equals(opt)) {
15950                oomOnly = true;
15951            } else if ("--local".equals(opt)) {
15952                localOnly = true;
15953            } else if ("--package".equals(opt)) {
15954                packages = true;
15955            } else if ("--checkin".equals(opt)) {
15956                isCheckinRequest = true;
15957
15958            } else if ("-h".equals(opt)) {
15959                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15960                pw.println("  -a: include all available information for each process.");
15961                pw.println("  -d: include dalvik details.");
15962                pw.println("  -c: dump in a compact machine-parseable representation.");
15963                pw.println("  -s: dump only summary of application memory usage.");
15964                pw.println("  -S: dump also SwapPss.");
15965                pw.println("  --oom: only show processes organized by oom adj.");
15966                pw.println("  --local: only collect details locally, don't call process.");
15967                pw.println("  --package: interpret process arg as package, dumping all");
15968                pw.println("             processes that have loaded that package.");
15969                pw.println("  --checkin: dump data for a checkin");
15970                pw.println("If [process] is specified it can be the name or ");
15971                pw.println("pid of a specific process to dump.");
15972                return;
15973            } else {
15974                pw.println("Unknown argument: " + opt + "; use -h for help");
15975            }
15976        }
15977
15978        long uptime = SystemClock.uptimeMillis();
15979        long realtime = SystemClock.elapsedRealtime();
15980        final long[] tmpLong = new long[1];
15981
15982        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15983        if (procs == null) {
15984            // No Java processes.  Maybe they want to print a native process.
15985            if (args != null && args.length > opti
15986                    && args[opti].charAt(0) != '-') {
15987                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15988                        = new ArrayList<ProcessCpuTracker.Stats>();
15989                updateCpuStatsNow();
15990                int findPid = -1;
15991                try {
15992                    findPid = Integer.parseInt(args[opti]);
15993                } catch (NumberFormatException e) {
15994                }
15995                synchronized (mProcessCpuTracker) {
15996                    final int N = mProcessCpuTracker.countStats();
15997                    for (int i=0; i<N; i++) {
15998                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15999                        if (st.pid == findPid || (st.baseName != null
16000                                && st.baseName.equals(args[opti]))) {
16001                            nativeProcs.add(st);
16002                        }
16003                    }
16004                }
16005                if (nativeProcs.size() > 0) {
16006                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16007                            isCompact);
16008                    Debug.MemoryInfo mi = null;
16009                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16010                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16011                        final int pid = r.pid;
16012                        if (!isCheckinRequest && dumpDetails) {
16013                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16014                        }
16015                        if (mi == null) {
16016                            mi = new Debug.MemoryInfo();
16017                        }
16018                        if (dumpDetails || (!brief && !oomOnly)) {
16019                            Debug.getMemoryInfo(pid, mi);
16020                        } else {
16021                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16022                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16023                        }
16024                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16025                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16026                        if (isCheckinRequest) {
16027                            pw.println();
16028                        }
16029                    }
16030                    return;
16031                }
16032            }
16033            pw.println("No process found for: " + args[opti]);
16034            return;
16035        }
16036
16037        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16038            dumpDetails = true;
16039        }
16040
16041        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16042
16043        String[] innerArgs = new String[args.length-opti];
16044        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16045
16046        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16047        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16048        long nativePss = 0;
16049        long nativeSwapPss = 0;
16050        long dalvikPss = 0;
16051        long dalvikSwapPss = 0;
16052        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16053                EmptyArray.LONG;
16054        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16055                EmptyArray.LONG;
16056        long otherPss = 0;
16057        long otherSwapPss = 0;
16058        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16059        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16060
16061        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16062        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16063        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16064                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16065
16066        long totalPss = 0;
16067        long totalSwapPss = 0;
16068        long cachedPss = 0;
16069        long cachedSwapPss = 0;
16070        boolean hasSwapPss = false;
16071
16072        Debug.MemoryInfo mi = null;
16073        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16074            final ProcessRecord r = procs.get(i);
16075            final IApplicationThread thread;
16076            final int pid;
16077            final int oomAdj;
16078            final boolean hasActivities;
16079            synchronized (this) {
16080                thread = r.thread;
16081                pid = r.pid;
16082                oomAdj = r.getSetAdjWithServices();
16083                hasActivities = r.activities.size() > 0;
16084            }
16085            if (thread != null) {
16086                if (!isCheckinRequest && dumpDetails) {
16087                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16088                }
16089                if (mi == null) {
16090                    mi = new Debug.MemoryInfo();
16091                }
16092                if (dumpDetails || (!brief && !oomOnly)) {
16093                    Debug.getMemoryInfo(pid, mi);
16094                    hasSwapPss = mi.hasSwappedOutPss;
16095                } else {
16096                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16097                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16098                }
16099                if (dumpDetails) {
16100                    if (localOnly) {
16101                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16102                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16103                        if (isCheckinRequest) {
16104                            pw.println();
16105                        }
16106                    } else {
16107                        pw.flush();
16108                        try {
16109                            TransferPipe tp = new TransferPipe();
16110                            try {
16111                                thread.dumpMemInfo(tp.getWriteFd(),
16112                                        mi, isCheckinRequest, dumpFullDetails,
16113                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16114                                tp.go(fd);
16115                            } finally {
16116                                tp.kill();
16117                            }
16118                        } catch (IOException e) {
16119                            if (!isCheckinRequest) {
16120                                pw.println("Got IoException!");
16121                                pw.flush();
16122                            }
16123                        } catch (RemoteException e) {
16124                            if (!isCheckinRequest) {
16125                                pw.println("Got RemoteException!");
16126                                pw.flush();
16127                            }
16128                        }
16129                    }
16130                }
16131
16132                final long myTotalPss = mi.getTotalPss();
16133                final long myTotalUss = mi.getTotalUss();
16134                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16135
16136                synchronized (this) {
16137                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16138                        // Record this for posterity if the process has been stable.
16139                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16140                    }
16141                }
16142
16143                if (!isCheckinRequest && mi != null) {
16144                    totalPss += myTotalPss;
16145                    totalSwapPss += myTotalSwapPss;
16146                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16147                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16148                            myTotalSwapPss, pid, hasActivities);
16149                    procMems.add(pssItem);
16150                    procMemsMap.put(pid, pssItem);
16151
16152                    nativePss += mi.nativePss;
16153                    nativeSwapPss += mi.nativeSwappedOutPss;
16154                    dalvikPss += mi.dalvikPss;
16155                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16156                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16157                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16158                        dalvikSubitemSwapPss[j] +=
16159                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16160                    }
16161                    otherPss += mi.otherPss;
16162                    otherSwapPss += mi.otherSwappedOutPss;
16163                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16164                        long mem = mi.getOtherPss(j);
16165                        miscPss[j] += mem;
16166                        otherPss -= mem;
16167                        mem = mi.getOtherSwappedOutPss(j);
16168                        miscSwapPss[j] += mem;
16169                        otherSwapPss -= mem;
16170                    }
16171
16172                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16173                        cachedPss += myTotalPss;
16174                        cachedSwapPss += myTotalSwapPss;
16175                    }
16176
16177                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16178                        if (oomIndex == (oomPss.length - 1)
16179                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16180                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16181                            oomPss[oomIndex] += myTotalPss;
16182                            oomSwapPss[oomIndex] += myTotalSwapPss;
16183                            if (oomProcs[oomIndex] == null) {
16184                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16185                            }
16186                            oomProcs[oomIndex].add(pssItem);
16187                            break;
16188                        }
16189                    }
16190                }
16191            }
16192        }
16193
16194        long nativeProcTotalPss = 0;
16195
16196        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16197            // If we are showing aggregations, also look for native processes to
16198            // include so that our aggregations are more accurate.
16199            updateCpuStatsNow();
16200            mi = null;
16201            synchronized (mProcessCpuTracker) {
16202                final int N = mProcessCpuTracker.countStats();
16203                for (int i=0; i<N; i++) {
16204                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16205                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16206                        if (mi == null) {
16207                            mi = new Debug.MemoryInfo();
16208                        }
16209                        if (!brief && !oomOnly) {
16210                            Debug.getMemoryInfo(st.pid, mi);
16211                        } else {
16212                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16213                            mi.nativePrivateDirty = (int)tmpLong[0];
16214                        }
16215
16216                        final long myTotalPss = mi.getTotalPss();
16217                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16218                        totalPss += myTotalPss;
16219                        nativeProcTotalPss += myTotalPss;
16220
16221                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16222                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16223                        procMems.add(pssItem);
16224
16225                        nativePss += mi.nativePss;
16226                        nativeSwapPss += mi.nativeSwappedOutPss;
16227                        dalvikPss += mi.dalvikPss;
16228                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16229                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16230                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16231                            dalvikSubitemSwapPss[j] +=
16232                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16233                        }
16234                        otherPss += mi.otherPss;
16235                        otherSwapPss += mi.otherSwappedOutPss;
16236                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16237                            long mem = mi.getOtherPss(j);
16238                            miscPss[j] += mem;
16239                            otherPss -= mem;
16240                            mem = mi.getOtherSwappedOutPss(j);
16241                            miscSwapPss[j] += mem;
16242                            otherSwapPss -= mem;
16243                        }
16244                        oomPss[0] += myTotalPss;
16245                        oomSwapPss[0] += myTotalSwapPss;
16246                        if (oomProcs[0] == null) {
16247                            oomProcs[0] = new ArrayList<MemItem>();
16248                        }
16249                        oomProcs[0].add(pssItem);
16250                    }
16251                }
16252            }
16253
16254            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16255
16256            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16257            final MemItem dalvikItem =
16258                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16259            if (dalvikSubitemPss.length > 0) {
16260                dalvikItem.subitems = new ArrayList<MemItem>();
16261                for (int j=0; j<dalvikSubitemPss.length; j++) {
16262                    final String name = Debug.MemoryInfo.getOtherLabel(
16263                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16264                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16265                                    dalvikSubitemSwapPss[j], j));
16266                }
16267            }
16268            catMems.add(dalvikItem);
16269            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16270            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16271                String label = Debug.MemoryInfo.getOtherLabel(j);
16272                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16273            }
16274
16275            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16276            for (int j=0; j<oomPss.length; j++) {
16277                if (oomPss[j] != 0) {
16278                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16279                            : DUMP_MEM_OOM_LABEL[j];
16280                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16281                            DUMP_MEM_OOM_ADJ[j]);
16282                    item.subitems = oomProcs[j];
16283                    oomMems.add(item);
16284                }
16285            }
16286
16287            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16288            if (!brief && !oomOnly && !isCompact) {
16289                pw.println();
16290                pw.println("Total PSS by process:");
16291                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16292                pw.println();
16293            }
16294            if (!isCompact) {
16295                pw.println("Total PSS by OOM adjustment:");
16296            }
16297            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16298            if (!brief && !oomOnly) {
16299                PrintWriter out = categoryPw != null ? categoryPw : pw;
16300                if (!isCompact) {
16301                    out.println();
16302                    out.println("Total PSS by category:");
16303                }
16304                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16305            }
16306            if (!isCompact) {
16307                pw.println();
16308            }
16309            MemInfoReader memInfo = new MemInfoReader();
16310            memInfo.readMemInfo();
16311            if (nativeProcTotalPss > 0) {
16312                synchronized (this) {
16313                    final long cachedKb = memInfo.getCachedSizeKb();
16314                    final long freeKb = memInfo.getFreeSizeKb();
16315                    final long zramKb = memInfo.getZramTotalSizeKb();
16316                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16317                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16318                            kernelKb*1024, nativeProcTotalPss*1024);
16319                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16320                            nativeProcTotalPss);
16321                }
16322            }
16323            if (!brief) {
16324                if (!isCompact) {
16325                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16326                    pw.print(" (status ");
16327                    switch (mLastMemoryLevel) {
16328                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16329                            pw.println("normal)");
16330                            break;
16331                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16332                            pw.println("moderate)");
16333                            break;
16334                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16335                            pw.println("low)");
16336                            break;
16337                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16338                            pw.println("critical)");
16339                            break;
16340                        default:
16341                            pw.print(mLastMemoryLevel);
16342                            pw.println(")");
16343                            break;
16344                    }
16345                    pw.print(" Free RAM: ");
16346                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16347                            + memInfo.getFreeSizeKb()));
16348                    pw.print(" (");
16349                    pw.print(stringifyKBSize(cachedPss));
16350                    pw.print(" cached pss + ");
16351                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16352                    pw.print(" cached kernel + ");
16353                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16354                    pw.println(" free)");
16355                } else {
16356                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16357                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16358                            + memInfo.getFreeSizeKb()); pw.print(",");
16359                    pw.println(totalPss - cachedPss);
16360                }
16361            }
16362            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16363                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16364                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16365            if (!isCompact) {
16366                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16367                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16368                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16369                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16370                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16371            } else {
16372                pw.print("lostram,"); pw.println(lostRAM);
16373            }
16374            if (!brief) {
16375                if (memInfo.getZramTotalSizeKb() != 0) {
16376                    if (!isCompact) {
16377                        pw.print("     ZRAM: ");
16378                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16379                                pw.print(" physical used for ");
16380                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16381                                        - memInfo.getSwapFreeSizeKb()));
16382                                pw.print(" in swap (");
16383                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16384                                pw.println(" total swap)");
16385                    } else {
16386                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16387                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16388                                pw.println(memInfo.getSwapFreeSizeKb());
16389                    }
16390                }
16391                final long[] ksm = getKsmInfo();
16392                if (!isCompact) {
16393                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16394                            || ksm[KSM_VOLATILE] != 0) {
16395                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16396                                pw.print(" saved from shared ");
16397                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16398                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16399                                pw.print(" unshared; ");
16400                                pw.print(stringifyKBSize(
16401                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16402                    }
16403                    pw.print("   Tuning: ");
16404                    pw.print(ActivityManager.staticGetMemoryClass());
16405                    pw.print(" (large ");
16406                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16407                    pw.print("), oom ");
16408                    pw.print(stringifySize(
16409                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16410                    pw.print(", restore limit ");
16411                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16412                    if (ActivityManager.isLowRamDeviceStatic()) {
16413                        pw.print(" (low-ram)");
16414                    }
16415                    if (ActivityManager.isHighEndGfx()) {
16416                        pw.print(" (high-end-gfx)");
16417                    }
16418                    pw.println();
16419                } else {
16420                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16421                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16422                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16423                    pw.print("tuning,");
16424                    pw.print(ActivityManager.staticGetMemoryClass());
16425                    pw.print(',');
16426                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16427                    pw.print(',');
16428                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16429                    if (ActivityManager.isLowRamDeviceStatic()) {
16430                        pw.print(",low-ram");
16431                    }
16432                    if (ActivityManager.isHighEndGfx()) {
16433                        pw.print(",high-end-gfx");
16434                    }
16435                    pw.println();
16436                }
16437            }
16438        }
16439    }
16440
16441    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16442            long memtrack, String name) {
16443        sb.append("  ");
16444        sb.append(ProcessList.makeOomAdjString(oomAdj));
16445        sb.append(' ');
16446        sb.append(ProcessList.makeProcStateString(procState));
16447        sb.append(' ');
16448        ProcessList.appendRamKb(sb, pss);
16449        sb.append(": ");
16450        sb.append(name);
16451        if (memtrack > 0) {
16452            sb.append(" (");
16453            sb.append(stringifyKBSize(memtrack));
16454            sb.append(" memtrack)");
16455        }
16456    }
16457
16458    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16459        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16460        sb.append(" (pid ");
16461        sb.append(mi.pid);
16462        sb.append(") ");
16463        sb.append(mi.adjType);
16464        sb.append('\n');
16465        if (mi.adjReason != null) {
16466            sb.append("                      ");
16467            sb.append(mi.adjReason);
16468            sb.append('\n');
16469        }
16470    }
16471
16472    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16473        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16474        for (int i=0, N=memInfos.size(); i<N; i++) {
16475            ProcessMemInfo mi = memInfos.get(i);
16476            infoMap.put(mi.pid, mi);
16477        }
16478        updateCpuStatsNow();
16479        long[] memtrackTmp = new long[1];
16480        final List<ProcessCpuTracker.Stats> stats;
16481        // Get a list of Stats that have vsize > 0
16482        synchronized (mProcessCpuTracker) {
16483            stats = mProcessCpuTracker.getStats((st) -> {
16484                return st.vsize > 0;
16485            });
16486        }
16487        final int statsCount = stats.size();
16488        for (int i = 0; i < statsCount; i++) {
16489            ProcessCpuTracker.Stats st = stats.get(i);
16490            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16491            if (pss > 0) {
16492                if (infoMap.indexOfKey(st.pid) < 0) {
16493                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16494                            ProcessList.NATIVE_ADJ, -1, "native", null);
16495                    mi.pss = pss;
16496                    mi.memtrack = memtrackTmp[0];
16497                    memInfos.add(mi);
16498                }
16499            }
16500        }
16501
16502        long totalPss = 0;
16503        long totalMemtrack = 0;
16504        for (int i=0, N=memInfos.size(); i<N; i++) {
16505            ProcessMemInfo mi = memInfos.get(i);
16506            if (mi.pss == 0) {
16507                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16508                mi.memtrack = memtrackTmp[0];
16509            }
16510            totalPss += mi.pss;
16511            totalMemtrack += mi.memtrack;
16512        }
16513        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16514            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16515                if (lhs.oomAdj != rhs.oomAdj) {
16516                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16517                }
16518                if (lhs.pss != rhs.pss) {
16519                    return lhs.pss < rhs.pss ? 1 : -1;
16520                }
16521                return 0;
16522            }
16523        });
16524
16525        StringBuilder tag = new StringBuilder(128);
16526        StringBuilder stack = new StringBuilder(128);
16527        tag.append("Low on memory -- ");
16528        appendMemBucket(tag, totalPss, "total", false);
16529        appendMemBucket(stack, totalPss, "total", true);
16530
16531        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16532        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16533        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16534
16535        boolean firstLine = true;
16536        int lastOomAdj = Integer.MIN_VALUE;
16537        long extraNativeRam = 0;
16538        long extraNativeMemtrack = 0;
16539        long cachedPss = 0;
16540        for (int i=0, N=memInfos.size(); i<N; i++) {
16541            ProcessMemInfo mi = memInfos.get(i);
16542
16543            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16544                cachedPss += mi.pss;
16545            }
16546
16547            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16548                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16549                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16550                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16551                if (lastOomAdj != mi.oomAdj) {
16552                    lastOomAdj = mi.oomAdj;
16553                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16554                        tag.append(" / ");
16555                    }
16556                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16557                        if (firstLine) {
16558                            stack.append(":");
16559                            firstLine = false;
16560                        }
16561                        stack.append("\n\t at ");
16562                    } else {
16563                        stack.append("$");
16564                    }
16565                } else {
16566                    tag.append(" ");
16567                    stack.append("$");
16568                }
16569                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16570                    appendMemBucket(tag, mi.pss, mi.name, false);
16571                }
16572                appendMemBucket(stack, mi.pss, mi.name, true);
16573                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16574                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16575                    stack.append("(");
16576                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16577                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16578                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16579                            stack.append(":");
16580                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16581                        }
16582                    }
16583                    stack.append(")");
16584                }
16585            }
16586
16587            appendMemInfo(fullNativeBuilder, mi);
16588            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16589                // The short form only has native processes that are >= 512K.
16590                if (mi.pss >= 512) {
16591                    appendMemInfo(shortNativeBuilder, mi);
16592                } else {
16593                    extraNativeRam += mi.pss;
16594                    extraNativeMemtrack += mi.memtrack;
16595                }
16596            } else {
16597                // Short form has all other details, but if we have collected RAM
16598                // from smaller native processes let's dump a summary of that.
16599                if (extraNativeRam > 0) {
16600                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16601                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16602                    shortNativeBuilder.append('\n');
16603                    extraNativeRam = 0;
16604                }
16605                appendMemInfo(fullJavaBuilder, mi);
16606            }
16607        }
16608
16609        fullJavaBuilder.append("           ");
16610        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16611        fullJavaBuilder.append(": TOTAL");
16612        if (totalMemtrack > 0) {
16613            fullJavaBuilder.append(" (");
16614            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16615            fullJavaBuilder.append(" memtrack)");
16616        } else {
16617        }
16618        fullJavaBuilder.append("\n");
16619
16620        MemInfoReader memInfo = new MemInfoReader();
16621        memInfo.readMemInfo();
16622        final long[] infos = memInfo.getRawInfo();
16623
16624        StringBuilder memInfoBuilder = new StringBuilder(1024);
16625        Debug.getMemInfo(infos);
16626        memInfoBuilder.append("  MemInfo: ");
16627        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16628        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16629        memInfoBuilder.append(stringifyKBSize(
16630                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16631        memInfoBuilder.append(stringifyKBSize(
16632                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16633        memInfoBuilder.append(stringifyKBSize(
16634                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16635        memInfoBuilder.append("           ");
16636        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16637        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16638        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16639        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16640        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16641            memInfoBuilder.append("  ZRAM: ");
16642            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16643            memInfoBuilder.append(" RAM, ");
16644            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16645            memInfoBuilder.append(" swap total, ");
16646            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16647            memInfoBuilder.append(" swap free\n");
16648        }
16649        final long[] ksm = getKsmInfo();
16650        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16651                || ksm[KSM_VOLATILE] != 0) {
16652            memInfoBuilder.append("  KSM: ");
16653            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16654            memInfoBuilder.append(" saved from shared ");
16655            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16656            memInfoBuilder.append("\n       ");
16657            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16658            memInfoBuilder.append(" unshared; ");
16659            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16660            memInfoBuilder.append(" volatile\n");
16661        }
16662        memInfoBuilder.append("  Free RAM: ");
16663        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16664                + memInfo.getFreeSizeKb()));
16665        memInfoBuilder.append("\n");
16666        memInfoBuilder.append("  Used RAM: ");
16667        memInfoBuilder.append(stringifyKBSize(
16668                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16669        memInfoBuilder.append("\n");
16670        memInfoBuilder.append("  Lost RAM: ");
16671        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16672                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16673                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16674        memInfoBuilder.append("\n");
16675        Slog.i(TAG, "Low on memory:");
16676        Slog.i(TAG, shortNativeBuilder.toString());
16677        Slog.i(TAG, fullJavaBuilder.toString());
16678        Slog.i(TAG, memInfoBuilder.toString());
16679
16680        StringBuilder dropBuilder = new StringBuilder(1024);
16681        /*
16682        StringWriter oomSw = new StringWriter();
16683        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16684        StringWriter catSw = new StringWriter();
16685        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16686        String[] emptyArgs = new String[] { };
16687        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16688        oomPw.flush();
16689        String oomString = oomSw.toString();
16690        */
16691        dropBuilder.append("Low on memory:");
16692        dropBuilder.append(stack);
16693        dropBuilder.append('\n');
16694        dropBuilder.append(fullNativeBuilder);
16695        dropBuilder.append(fullJavaBuilder);
16696        dropBuilder.append('\n');
16697        dropBuilder.append(memInfoBuilder);
16698        dropBuilder.append('\n');
16699        /*
16700        dropBuilder.append(oomString);
16701        dropBuilder.append('\n');
16702        */
16703        StringWriter catSw = new StringWriter();
16704        synchronized (ActivityManagerService.this) {
16705            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16706            String[] emptyArgs = new String[] { };
16707            catPw.println();
16708            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16709            catPw.println();
16710            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16711                    false, null).dumpLocked();
16712            catPw.println();
16713            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16714            catPw.flush();
16715        }
16716        dropBuilder.append(catSw.toString());
16717        addErrorToDropBox("lowmem", null, "system_server", null,
16718                null, tag.toString(), dropBuilder.toString(), null, null);
16719        //Slog.i(TAG, "Sent to dropbox:");
16720        //Slog.i(TAG, dropBuilder.toString());
16721        synchronized (ActivityManagerService.this) {
16722            long now = SystemClock.uptimeMillis();
16723            if (mLastMemUsageReportTime < now) {
16724                mLastMemUsageReportTime = now;
16725            }
16726        }
16727    }
16728
16729    /**
16730     * Searches array of arguments for the specified string
16731     * @param args array of argument strings
16732     * @param value value to search for
16733     * @return true if the value is contained in the array
16734     */
16735    private static boolean scanArgs(String[] args, String value) {
16736        if (args != null) {
16737            for (String arg : args) {
16738                if (value.equals(arg)) {
16739                    return true;
16740                }
16741            }
16742        }
16743        return false;
16744    }
16745
16746    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16747            ContentProviderRecord cpr, boolean always) {
16748        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16749
16750        if (!inLaunching || always) {
16751            synchronized (cpr) {
16752                cpr.launchingApp = null;
16753                cpr.notifyAll();
16754            }
16755            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16756            String names[] = cpr.info.authority.split(";");
16757            for (int j = 0; j < names.length; j++) {
16758                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16759            }
16760        }
16761
16762        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16763            ContentProviderConnection conn = cpr.connections.get(i);
16764            if (conn.waiting) {
16765                // If this connection is waiting for the provider, then we don't
16766                // need to mess with its process unless we are always removing
16767                // or for some reason the provider is not currently launching.
16768                if (inLaunching && !always) {
16769                    continue;
16770                }
16771            }
16772            ProcessRecord capp = conn.client;
16773            conn.dead = true;
16774            if (conn.stableCount > 0) {
16775                if (!capp.persistent && capp.thread != null
16776                        && capp.pid != 0
16777                        && capp.pid != MY_PID) {
16778                    capp.kill("depends on provider "
16779                            + cpr.name.flattenToShortString()
16780                            + " in dying proc " + (proc != null ? proc.processName : "??")
16781                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16782                }
16783            } else if (capp.thread != null && conn.provider.provider != null) {
16784                try {
16785                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16786                } catch (RemoteException e) {
16787                }
16788                // In the protocol here, we don't expect the client to correctly
16789                // clean up this connection, we'll just remove it.
16790                cpr.connections.remove(i);
16791                if (conn.client.conProviders.remove(conn)) {
16792                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16793                }
16794            }
16795        }
16796
16797        if (inLaunching && always) {
16798            mLaunchingProviders.remove(cpr);
16799        }
16800        return inLaunching;
16801    }
16802
16803    /**
16804     * Main code for cleaning up a process when it has gone away.  This is
16805     * called both as a result of the process dying, or directly when stopping
16806     * a process when running in single process mode.
16807     *
16808     * @return Returns true if the given process has been restarted, so the
16809     * app that was passed in must remain on the process lists.
16810     */
16811    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16812            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16813        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16814        if (index >= 0) {
16815            removeLruProcessLocked(app);
16816            ProcessList.remove(app.pid);
16817        }
16818
16819        mProcessesToGc.remove(app);
16820        mPendingPssProcesses.remove(app);
16821
16822        // Dismiss any open dialogs.
16823        if (app.crashDialog != null && !app.forceCrashReport) {
16824            app.crashDialog.dismiss();
16825            app.crashDialog = null;
16826        }
16827        if (app.anrDialog != null) {
16828            app.anrDialog.dismiss();
16829            app.anrDialog = null;
16830        }
16831        if (app.waitDialog != null) {
16832            app.waitDialog.dismiss();
16833            app.waitDialog = null;
16834        }
16835
16836        app.crashing = false;
16837        app.notResponding = false;
16838
16839        app.resetPackageList(mProcessStats);
16840        app.unlinkDeathRecipient();
16841        app.makeInactive(mProcessStats);
16842        app.waitingToKill = null;
16843        app.forcingToForeground = null;
16844        updateProcessForegroundLocked(app, false, false);
16845        app.foregroundActivities = false;
16846        app.hasShownUi = false;
16847        app.treatLikeActivity = false;
16848        app.hasAboveClient = false;
16849        app.hasClientActivities = false;
16850
16851        mServices.killServicesLocked(app, allowRestart);
16852
16853        boolean restart = false;
16854
16855        // Remove published content providers.
16856        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16857            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16858            final boolean always = app.bad || !allowRestart;
16859            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16860            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16861                // We left the provider in the launching list, need to
16862                // restart it.
16863                restart = true;
16864            }
16865
16866            cpr.provider = null;
16867            cpr.proc = null;
16868        }
16869        app.pubProviders.clear();
16870
16871        // Take care of any launching providers waiting for this process.
16872        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16873            restart = true;
16874        }
16875
16876        // Unregister from connected content providers.
16877        if (!app.conProviders.isEmpty()) {
16878            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16879                ContentProviderConnection conn = app.conProviders.get(i);
16880                conn.provider.connections.remove(conn);
16881                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16882                        conn.provider.name);
16883            }
16884            app.conProviders.clear();
16885        }
16886
16887        // At this point there may be remaining entries in mLaunchingProviders
16888        // where we were the only one waiting, so they are no longer of use.
16889        // Look for these and clean up if found.
16890        // XXX Commented out for now.  Trying to figure out a way to reproduce
16891        // the actual situation to identify what is actually going on.
16892        if (false) {
16893            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16894                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16895                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16896                    synchronized (cpr) {
16897                        cpr.launchingApp = null;
16898                        cpr.notifyAll();
16899                    }
16900                }
16901            }
16902        }
16903
16904        skipCurrentReceiverLocked(app);
16905
16906        // Unregister any receivers.
16907        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16908            removeReceiverLocked(app.receivers.valueAt(i));
16909        }
16910        app.receivers.clear();
16911
16912        // If the app is undergoing backup, tell the backup manager about it
16913        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16914            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16915                    + mBackupTarget.appInfo + " died during backup");
16916            try {
16917                IBackupManager bm = IBackupManager.Stub.asInterface(
16918                        ServiceManager.getService(Context.BACKUP_SERVICE));
16919                bm.agentDisconnected(app.info.packageName);
16920            } catch (RemoteException e) {
16921                // can't happen; backup manager is local
16922            }
16923        }
16924
16925        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16926            ProcessChangeItem item = mPendingProcessChanges.get(i);
16927            if (item.pid == app.pid) {
16928                mPendingProcessChanges.remove(i);
16929                mAvailProcessChanges.add(item);
16930            }
16931        }
16932        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16933                null).sendToTarget();
16934
16935        // If the caller is restarting this app, then leave it in its
16936        // current lists and let the caller take care of it.
16937        if (restarting) {
16938            return false;
16939        }
16940
16941        if (!app.persistent || app.isolated) {
16942            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16943                    "Removing non-persistent process during cleanup: " + app);
16944            if (!replacingPid) {
16945                removeProcessNameLocked(app.processName, app.uid);
16946            }
16947            if (mHeavyWeightProcess == app) {
16948                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16949                        mHeavyWeightProcess.userId, 0));
16950                mHeavyWeightProcess = null;
16951            }
16952        } else if (!app.removed) {
16953            // This app is persistent, so we need to keep its record around.
16954            // If it is not already on the pending app list, add it there
16955            // and start a new process for it.
16956            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16957                mPersistentStartingProcesses.add(app);
16958                restart = true;
16959            }
16960        }
16961        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16962                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16963        mProcessesOnHold.remove(app);
16964
16965        if (app == mHomeProcess) {
16966            mHomeProcess = null;
16967        }
16968        if (app == mPreviousProcess) {
16969            mPreviousProcess = null;
16970        }
16971
16972        if (restart && !app.isolated) {
16973            // We have components that still need to be running in the
16974            // process, so re-launch it.
16975            if (index < 0) {
16976                ProcessList.remove(app.pid);
16977            }
16978            addProcessNameLocked(app);
16979            startProcessLocked(app, "restart", app.processName);
16980            return true;
16981        } else if (app.pid > 0 && app.pid != MY_PID) {
16982            // Goodbye!
16983            boolean removed;
16984            synchronized (mPidsSelfLocked) {
16985                mPidsSelfLocked.remove(app.pid);
16986                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16987            }
16988            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16989            if (app.isolated) {
16990                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16991            }
16992            app.setPid(0);
16993        }
16994        return false;
16995    }
16996
16997    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16998        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16999            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17000            if (cpr.launchingApp == app) {
17001                return true;
17002            }
17003        }
17004        return false;
17005    }
17006
17007    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17008        // Look through the content providers we are waiting to have launched,
17009        // and if any run in this process then either schedule a restart of
17010        // the process or kill the client waiting for it if this process has
17011        // gone bad.
17012        boolean restart = false;
17013        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17014            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17015            if (cpr.launchingApp == app) {
17016                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17017                    restart = true;
17018                } else {
17019                    removeDyingProviderLocked(app, cpr, true);
17020                }
17021            }
17022        }
17023        return restart;
17024    }
17025
17026    // =========================================================
17027    // SERVICES
17028    // =========================================================
17029
17030    @Override
17031    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17032            int flags) {
17033        enforceNotIsolatedCaller("getServices");
17034        synchronized (this) {
17035            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17036        }
17037    }
17038
17039    @Override
17040    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17041        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17042        synchronized (this) {
17043            return mServices.getRunningServiceControlPanelLocked(name);
17044        }
17045    }
17046
17047    @Override
17048    public ComponentName startService(IApplicationThread caller, Intent service,
17049            String resolvedType, String callingPackage, int userId)
17050            throws TransactionTooLargeException {
17051        enforceNotIsolatedCaller("startService");
17052        // Refuse possible leaked file descriptors
17053        if (service != null && service.hasFileDescriptors() == true) {
17054            throw new IllegalArgumentException("File descriptors passed in Intent");
17055        }
17056
17057        if (callingPackage == null) {
17058            throw new IllegalArgumentException("callingPackage cannot be null");
17059        }
17060
17061        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17062                "startService: " + service + " type=" + resolvedType);
17063        synchronized(this) {
17064            final int callingPid = Binder.getCallingPid();
17065            final int callingUid = Binder.getCallingUid();
17066            final long origId = Binder.clearCallingIdentity();
17067            ComponentName res = mServices.startServiceLocked(caller, service,
17068                    resolvedType, callingPid, callingUid, callingPackage, userId);
17069            Binder.restoreCallingIdentity(origId);
17070            return res;
17071        }
17072    }
17073
17074    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17075            String callingPackage, int userId)
17076            throws TransactionTooLargeException {
17077        synchronized(this) {
17078            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17079                    "startServiceInPackage: " + service + " type=" + resolvedType);
17080            final long origId = Binder.clearCallingIdentity();
17081            ComponentName res = mServices.startServiceLocked(null, service,
17082                    resolvedType, -1, uid, callingPackage, userId);
17083            Binder.restoreCallingIdentity(origId);
17084            return res;
17085        }
17086    }
17087
17088    @Override
17089    public int stopService(IApplicationThread caller, Intent service,
17090            String resolvedType, int userId) {
17091        enforceNotIsolatedCaller("stopService");
17092        // Refuse possible leaked file descriptors
17093        if (service != null && service.hasFileDescriptors() == true) {
17094            throw new IllegalArgumentException("File descriptors passed in Intent");
17095        }
17096
17097        synchronized(this) {
17098            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17099        }
17100    }
17101
17102    @Override
17103    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17104        enforceNotIsolatedCaller("peekService");
17105        // Refuse possible leaked file descriptors
17106        if (service != null && service.hasFileDescriptors() == true) {
17107            throw new IllegalArgumentException("File descriptors passed in Intent");
17108        }
17109
17110        if (callingPackage == null) {
17111            throw new IllegalArgumentException("callingPackage cannot be null");
17112        }
17113
17114        synchronized(this) {
17115            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17116        }
17117    }
17118
17119    @Override
17120    public boolean stopServiceToken(ComponentName className, IBinder token,
17121            int startId) {
17122        synchronized(this) {
17123            return mServices.stopServiceTokenLocked(className, token, startId);
17124        }
17125    }
17126
17127    @Override
17128    public void setServiceForeground(ComponentName className, IBinder token,
17129            int id, Notification notification, int flags) {
17130        synchronized(this) {
17131            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17132        }
17133    }
17134
17135    @Override
17136    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17137            boolean requireFull, String name, String callerPackage) {
17138        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17139                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17140    }
17141
17142    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17143            String className, int flags) {
17144        boolean result = false;
17145        // For apps that don't have pre-defined UIDs, check for permission
17146        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17147            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17148                if (ActivityManager.checkUidPermission(
17149                        INTERACT_ACROSS_USERS,
17150                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17151                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17152                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17153                            + " requests FLAG_SINGLE_USER, but app does not hold "
17154                            + INTERACT_ACROSS_USERS;
17155                    Slog.w(TAG, msg);
17156                    throw new SecurityException(msg);
17157                }
17158                // Permission passed
17159                result = true;
17160            }
17161        } else if ("system".equals(componentProcessName)) {
17162            result = true;
17163        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17164            // Phone app and persistent apps are allowed to export singleuser providers.
17165            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17166                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17167        }
17168        if (DEBUG_MU) Slog.v(TAG_MU,
17169                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17170                + Integer.toHexString(flags) + ") = " + result);
17171        return result;
17172    }
17173
17174    /**
17175     * Checks to see if the caller is in the same app as the singleton
17176     * component, or the component is in a special app. It allows special apps
17177     * to export singleton components but prevents exporting singleton
17178     * components for regular apps.
17179     */
17180    boolean isValidSingletonCall(int callingUid, int componentUid) {
17181        int componentAppId = UserHandle.getAppId(componentUid);
17182        return UserHandle.isSameApp(callingUid, componentUid)
17183                || componentAppId == Process.SYSTEM_UID
17184                || componentAppId == Process.PHONE_UID
17185                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17186                        == PackageManager.PERMISSION_GRANTED;
17187    }
17188
17189    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17190            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17191            int userId) throws TransactionTooLargeException {
17192        enforceNotIsolatedCaller("bindService");
17193
17194        // Refuse possible leaked file descriptors
17195        if (service != null && service.hasFileDescriptors() == true) {
17196            throw new IllegalArgumentException("File descriptors passed in Intent");
17197        }
17198
17199        if (callingPackage == null) {
17200            throw new IllegalArgumentException("callingPackage cannot be null");
17201        }
17202
17203        synchronized(this) {
17204            return mServices.bindServiceLocked(caller, token, service,
17205                    resolvedType, connection, flags, callingPackage, userId);
17206        }
17207    }
17208
17209    public boolean unbindService(IServiceConnection connection) {
17210        synchronized (this) {
17211            return mServices.unbindServiceLocked(connection);
17212        }
17213    }
17214
17215    public void publishService(IBinder token, Intent intent, IBinder service) {
17216        // Refuse possible leaked file descriptors
17217        if (intent != null && intent.hasFileDescriptors() == true) {
17218            throw new IllegalArgumentException("File descriptors passed in Intent");
17219        }
17220
17221        synchronized(this) {
17222            if (!(token instanceof ServiceRecord)) {
17223                throw new IllegalArgumentException("Invalid service token");
17224            }
17225            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17226        }
17227    }
17228
17229    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17230        // Refuse possible leaked file descriptors
17231        if (intent != null && intent.hasFileDescriptors() == true) {
17232            throw new IllegalArgumentException("File descriptors passed in Intent");
17233        }
17234
17235        synchronized(this) {
17236            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17237        }
17238    }
17239
17240    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17241        synchronized(this) {
17242            if (!(token instanceof ServiceRecord)) {
17243                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17244                throw new IllegalArgumentException("Invalid service token");
17245            }
17246            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17247        }
17248    }
17249
17250    // =========================================================
17251    // BACKUP AND RESTORE
17252    // =========================================================
17253
17254    // Cause the target app to be launched if necessary and its backup agent
17255    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17256    // activity manager to announce its creation.
17257    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17258        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17259        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17260
17261        IPackageManager pm = AppGlobals.getPackageManager();
17262        ApplicationInfo app = null;
17263        try {
17264            app = pm.getApplicationInfo(packageName, 0, userId);
17265        } catch (RemoteException e) {
17266            // can't happen; package manager is process-local
17267        }
17268        if (app == null) {
17269            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17270            return false;
17271        }
17272
17273        synchronized(this) {
17274            // !!! TODO: currently no check here that we're already bound
17275            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17276            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17277            synchronized (stats) {
17278                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17279            }
17280
17281            // Backup agent is now in use, its package can't be stopped.
17282            try {
17283                AppGlobals.getPackageManager().setPackageStoppedState(
17284                        app.packageName, false, UserHandle.getUserId(app.uid));
17285            } catch (RemoteException e) {
17286            } catch (IllegalArgumentException e) {
17287                Slog.w(TAG, "Failed trying to unstop package "
17288                        + app.packageName + ": " + e);
17289            }
17290
17291            BackupRecord r = new BackupRecord(ss, app, backupMode);
17292            ComponentName hostingName =
17293                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17294                            ? new ComponentName(app.packageName, app.backupAgentName)
17295                            : new ComponentName("android", "FullBackupAgent");
17296            // startProcessLocked() returns existing proc's record if it's already running
17297            ProcessRecord proc = startProcessLocked(app.processName, app,
17298                    false, 0, "backup", hostingName, false, false, false);
17299            if (proc == null) {
17300                Slog.e(TAG, "Unable to start backup agent process " + r);
17301                return false;
17302            }
17303
17304            // If the app is a regular app (uid >= 10000) and not the system server or phone
17305            // process, etc, then mark it as being in full backup so that certain calls to the
17306            // process can be blocked. This is not reset to false anywhere because we kill the
17307            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17308            if (UserHandle.isApp(app.uid) &&
17309                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17310                proc.inFullBackup = true;
17311            }
17312            r.app = proc;
17313            mBackupTarget = r;
17314            mBackupAppName = app.packageName;
17315
17316            // Try not to kill the process during backup
17317            updateOomAdjLocked(proc);
17318
17319            // If the process is already attached, schedule the creation of the backup agent now.
17320            // If it is not yet live, this will be done when it attaches to the framework.
17321            if (proc.thread != null) {
17322                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17323                try {
17324                    proc.thread.scheduleCreateBackupAgent(app,
17325                            compatibilityInfoForPackageLocked(app), backupMode);
17326                } catch (RemoteException e) {
17327                    // Will time out on the backup manager side
17328                }
17329            } else {
17330                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17331            }
17332            // Invariants: at this point, the target app process exists and the application
17333            // is either already running or in the process of coming up.  mBackupTarget and
17334            // mBackupAppName describe the app, so that when it binds back to the AM we
17335            // know that it's scheduled for a backup-agent operation.
17336        }
17337
17338        return true;
17339    }
17340
17341    @Override
17342    public void clearPendingBackup() {
17343        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17344        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17345
17346        synchronized (this) {
17347            mBackupTarget = null;
17348            mBackupAppName = null;
17349        }
17350    }
17351
17352    // A backup agent has just come up
17353    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17354        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17355                + " = " + agent);
17356
17357        synchronized(this) {
17358            if (!agentPackageName.equals(mBackupAppName)) {
17359                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17360                return;
17361            }
17362        }
17363
17364        long oldIdent = Binder.clearCallingIdentity();
17365        try {
17366            IBackupManager bm = IBackupManager.Stub.asInterface(
17367                    ServiceManager.getService(Context.BACKUP_SERVICE));
17368            bm.agentConnected(agentPackageName, agent);
17369        } catch (RemoteException e) {
17370            // can't happen; the backup manager service is local
17371        } catch (Exception e) {
17372            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17373            e.printStackTrace();
17374        } finally {
17375            Binder.restoreCallingIdentity(oldIdent);
17376        }
17377    }
17378
17379    // done with this agent
17380    public void unbindBackupAgent(ApplicationInfo appInfo) {
17381        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17382        if (appInfo == null) {
17383            Slog.w(TAG, "unbind backup agent for null app");
17384            return;
17385        }
17386
17387        synchronized(this) {
17388            try {
17389                if (mBackupAppName == null) {
17390                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17391                    return;
17392                }
17393
17394                if (!mBackupAppName.equals(appInfo.packageName)) {
17395                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17396                    return;
17397                }
17398
17399                // Not backing this app up any more; reset its OOM adjustment
17400                final ProcessRecord proc = mBackupTarget.app;
17401                updateOomAdjLocked(proc);
17402
17403                // If the app crashed during backup, 'thread' will be null here
17404                if (proc.thread != null) {
17405                    try {
17406                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17407                                compatibilityInfoForPackageLocked(appInfo));
17408                    } catch (Exception e) {
17409                        Slog.e(TAG, "Exception when unbinding backup agent:");
17410                        e.printStackTrace();
17411                    }
17412                }
17413            } finally {
17414                mBackupTarget = null;
17415                mBackupAppName = null;
17416            }
17417        }
17418    }
17419    // =========================================================
17420    // BROADCASTS
17421    // =========================================================
17422
17423    boolean isPendingBroadcastProcessLocked(int pid) {
17424        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17425                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17426    }
17427
17428    void skipPendingBroadcastLocked(int pid) {
17429            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17430            for (BroadcastQueue queue : mBroadcastQueues) {
17431                queue.skipPendingBroadcastLocked(pid);
17432            }
17433    }
17434
17435    // The app just attached; send any pending broadcasts that it should receive
17436    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17437        boolean didSomething = false;
17438        for (BroadcastQueue queue : mBroadcastQueues) {
17439            didSomething |= queue.sendPendingBroadcastsLocked(app);
17440        }
17441        return didSomething;
17442    }
17443
17444    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17445            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17446        enforceNotIsolatedCaller("registerReceiver");
17447        ArrayList<Intent> stickyIntents = null;
17448        ProcessRecord callerApp = null;
17449        int callingUid;
17450        int callingPid;
17451        synchronized(this) {
17452            if (caller != null) {
17453                callerApp = getRecordForAppLocked(caller);
17454                if (callerApp == null) {
17455                    throw new SecurityException(
17456                            "Unable to find app for caller " + caller
17457                            + " (pid=" + Binder.getCallingPid()
17458                            + ") when registering receiver " + receiver);
17459                }
17460                if (callerApp.info.uid != Process.SYSTEM_UID &&
17461                        !callerApp.pkgList.containsKey(callerPackage) &&
17462                        !"android".equals(callerPackage)) {
17463                    throw new SecurityException("Given caller package " + callerPackage
17464                            + " is not running in process " + callerApp);
17465                }
17466                callingUid = callerApp.info.uid;
17467                callingPid = callerApp.pid;
17468            } else {
17469                callerPackage = null;
17470                callingUid = Binder.getCallingUid();
17471                callingPid = Binder.getCallingPid();
17472            }
17473
17474            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17475                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17476
17477            Iterator<String> actions = filter.actionsIterator();
17478            if (actions == null) {
17479                ArrayList<String> noAction = new ArrayList<String>(1);
17480                noAction.add(null);
17481                actions = noAction.iterator();
17482            }
17483
17484            // Collect stickies of users
17485            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17486            while (actions.hasNext()) {
17487                String action = actions.next();
17488                for (int id : userIds) {
17489                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17490                    if (stickies != null) {
17491                        ArrayList<Intent> intents = stickies.get(action);
17492                        if (intents != null) {
17493                            if (stickyIntents == null) {
17494                                stickyIntents = new ArrayList<Intent>();
17495                            }
17496                            stickyIntents.addAll(intents);
17497                        }
17498                    }
17499                }
17500            }
17501        }
17502
17503        ArrayList<Intent> allSticky = null;
17504        if (stickyIntents != null) {
17505            final ContentResolver resolver = mContext.getContentResolver();
17506            // Look for any matching sticky broadcasts...
17507            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17508                Intent intent = stickyIntents.get(i);
17509                // If intent has scheme "content", it will need to acccess
17510                // provider that needs to lock mProviderMap in ActivityThread
17511                // and also it may need to wait application response, so we
17512                // cannot lock ActivityManagerService here.
17513                if (filter.match(resolver, intent, true, TAG) >= 0) {
17514                    if (allSticky == null) {
17515                        allSticky = new ArrayList<Intent>();
17516                    }
17517                    allSticky.add(intent);
17518                }
17519            }
17520        }
17521
17522        // The first sticky in the list is returned directly back to the client.
17523        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17524        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17525        if (receiver == null) {
17526            return sticky;
17527        }
17528
17529        synchronized (this) {
17530            if (callerApp != null && (callerApp.thread == null
17531                    || callerApp.thread.asBinder() != caller.asBinder())) {
17532                // Original caller already died
17533                return null;
17534            }
17535            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17536            if (rl == null) {
17537                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17538                        userId, receiver);
17539                if (rl.app != null) {
17540                    rl.app.receivers.add(rl);
17541                } else {
17542                    try {
17543                        receiver.asBinder().linkToDeath(rl, 0);
17544                    } catch (RemoteException e) {
17545                        return sticky;
17546                    }
17547                    rl.linkedToDeath = true;
17548                }
17549                mRegisteredReceivers.put(receiver.asBinder(), rl);
17550            } else if (rl.uid != callingUid) {
17551                throw new IllegalArgumentException(
17552                        "Receiver requested to register for uid " + callingUid
17553                        + " was previously registered for uid " + rl.uid);
17554            } else if (rl.pid != callingPid) {
17555                throw new IllegalArgumentException(
17556                        "Receiver requested to register for pid " + callingPid
17557                        + " was previously registered for pid " + rl.pid);
17558            } else if (rl.userId != userId) {
17559                throw new IllegalArgumentException(
17560                        "Receiver requested to register for user " + userId
17561                        + " was previously registered for user " + rl.userId);
17562            }
17563            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17564                    permission, callingUid, userId);
17565            rl.add(bf);
17566            if (!bf.debugCheck()) {
17567                Slog.w(TAG, "==> For Dynamic broadcast");
17568            }
17569            mReceiverResolver.addFilter(bf);
17570
17571            // Enqueue broadcasts for all existing stickies that match
17572            // this filter.
17573            if (allSticky != null) {
17574                ArrayList receivers = new ArrayList();
17575                receivers.add(bf);
17576
17577                final int stickyCount = allSticky.size();
17578                for (int i = 0; i < stickyCount; i++) {
17579                    Intent intent = allSticky.get(i);
17580                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17581                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17582                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17583                            null, 0, null, null, false, true, true, -1);
17584                    queue.enqueueParallelBroadcastLocked(r);
17585                    queue.scheduleBroadcastsLocked();
17586                }
17587            }
17588
17589            return sticky;
17590        }
17591    }
17592
17593    public void unregisterReceiver(IIntentReceiver receiver) {
17594        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17595
17596        final long origId = Binder.clearCallingIdentity();
17597        try {
17598            boolean doTrim = false;
17599
17600            synchronized(this) {
17601                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17602                if (rl != null) {
17603                    final BroadcastRecord r = rl.curBroadcast;
17604                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17605                        final boolean doNext = r.queue.finishReceiverLocked(
17606                                r, r.resultCode, r.resultData, r.resultExtras,
17607                                r.resultAbort, false);
17608                        if (doNext) {
17609                            doTrim = true;
17610                            r.queue.processNextBroadcast(false);
17611                        }
17612                    }
17613
17614                    if (rl.app != null) {
17615                        rl.app.receivers.remove(rl);
17616                    }
17617                    removeReceiverLocked(rl);
17618                    if (rl.linkedToDeath) {
17619                        rl.linkedToDeath = false;
17620                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17621                    }
17622                }
17623            }
17624
17625            // If we actually concluded any broadcasts, we might now be able
17626            // to trim the recipients' apps from our working set
17627            if (doTrim) {
17628                trimApplications();
17629                return;
17630            }
17631
17632        } finally {
17633            Binder.restoreCallingIdentity(origId);
17634        }
17635    }
17636
17637    void removeReceiverLocked(ReceiverList rl) {
17638        mRegisteredReceivers.remove(rl.receiver.asBinder());
17639        for (int i = rl.size() - 1; i >= 0; i--) {
17640            mReceiverResolver.removeFilter(rl.get(i));
17641        }
17642    }
17643
17644    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17645        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17646            ProcessRecord r = mLruProcesses.get(i);
17647            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17648                try {
17649                    r.thread.dispatchPackageBroadcast(cmd, packages);
17650                } catch (RemoteException ex) {
17651                }
17652            }
17653        }
17654    }
17655
17656    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17657            int callingUid, int[] users) {
17658        // TODO: come back and remove this assumption to triage all broadcasts
17659        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17660
17661        List<ResolveInfo> receivers = null;
17662        try {
17663            HashSet<ComponentName> singleUserReceivers = null;
17664            boolean scannedFirstReceivers = false;
17665            for (int user : users) {
17666                // Skip users that have Shell restrictions, with exception of always permitted
17667                // Shell broadcasts
17668                if (callingUid == Process.SHELL_UID
17669                        && mUserController.hasUserRestriction(
17670                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17671                        && !isPermittedShellBroadcast(intent)) {
17672                    continue;
17673                }
17674                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17675                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17676                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17677                    // If this is not the system user, we need to check for
17678                    // any receivers that should be filtered out.
17679                    for (int i=0; i<newReceivers.size(); i++) {
17680                        ResolveInfo ri = newReceivers.get(i);
17681                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17682                            newReceivers.remove(i);
17683                            i--;
17684                        }
17685                    }
17686                }
17687                if (newReceivers != null && newReceivers.size() == 0) {
17688                    newReceivers = null;
17689                }
17690                if (receivers == null) {
17691                    receivers = newReceivers;
17692                } else if (newReceivers != null) {
17693                    // We need to concatenate the additional receivers
17694                    // found with what we have do far.  This would be easy,
17695                    // but we also need to de-dup any receivers that are
17696                    // singleUser.
17697                    if (!scannedFirstReceivers) {
17698                        // Collect any single user receivers we had already retrieved.
17699                        scannedFirstReceivers = true;
17700                        for (int i=0; i<receivers.size(); i++) {
17701                            ResolveInfo ri = receivers.get(i);
17702                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17703                                ComponentName cn = new ComponentName(
17704                                        ri.activityInfo.packageName, ri.activityInfo.name);
17705                                if (singleUserReceivers == null) {
17706                                    singleUserReceivers = new HashSet<ComponentName>();
17707                                }
17708                                singleUserReceivers.add(cn);
17709                            }
17710                        }
17711                    }
17712                    // Add the new results to the existing results, tracking
17713                    // and de-dupping single user receivers.
17714                    for (int i=0; i<newReceivers.size(); i++) {
17715                        ResolveInfo ri = newReceivers.get(i);
17716                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17717                            ComponentName cn = new ComponentName(
17718                                    ri.activityInfo.packageName, ri.activityInfo.name);
17719                            if (singleUserReceivers == null) {
17720                                singleUserReceivers = new HashSet<ComponentName>();
17721                            }
17722                            if (!singleUserReceivers.contains(cn)) {
17723                                singleUserReceivers.add(cn);
17724                                receivers.add(ri);
17725                            }
17726                        } else {
17727                            receivers.add(ri);
17728                        }
17729                    }
17730                }
17731            }
17732        } catch (RemoteException ex) {
17733            // pm is in same process, this will never happen.
17734        }
17735        return receivers;
17736    }
17737
17738    private boolean isPermittedShellBroadcast(Intent intent) {
17739        // remote bugreport should always be allowed to be taken
17740        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17741    }
17742
17743    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17744            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17745        final String action = intent.getAction();
17746        if (isProtectedBroadcast
17747                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17748                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17749                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17750                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17751                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17752                || Intent.ACTION_MASTER_CLEAR.equals(action)
17753                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17754                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17755                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17756                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17757                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17758            // Broadcast is either protected, or it's a public action that
17759            // we've relaxed, so it's fine for system internals to send.
17760            return;
17761        }
17762
17763        // This broadcast may be a problem...  but there are often system components that
17764        // want to send an internal broadcast to themselves, which is annoying to have to
17765        // explicitly list each action as a protected broadcast, so we will check for that
17766        // one safe case and allow it: an explicit broadcast, only being received by something
17767        // that has protected itself.
17768        if (receivers != null && receivers.size() > 0
17769                && (intent.getPackage() != null || intent.getComponent() != null)) {
17770            boolean allProtected = true;
17771            for (int i = receivers.size()-1; i >= 0; i--) {
17772                Object target = receivers.get(i);
17773                if (target instanceof ResolveInfo) {
17774                    ResolveInfo ri = (ResolveInfo)target;
17775                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17776                        allProtected = false;
17777                        break;
17778                    }
17779                } else {
17780                    BroadcastFilter bf = (BroadcastFilter)target;
17781                    if (bf.requiredPermission == null) {
17782                        allProtected = false;
17783                        break;
17784                    }
17785                }
17786            }
17787            if (allProtected) {
17788                // All safe!
17789                return;
17790            }
17791        }
17792
17793        // The vast majority of broadcasts sent from system internals
17794        // should be protected to avoid security holes, so yell loudly
17795        // to ensure we examine these cases.
17796        if (callerApp != null) {
17797            Log.wtf(TAG, "Sending non-protected broadcast " + action
17798                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17799                    new Throwable());
17800        } else {
17801            Log.wtf(TAG, "Sending non-protected broadcast " + action
17802                            + " from system uid " + UserHandle.formatUid(callingUid)
17803                            + " pkg " + callerPackage,
17804                    new Throwable());
17805        }
17806    }
17807
17808    final int broadcastIntentLocked(ProcessRecord callerApp,
17809            String callerPackage, Intent intent, String resolvedType,
17810            IIntentReceiver resultTo, int resultCode, String resultData,
17811            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17812            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17813        intent = new Intent(intent);
17814
17815        // By default broadcasts do not go to stopped apps.
17816        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17817
17818        // If we have not finished booting, don't allow this to launch new processes.
17819        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17820            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17821        }
17822
17823        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17824                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17825                + " ordered=" + ordered + " userid=" + userId);
17826        if ((resultTo != null) && !ordered) {
17827            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17828        }
17829
17830        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17831                ALLOW_NON_FULL, "broadcast", callerPackage);
17832
17833        // Make sure that the user who is receiving this broadcast is running.
17834        // If not, we will just skip it. Make an exception for shutdown broadcasts
17835        // and upgrade steps.
17836
17837        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17838            if ((callingUid != Process.SYSTEM_UID
17839                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17840                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17841                Slog.w(TAG, "Skipping broadcast of " + intent
17842                        + ": user " + userId + " is stopped");
17843                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17844            }
17845        }
17846
17847        BroadcastOptions brOptions = null;
17848        if (bOptions != null) {
17849            brOptions = new BroadcastOptions(bOptions);
17850            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17851                // See if the caller is allowed to do this.  Note we are checking against
17852                // the actual real caller (not whoever provided the operation as say a
17853                // PendingIntent), because that who is actually supplied the arguments.
17854                if (checkComponentPermission(
17855                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17856                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17857                        != PackageManager.PERMISSION_GRANTED) {
17858                    String msg = "Permission Denial: " + intent.getAction()
17859                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17860                            + ", uid=" + callingUid + ")"
17861                            + " requires "
17862                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17863                    Slog.w(TAG, msg);
17864                    throw new SecurityException(msg);
17865                }
17866            }
17867        }
17868
17869        // Verify that protected broadcasts are only being sent by system code,
17870        // and that system code is only sending protected broadcasts.
17871        final String action = intent.getAction();
17872        final boolean isProtectedBroadcast;
17873        try {
17874            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17875        } catch (RemoteException e) {
17876            Slog.w(TAG, "Remote exception", e);
17877            return ActivityManager.BROADCAST_SUCCESS;
17878        }
17879
17880        final boolean isCallerSystem;
17881        switch (UserHandle.getAppId(callingUid)) {
17882            case Process.ROOT_UID:
17883            case Process.SYSTEM_UID:
17884            case Process.PHONE_UID:
17885            case Process.BLUETOOTH_UID:
17886            case Process.NFC_UID:
17887                isCallerSystem = true;
17888                break;
17889            default:
17890                isCallerSystem = (callerApp != null) && callerApp.persistent;
17891                break;
17892        }
17893
17894        // First line security check before anything else: stop non-system apps from
17895        // sending protected broadcasts.
17896        if (!isCallerSystem) {
17897            if (isProtectedBroadcast) {
17898                String msg = "Permission Denial: not allowed to send broadcast "
17899                        + action + " from pid="
17900                        + callingPid + ", uid=" + callingUid;
17901                Slog.w(TAG, msg);
17902                throw new SecurityException(msg);
17903
17904            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17905                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17906                // Special case for compatibility: we don't want apps to send this,
17907                // but historically it has not been protected and apps may be using it
17908                // to poke their own app widget.  So, instead of making it protected,
17909                // just limit it to the caller.
17910                if (callerPackage == null) {
17911                    String msg = "Permission Denial: not allowed to send broadcast "
17912                            + action + " from unknown caller.";
17913                    Slog.w(TAG, msg);
17914                    throw new SecurityException(msg);
17915                } else if (intent.getComponent() != null) {
17916                    // They are good enough to send to an explicit component...  verify
17917                    // it is being sent to the calling app.
17918                    if (!intent.getComponent().getPackageName().equals(
17919                            callerPackage)) {
17920                        String msg = "Permission Denial: not allowed to send broadcast "
17921                                + action + " to "
17922                                + intent.getComponent().getPackageName() + " from "
17923                                + callerPackage;
17924                        Slog.w(TAG, msg);
17925                        throw new SecurityException(msg);
17926                    }
17927                } else {
17928                    // Limit broadcast to their own package.
17929                    intent.setPackage(callerPackage);
17930                }
17931            }
17932        }
17933
17934        if (action != null) {
17935            switch (action) {
17936                case Intent.ACTION_UID_REMOVED:
17937                case Intent.ACTION_PACKAGE_REMOVED:
17938                case Intent.ACTION_PACKAGE_CHANGED:
17939                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17940                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17941                case Intent.ACTION_PACKAGES_SUSPENDED:
17942                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17943                    // Handle special intents: if this broadcast is from the package
17944                    // manager about a package being removed, we need to remove all of
17945                    // its activities from the history stack.
17946                    if (checkComponentPermission(
17947                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17948                            callingPid, callingUid, -1, true)
17949                            != PackageManager.PERMISSION_GRANTED) {
17950                        String msg = "Permission Denial: " + intent.getAction()
17951                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17952                                + ", uid=" + callingUid + ")"
17953                                + " requires "
17954                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17955                        Slog.w(TAG, msg);
17956                        throw new SecurityException(msg);
17957                    }
17958                    switch (action) {
17959                        case Intent.ACTION_UID_REMOVED:
17960                            final Bundle intentExtras = intent.getExtras();
17961                            final int uid = intentExtras != null
17962                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17963                            if (uid >= 0) {
17964                                mBatteryStatsService.removeUid(uid);
17965                                mAppOpsService.uidRemoved(uid);
17966                            }
17967                            break;
17968                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17969                            // If resources are unavailable just force stop all those packages
17970                            // and flush the attribute cache as well.
17971                            String list[] =
17972                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17973                            if (list != null && list.length > 0) {
17974                                for (int i = 0; i < list.length; i++) {
17975                                    forceStopPackageLocked(list[i], -1, false, true, true,
17976                                            false, false, userId, "storage unmount");
17977                                }
17978                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17979                                sendPackageBroadcastLocked(
17980                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
17981                                        list, userId);
17982                            }
17983                            break;
17984                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17985                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17986                            break;
17987                        case Intent.ACTION_PACKAGE_REMOVED:
17988                        case Intent.ACTION_PACKAGE_CHANGED:
17989                            Uri data = intent.getData();
17990                            String ssp;
17991                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17992                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17993                                final boolean replacing =
17994                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17995                                final boolean killProcess =
17996                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17997                                final boolean fullUninstall = removed && !replacing;
17998                                if (removed) {
17999                                    if (killProcess) {
18000                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18001                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18002                                                false, true, true, false, fullUninstall, userId,
18003                                                removed ? "pkg removed" : "pkg changed");
18004                                    }
18005                                    final int cmd = killProcess
18006                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18007                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18008                                    sendPackageBroadcastLocked(cmd,
18009                                            new String[] {ssp}, userId);
18010                                    if (fullUninstall) {
18011                                        mAppOpsService.packageRemoved(
18012                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18013
18014                                        // Remove all permissions granted from/to this package
18015                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18016
18017                                        removeTasksByPackageNameLocked(ssp, userId);
18018
18019                                        // Hide the "unsupported display" dialog if necessary.
18020                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18021                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18022                                            mUnsupportedDisplaySizeDialog.dismiss();
18023                                            mUnsupportedDisplaySizeDialog = null;
18024                                        }
18025                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18026                                        mBatteryStatsService.notePackageUninstalled(ssp);
18027                                    }
18028                                } else {
18029                                    if (killProcess) {
18030                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18031                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18032                                                userId, ProcessList.INVALID_ADJ,
18033                                                false, true, true, false, "change " + ssp);
18034                                    }
18035                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18036                                            intent.getStringArrayExtra(
18037                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18038                                }
18039                            }
18040                            break;
18041                        case Intent.ACTION_PACKAGES_SUSPENDED:
18042                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18043                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18044                                    intent.getAction());
18045                            final String[] packageNames = intent.getStringArrayExtra(
18046                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18047                            final int userHandle = intent.getIntExtra(
18048                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18049
18050                            synchronized(ActivityManagerService.this) {
18051                                mRecentTasks.onPackagesSuspendedChanged(
18052                                        packageNames, suspended, userHandle);
18053                            }
18054                            break;
18055                    }
18056                    break;
18057                case Intent.ACTION_PACKAGE_REPLACED:
18058                {
18059                    final Uri data = intent.getData();
18060                    final String ssp;
18061                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18062                        final ApplicationInfo aInfo =
18063                                getPackageManagerInternalLocked().getApplicationInfo(
18064                                        ssp,
18065                                        userId);
18066                        if (aInfo == null) {
18067                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18068                                    + " ssp=" + ssp + " data=" + data);
18069                            return ActivityManager.BROADCAST_SUCCESS;
18070                        }
18071                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18072                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18073                                new String[] {ssp}, userId);
18074                    }
18075                    break;
18076                }
18077                case Intent.ACTION_PACKAGE_ADDED:
18078                {
18079                    // Special case for adding a package: by default turn on compatibility mode.
18080                    Uri data = intent.getData();
18081                    String ssp;
18082                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18083                        final boolean replacing =
18084                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18085                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18086
18087                        try {
18088                            ApplicationInfo ai = AppGlobals.getPackageManager().
18089                                    getApplicationInfo(ssp, 0, 0);
18090                            mBatteryStatsService.notePackageInstalled(ssp,
18091                                    ai != null ? ai.versionCode : 0);
18092                        } catch (RemoteException e) {
18093                        }
18094                    }
18095                    break;
18096                }
18097                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18098                {
18099                    Uri data = intent.getData();
18100                    String ssp;
18101                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18102                        // Hide the "unsupported display" dialog if necessary.
18103                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18104                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18105                            mUnsupportedDisplaySizeDialog.dismiss();
18106                            mUnsupportedDisplaySizeDialog = null;
18107                        }
18108                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18109                    }
18110                    break;
18111                }
18112                case Intent.ACTION_TIMEZONE_CHANGED:
18113                    // If this is the time zone changed action, queue up a message that will reset
18114                    // the timezone of all currently running processes. This message will get
18115                    // queued up before the broadcast happens.
18116                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18117                    break;
18118                case Intent.ACTION_TIME_CHANGED:
18119                    // If the user set the time, let all running processes know.
18120                    final int is24Hour =
18121                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18122                                    : 0;
18123                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18124                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18125                    synchronized (stats) {
18126                        stats.noteCurrentTimeChangedLocked();
18127                    }
18128                    break;
18129                case Intent.ACTION_CLEAR_DNS_CACHE:
18130                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18131                    break;
18132                case Proxy.PROXY_CHANGE_ACTION:
18133                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18134                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18135                    break;
18136                case android.hardware.Camera.ACTION_NEW_PICTURE:
18137                case android.hardware.Camera.ACTION_NEW_VIDEO:
18138                    // These broadcasts are no longer allowed by the system, since they can
18139                    // cause significant thrashing at a crictical point (using the camera).
18140                    // Apps should use JobScehduler to monitor for media provider changes.
18141                    Slog.w(TAG, action + " no longer allowed; dropping from "
18142                            + UserHandle.formatUid(callingUid));
18143                    if (resultTo != null) {
18144                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18145                        try {
18146                            queue.performReceiveLocked(callerApp, resultTo, intent,
18147                                    Activity.RESULT_CANCELED, null, null,
18148                                    false, false, userId);
18149                        } catch (RemoteException e) {
18150                            Slog.w(TAG, "Failure ["
18151                                    + queue.mQueueName + "] sending broadcast result of "
18152                                    + intent, e);
18153
18154                        }
18155                    }
18156                    // Lie; we don't want to crash the app.
18157                    return ActivityManager.BROADCAST_SUCCESS;
18158                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18159                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18160                    break;
18161            }
18162        }
18163
18164        // Add to the sticky list if requested.
18165        if (sticky) {
18166            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18167                    callingPid, callingUid)
18168                    != PackageManager.PERMISSION_GRANTED) {
18169                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18170                        + callingPid + ", uid=" + callingUid
18171                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18172                Slog.w(TAG, msg);
18173                throw new SecurityException(msg);
18174            }
18175            if (requiredPermissions != null && requiredPermissions.length > 0) {
18176                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18177                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18178                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18179            }
18180            if (intent.getComponent() != null) {
18181                throw new SecurityException(
18182                        "Sticky broadcasts can't target a specific component");
18183            }
18184            // We use userId directly here, since the "all" target is maintained
18185            // as a separate set of sticky broadcasts.
18186            if (userId != UserHandle.USER_ALL) {
18187                // But first, if this is not a broadcast to all users, then
18188                // make sure it doesn't conflict with an existing broadcast to
18189                // all users.
18190                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18191                        UserHandle.USER_ALL);
18192                if (stickies != null) {
18193                    ArrayList<Intent> list = stickies.get(intent.getAction());
18194                    if (list != null) {
18195                        int N = list.size();
18196                        int i;
18197                        for (i=0; i<N; i++) {
18198                            if (intent.filterEquals(list.get(i))) {
18199                                throw new IllegalArgumentException(
18200                                        "Sticky broadcast " + intent + " for user "
18201                                        + userId + " conflicts with existing global broadcast");
18202                            }
18203                        }
18204                    }
18205                }
18206            }
18207            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18208            if (stickies == null) {
18209                stickies = new ArrayMap<>();
18210                mStickyBroadcasts.put(userId, stickies);
18211            }
18212            ArrayList<Intent> list = stickies.get(intent.getAction());
18213            if (list == null) {
18214                list = new ArrayList<>();
18215                stickies.put(intent.getAction(), list);
18216            }
18217            final int stickiesCount = list.size();
18218            int i;
18219            for (i = 0; i < stickiesCount; i++) {
18220                if (intent.filterEquals(list.get(i))) {
18221                    // This sticky already exists, replace it.
18222                    list.set(i, new Intent(intent));
18223                    break;
18224                }
18225            }
18226            if (i >= stickiesCount) {
18227                list.add(new Intent(intent));
18228            }
18229        }
18230
18231        int[] users;
18232        if (userId == UserHandle.USER_ALL) {
18233            // Caller wants broadcast to go to all started users.
18234            users = mUserController.getStartedUserArrayLocked();
18235        } else {
18236            // Caller wants broadcast to go to one specific user.
18237            users = new int[] {userId};
18238        }
18239
18240        // Figure out who all will receive this broadcast.
18241        List receivers = null;
18242        List<BroadcastFilter> registeredReceivers = null;
18243        // Need to resolve the intent to interested receivers...
18244        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18245                 == 0) {
18246            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18247        }
18248        if (intent.getComponent() == null) {
18249            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18250                // Query one target user at a time, excluding shell-restricted users
18251                for (int i = 0; i < users.length; i++) {
18252                    if (mUserController.hasUserRestriction(
18253                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18254                        continue;
18255                    }
18256                    List<BroadcastFilter> registeredReceiversForUser =
18257                            mReceiverResolver.queryIntent(intent,
18258                                    resolvedType, false, users[i]);
18259                    if (registeredReceivers == null) {
18260                        registeredReceivers = registeredReceiversForUser;
18261                    } else if (registeredReceiversForUser != null) {
18262                        registeredReceivers.addAll(registeredReceiversForUser);
18263                    }
18264                }
18265            } else {
18266                registeredReceivers = mReceiverResolver.queryIntent(intent,
18267                        resolvedType, false, userId);
18268            }
18269        }
18270
18271        final boolean replacePending =
18272                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18273
18274        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18275                + " replacePending=" + replacePending);
18276
18277        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18278        if (!ordered && NR > 0) {
18279            // If we are not serializing this broadcast, then send the
18280            // registered receivers separately so they don't wait for the
18281            // components to be launched.
18282            if (isCallerSystem) {
18283                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18284                        isProtectedBroadcast, registeredReceivers);
18285            }
18286            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18287            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18288                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18289                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18290                    resultExtras, ordered, sticky, false, userId);
18291            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18292            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18293            if (!replaced) {
18294                queue.enqueueParallelBroadcastLocked(r);
18295                queue.scheduleBroadcastsLocked();
18296            }
18297            registeredReceivers = null;
18298            NR = 0;
18299        }
18300
18301        // Merge into one list.
18302        int ir = 0;
18303        if (receivers != null) {
18304            // A special case for PACKAGE_ADDED: do not allow the package
18305            // being added to see this broadcast.  This prevents them from
18306            // using this as a back door to get run as soon as they are
18307            // installed.  Maybe in the future we want to have a special install
18308            // broadcast or such for apps, but we'd like to deliberately make
18309            // this decision.
18310            String skipPackages[] = null;
18311            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18312                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18313                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18314                Uri data = intent.getData();
18315                if (data != null) {
18316                    String pkgName = data.getSchemeSpecificPart();
18317                    if (pkgName != null) {
18318                        skipPackages = new String[] { pkgName };
18319                    }
18320                }
18321            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18322                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18323            }
18324            if (skipPackages != null && (skipPackages.length > 0)) {
18325                for (String skipPackage : skipPackages) {
18326                    if (skipPackage != null) {
18327                        int NT = receivers.size();
18328                        for (int it=0; it<NT; it++) {
18329                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18330                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18331                                receivers.remove(it);
18332                                it--;
18333                                NT--;
18334                            }
18335                        }
18336                    }
18337                }
18338            }
18339
18340            int NT = receivers != null ? receivers.size() : 0;
18341            int it = 0;
18342            ResolveInfo curt = null;
18343            BroadcastFilter curr = null;
18344            while (it < NT && ir < NR) {
18345                if (curt == null) {
18346                    curt = (ResolveInfo)receivers.get(it);
18347                }
18348                if (curr == null) {
18349                    curr = registeredReceivers.get(ir);
18350                }
18351                if (curr.getPriority() >= curt.priority) {
18352                    // Insert this broadcast record into the final list.
18353                    receivers.add(it, curr);
18354                    ir++;
18355                    curr = null;
18356                    it++;
18357                    NT++;
18358                } else {
18359                    // Skip to the next ResolveInfo in the final list.
18360                    it++;
18361                    curt = null;
18362                }
18363            }
18364        }
18365        while (ir < NR) {
18366            if (receivers == null) {
18367                receivers = new ArrayList();
18368            }
18369            receivers.add(registeredReceivers.get(ir));
18370            ir++;
18371        }
18372
18373        if (isCallerSystem) {
18374            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18375                    isProtectedBroadcast, receivers);
18376        }
18377
18378        if ((receivers != null && receivers.size() > 0)
18379                || resultTo != null) {
18380            BroadcastQueue queue = broadcastQueueForIntent(intent);
18381            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18382                    callerPackage, callingPid, callingUid, resolvedType,
18383                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18384                    resultData, resultExtras, ordered, sticky, false, userId);
18385
18386            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18387                    + ": prev had " + queue.mOrderedBroadcasts.size());
18388            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18389                    "Enqueueing broadcast " + r.intent.getAction());
18390
18391            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18392            if (!replaced) {
18393                queue.enqueueOrderedBroadcastLocked(r);
18394                queue.scheduleBroadcastsLocked();
18395            }
18396        } else {
18397            // There was nobody interested in the broadcast, but we still want to record
18398            // that it happened.
18399            if (intent.getComponent() == null && intent.getPackage() == null
18400                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18401                // This was an implicit broadcast... let's record it for posterity.
18402                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18403            }
18404        }
18405
18406        return ActivityManager.BROADCAST_SUCCESS;
18407    }
18408
18409    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18410            int skipCount, long dispatchTime) {
18411        final long now = SystemClock.elapsedRealtime();
18412        if (mCurBroadcastStats == null ||
18413                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18414            mLastBroadcastStats = mCurBroadcastStats;
18415            if (mLastBroadcastStats != null) {
18416                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18417                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18418            }
18419            mCurBroadcastStats = new BroadcastStats();
18420        }
18421        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18422    }
18423
18424    final Intent verifyBroadcastLocked(Intent intent) {
18425        // Refuse possible leaked file descriptors
18426        if (intent != null && intent.hasFileDescriptors() == true) {
18427            throw new IllegalArgumentException("File descriptors passed in Intent");
18428        }
18429
18430        int flags = intent.getFlags();
18431
18432        if (!mProcessesReady) {
18433            // if the caller really truly claims to know what they're doing, go
18434            // ahead and allow the broadcast without launching any receivers
18435            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18436                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18437            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18438                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18439                        + " before boot completion");
18440                throw new IllegalStateException("Cannot broadcast before boot completed");
18441            }
18442        }
18443
18444        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18445            throw new IllegalArgumentException(
18446                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18447        }
18448
18449        return intent;
18450    }
18451
18452    public final int broadcastIntent(IApplicationThread caller,
18453            Intent intent, String resolvedType, IIntentReceiver resultTo,
18454            int resultCode, String resultData, Bundle resultExtras,
18455            String[] requiredPermissions, int appOp, Bundle bOptions,
18456            boolean serialized, boolean sticky, int userId) {
18457        enforceNotIsolatedCaller("broadcastIntent");
18458        synchronized(this) {
18459            intent = verifyBroadcastLocked(intent);
18460
18461            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18462            final int callingPid = Binder.getCallingPid();
18463            final int callingUid = Binder.getCallingUid();
18464            final long origId = Binder.clearCallingIdentity();
18465            int res = broadcastIntentLocked(callerApp,
18466                    callerApp != null ? callerApp.info.packageName : null,
18467                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18468                    requiredPermissions, appOp, bOptions, serialized, sticky,
18469                    callingPid, callingUid, userId);
18470            Binder.restoreCallingIdentity(origId);
18471            return res;
18472        }
18473    }
18474
18475
18476    int broadcastIntentInPackage(String packageName, int uid,
18477            Intent intent, String resolvedType, IIntentReceiver resultTo,
18478            int resultCode, String resultData, Bundle resultExtras,
18479            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18480            int userId) {
18481        synchronized(this) {
18482            intent = verifyBroadcastLocked(intent);
18483
18484            final long origId = Binder.clearCallingIdentity();
18485            String[] requiredPermissions = requiredPermission == null ? null
18486                    : new String[] {requiredPermission};
18487            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18488                    resultTo, resultCode, resultData, resultExtras,
18489                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18490                    sticky, -1, uid, userId);
18491            Binder.restoreCallingIdentity(origId);
18492            return res;
18493        }
18494    }
18495
18496    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18497        // Refuse possible leaked file descriptors
18498        if (intent != null && intent.hasFileDescriptors() == true) {
18499            throw new IllegalArgumentException("File descriptors passed in Intent");
18500        }
18501
18502        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18503                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18504
18505        synchronized(this) {
18506            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18507                    != PackageManager.PERMISSION_GRANTED) {
18508                String msg = "Permission Denial: unbroadcastIntent() from pid="
18509                        + Binder.getCallingPid()
18510                        + ", uid=" + Binder.getCallingUid()
18511                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18512                Slog.w(TAG, msg);
18513                throw new SecurityException(msg);
18514            }
18515            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18516            if (stickies != null) {
18517                ArrayList<Intent> list = stickies.get(intent.getAction());
18518                if (list != null) {
18519                    int N = list.size();
18520                    int i;
18521                    for (i=0; i<N; i++) {
18522                        if (intent.filterEquals(list.get(i))) {
18523                            list.remove(i);
18524                            break;
18525                        }
18526                    }
18527                    if (list.size() <= 0) {
18528                        stickies.remove(intent.getAction());
18529                    }
18530                }
18531                if (stickies.size() <= 0) {
18532                    mStickyBroadcasts.remove(userId);
18533                }
18534            }
18535        }
18536    }
18537
18538    void backgroundServicesFinishedLocked(int userId) {
18539        for (BroadcastQueue queue : mBroadcastQueues) {
18540            queue.backgroundServicesFinishedLocked(userId);
18541        }
18542    }
18543
18544    public void finishReceiver(IBinder who, int resultCode, String resultData,
18545            Bundle resultExtras, boolean resultAbort, int flags) {
18546        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18547
18548        // Refuse possible leaked file descriptors
18549        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18550            throw new IllegalArgumentException("File descriptors passed in Bundle");
18551        }
18552
18553        final long origId = Binder.clearCallingIdentity();
18554        try {
18555            boolean doNext = false;
18556            BroadcastRecord r;
18557
18558            synchronized(this) {
18559                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18560                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18561                r = queue.getMatchingOrderedReceiver(who);
18562                if (r != null) {
18563                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18564                        resultData, resultExtras, resultAbort, true);
18565                }
18566            }
18567
18568            if (doNext) {
18569                r.queue.processNextBroadcast(false);
18570            }
18571            trimApplications();
18572        } finally {
18573            Binder.restoreCallingIdentity(origId);
18574        }
18575    }
18576
18577    // =========================================================
18578    // INSTRUMENTATION
18579    // =========================================================
18580
18581    public boolean startInstrumentation(ComponentName className,
18582            String profileFile, int flags, Bundle arguments,
18583            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18584            int userId, String abiOverride) {
18585        enforceNotIsolatedCaller("startInstrumentation");
18586        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18587                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18588        // Refuse possible leaked file descriptors
18589        if (arguments != null && arguments.hasFileDescriptors()) {
18590            throw new IllegalArgumentException("File descriptors passed in Bundle");
18591        }
18592
18593        synchronized(this) {
18594            InstrumentationInfo ii = null;
18595            ApplicationInfo ai = null;
18596            try {
18597                ii = mContext.getPackageManager().getInstrumentationInfo(
18598                    className, STOCK_PM_FLAGS);
18599                ai = AppGlobals.getPackageManager().getApplicationInfo(
18600                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18601            } catch (PackageManager.NameNotFoundException e) {
18602            } catch (RemoteException e) {
18603            }
18604            if (ii == null) {
18605                reportStartInstrumentationFailureLocked(watcher, className,
18606                        "Unable to find instrumentation info for: " + className);
18607                return false;
18608            }
18609            if (ai == null) {
18610                reportStartInstrumentationFailureLocked(watcher, className,
18611                        "Unable to find instrumentation target package: " + ii.targetPackage);
18612                return false;
18613            }
18614            if (!ai.hasCode()) {
18615                reportStartInstrumentationFailureLocked(watcher, className,
18616                        "Instrumentation target has no code: " + ii.targetPackage);
18617                return false;
18618            }
18619
18620            int match = mContext.getPackageManager().checkSignatures(
18621                    ii.targetPackage, ii.packageName);
18622            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18623                String msg = "Permission Denial: starting instrumentation "
18624                        + className + " from pid="
18625                        + Binder.getCallingPid()
18626                        + ", uid=" + Binder.getCallingPid()
18627                        + " not allowed because package " + ii.packageName
18628                        + " does not have a signature matching the target "
18629                        + ii.targetPackage;
18630                reportStartInstrumentationFailureLocked(watcher, className, msg);
18631                throw new SecurityException(msg);
18632            }
18633
18634            final long origId = Binder.clearCallingIdentity();
18635            // Instrumentation can kill and relaunch even persistent processes
18636            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18637                    "start instr");
18638            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18639            app.instrumentationClass = className;
18640            app.instrumentationInfo = ai;
18641            app.instrumentationProfileFile = profileFile;
18642            app.instrumentationArguments = arguments;
18643            app.instrumentationWatcher = watcher;
18644            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18645            app.instrumentationResultClass = className;
18646            Binder.restoreCallingIdentity(origId);
18647        }
18648
18649        return true;
18650    }
18651
18652    /**
18653     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18654     * error to the logs, but if somebody is watching, send the report there too.  This enables
18655     * the "am" command to report errors with more information.
18656     *
18657     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18658     * @param cn The component name of the instrumentation.
18659     * @param report The error report.
18660     */
18661    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18662            ComponentName cn, String report) {
18663        Slog.w(TAG, report);
18664        if (watcher != null) {
18665            Bundle results = new Bundle();
18666            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18667            results.putString("Error", report);
18668            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18669        }
18670    }
18671
18672    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18673        if (app.instrumentationWatcher != null) {
18674            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18675                    app.instrumentationClass, resultCode, results);
18676        }
18677
18678        // Can't call out of the system process with a lock held, so post a message.
18679        if (app.instrumentationUiAutomationConnection != null) {
18680            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18681                    app.instrumentationUiAutomationConnection).sendToTarget();
18682        }
18683
18684        app.instrumentationWatcher = null;
18685        app.instrumentationUiAutomationConnection = null;
18686        app.instrumentationClass = null;
18687        app.instrumentationInfo = null;
18688        app.instrumentationProfileFile = null;
18689        app.instrumentationArguments = null;
18690
18691        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18692                "finished inst");
18693    }
18694
18695    public void finishInstrumentation(IApplicationThread target,
18696            int resultCode, Bundle results) {
18697        int userId = UserHandle.getCallingUserId();
18698        // Refuse possible leaked file descriptors
18699        if (results != null && results.hasFileDescriptors()) {
18700            throw new IllegalArgumentException("File descriptors passed in Intent");
18701        }
18702
18703        synchronized(this) {
18704            ProcessRecord app = getRecordForAppLocked(target);
18705            if (app == null) {
18706                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18707                return;
18708            }
18709            final long origId = Binder.clearCallingIdentity();
18710            finishInstrumentationLocked(app, resultCode, results);
18711            Binder.restoreCallingIdentity(origId);
18712        }
18713    }
18714
18715    // =========================================================
18716    // CONFIGURATION
18717    // =========================================================
18718
18719    public ConfigurationInfo getDeviceConfigurationInfo() {
18720        ConfigurationInfo config = new ConfigurationInfo();
18721        synchronized (this) {
18722            final Configuration globalConfig = getGlobalConfiguration();
18723            config.reqTouchScreen = globalConfig.touchscreen;
18724            config.reqKeyboardType = globalConfig.keyboard;
18725            config.reqNavigation = globalConfig.navigation;
18726            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18727                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18728                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18729            }
18730            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18731                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18732                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18733            }
18734            config.reqGlEsVersion = GL_ES_VERSION;
18735        }
18736        return config;
18737    }
18738
18739    ActivityStack getFocusedStack() {
18740        return mStackSupervisor.getFocusedStack();
18741    }
18742
18743    @Override
18744    public int getFocusedStackId() throws RemoteException {
18745        ActivityStack focusedStack = getFocusedStack();
18746        if (focusedStack != null) {
18747            return focusedStack.getStackId();
18748        }
18749        return -1;
18750    }
18751
18752    public Configuration getConfiguration() {
18753        Configuration ci;
18754        synchronized(this) {
18755            ci = new Configuration(getGlobalConfiguration());
18756            ci.userSetLocale = false;
18757        }
18758        return ci;
18759    }
18760
18761    @Override
18762    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18764        synchronized (this) {
18765            mSuppressResizeConfigChanges = suppress;
18766        }
18767    }
18768
18769    @Override
18770    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18771        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18772        if (fromStackId == HOME_STACK_ID) {
18773            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18774        }
18775        synchronized (this) {
18776            final long origId = Binder.clearCallingIdentity();
18777            try {
18778                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18779            } finally {
18780                Binder.restoreCallingIdentity(origId);
18781            }
18782        }
18783    }
18784
18785    @Override
18786    public void updatePersistentConfiguration(Configuration values) {
18787        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18788        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18789        if (values == null) {
18790            throw new NullPointerException("Configuration must not be null");
18791        }
18792
18793        int userId = UserHandle.getCallingUserId();
18794
18795        synchronized(this) {
18796            updatePersistentConfigurationLocked(values, userId);
18797        }
18798    }
18799
18800    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18801        final long origId = Binder.clearCallingIdentity();
18802        try {
18803            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18804        } finally {
18805            Binder.restoreCallingIdentity(origId);
18806        }
18807    }
18808
18809    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18810        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18811                FONT_SCALE, 1.0f, userId);
18812
18813        synchronized (this) {
18814            if (getGlobalConfiguration().fontScale == scaleFactor) {
18815                return;
18816            }
18817
18818            final Configuration configuration
18819                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18820            configuration.fontScale = scaleFactor;
18821            updatePersistentConfigurationLocked(configuration, userId);
18822        }
18823    }
18824
18825    private void enforceWriteSettingsPermission(String func) {
18826        int uid = Binder.getCallingUid();
18827        if (uid == Process.ROOT_UID) {
18828            return;
18829        }
18830
18831        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18832                Settings.getPackageNameForUid(mContext, uid), false)) {
18833            return;
18834        }
18835
18836        String msg = "Permission Denial: " + func + " from pid="
18837                + Binder.getCallingPid()
18838                + ", uid=" + uid
18839                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18840        Slog.w(TAG, msg);
18841        throw new SecurityException(msg);
18842    }
18843
18844    @Override
18845    public boolean updateConfiguration(Configuration values) {
18846        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
18847
18848        synchronized(this) {
18849            if (values == null && mWindowManager != null) {
18850                // sentinel: fetch the current configuration from the window manager
18851                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18852            }
18853
18854            if (mWindowManager != null) {
18855                // Update OOM levels based on display size.
18856                mProcessList.applyDisplaySize(mWindowManager);
18857            }
18858
18859            final long origId = Binder.clearCallingIdentity();
18860            try {
18861                if (values != null) {
18862                    Settings.System.clearConfiguration(values);
18863                }
18864                updateConfigurationLocked(values, null, false, false /* persistent */,
18865                        UserHandle.USER_NULL, false /* deferResume */,
18866                        mTmpUpdateConfigurationResult);
18867                return mTmpUpdateConfigurationResult.changes != 0;
18868            } finally {
18869                Binder.restoreCallingIdentity(origId);
18870            }
18871        }
18872    }
18873
18874    void updateUserConfigurationLocked() {
18875        final Configuration configuration = new Configuration(getGlobalConfiguration());
18876        final int currentUserId = mUserController.getCurrentUserIdLocked();
18877        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18878                currentUserId, Settings.System.canWrite(mContext));
18879        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
18880                false /* persistent */, currentUserId, false /* deferResume */);
18881    }
18882
18883    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18884            boolean initLocale) {
18885        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18886    }
18887
18888    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18889            boolean initLocale, boolean deferResume) {
18890        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18891        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18892                UserHandle.USER_NULL, deferResume);
18893    }
18894
18895    // To cache the list of supported system locales
18896    private String[] mSupportedSystemLocales = null;
18897
18898    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18899            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18900        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
18901                deferResume, null /* result */);
18902    }
18903
18904    /**
18905     * Do either or both things: (1) change the current configuration, and (2)
18906     * make sure the given activity is running with the (now) current
18907     * configuration.  Returns true if the activity has been left running, or
18908     * false if <var>starting</var> is being destroyed to match the new
18909     * configuration.
18910     *
18911     * @param userId is only used when persistent parameter is set to true to persist configuration
18912     *               for that particular user
18913     */
18914    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18915            boolean initLocale, boolean persistent, int userId, boolean deferResume,
18916            UpdateConfigurationResult result) {
18917        int changes = 0;
18918        boolean kept = true;
18919
18920        if (mWindowManager != null) {
18921            mWindowManager.deferSurfaceLayout();
18922        }
18923        try {
18924            if (values != null) {
18925                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
18926                        deferResume);
18927            }
18928
18929            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18930        } finally {
18931            if (mWindowManager != null) {
18932                mWindowManager.continueSurfaceLayout();
18933            }
18934        }
18935
18936        if (result != null) {
18937            result.changes = changes;
18938            result.activityRelaunched = !kept;
18939        }
18940        return kept;
18941    }
18942
18943    /** Update default (global) configuration and notify listeners about changes. */
18944    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
18945            boolean persistent, int userId, boolean deferResume) {
18946        mTempConfig.setTo(getGlobalConfiguration());
18947        final int changes = mTempConfig.updateFrom(values);
18948        if (changes == 0) {
18949            return 0;
18950        }
18951
18952        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18953                "Updating global configuration to: " + values);
18954
18955        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18956
18957        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18958            final LocaleList locales = values.getLocales();
18959            int bestLocaleIndex = 0;
18960            if (locales.size() > 1) {
18961                if (mSupportedSystemLocales == null) {
18962                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
18963                }
18964                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
18965            }
18966            SystemProperties.set("persist.sys.locale",
18967                    locales.get(bestLocaleIndex).toLanguageTag());
18968            LocaleList.setDefault(locales, bestLocaleIndex);
18969            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18970                    locales.get(bestLocaleIndex)));
18971        }
18972
18973        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
18974        mTempConfig.seq = mConfigurationSeq;
18975
18976        // Update stored global config and notify everyone about the change.
18977        mStackSupervisor.onConfigurationChanged(mTempConfig);
18978
18979        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
18980        // TODO(multi-display): Update UsageEvents#Event to include displayId.
18981        mUsageStatsService.reportConfigurationChange(mTempConfig,
18982                mUserController.getCurrentUserIdLocked());
18983
18984        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
18985        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
18986
18987        AttributeCache ac = AttributeCache.instance();
18988        if (ac != null) {
18989            ac.updateConfiguration(mTempConfig);
18990        }
18991
18992        // Make sure all resources in our process are updated right now, so that anyone who is going
18993        // to retrieve resource values after we return will be sure to get the new ones. This is
18994        // especially important during boot, where the first config change needs to guarantee all
18995        // resources have that config before following boot code is executed.
18996        mSystemThread.applyConfigurationToResources(mTempConfig);
18997
18998        // We need another copy of global config because we're scheduling some calls instead of
18999        // running them in place. We need to be sure that object we send will be handled unchanged.
19000        final Configuration configCopy = new Configuration(mTempConfig);
19001        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19002            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19003            msg.obj = configCopy;
19004            msg.arg1 = userId;
19005            mHandler.sendMessage(msg);
19006        }
19007
19008        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19009            ProcessRecord app = mLruProcesses.get(i);
19010            try {
19011                if (app.thread != null) {
19012                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19013                            + app.processName + " new config " + configCopy);
19014                    app.thread.scheduleConfigurationChanged(configCopy);
19015                }
19016            } catch (Exception e) {
19017            }
19018        }
19019
19020        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19021        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19022                | Intent.FLAG_RECEIVER_FOREGROUND);
19023        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19024                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19025                UserHandle.USER_ALL);
19026        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19027            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19028            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19029            if (initLocale || !mProcessesReady) {
19030                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19031            }
19032            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19033                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19034                    UserHandle.USER_ALL);
19035        }
19036
19037        // Override configuration of the default display duplicates global config, so we need to
19038        // update it also. This will also notify WindowManager about changes.
19039        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19040                DEFAULT_DISPLAY);
19041
19042        return changes;
19043    }
19044
19045    @Override
19046    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19047        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19048
19049        synchronized (this) {
19050            if (values == null && mWindowManager != null) {
19051                // sentinel: fetch the current configuration from the window manager
19052                values = mWindowManager.computeNewConfiguration(displayId);
19053            }
19054
19055            if (mWindowManager != null) {
19056                // Update OOM levels based on display size.
19057                mProcessList.applyDisplaySize(mWindowManager);
19058            }
19059
19060            final long origId = Binder.clearCallingIdentity();
19061            try {
19062                if (values != null) {
19063                    Settings.System.clearConfiguration(values);
19064                }
19065                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19066                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19067                return mTmpUpdateConfigurationResult.changes != 0;
19068            } finally {
19069                Binder.restoreCallingIdentity(origId);
19070            }
19071        }
19072    }
19073
19074    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19075            boolean deferResume, int displayId) {
19076        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19077                displayId, null /* result */);
19078    }
19079
19080    /**
19081     * Updates override configuration specific for the selected display. If no config is provided,
19082     * new one will be computed in WM based on current display info.
19083     */
19084    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19085            ActivityRecord starting, boolean deferResume, int displayId,
19086            UpdateConfigurationResult result) {
19087        int changes = 0;
19088        boolean kept = true;
19089
19090        if (mWindowManager != null) {
19091            mWindowManager.deferSurfaceLayout();
19092        }
19093        try {
19094            if (values != null) {
19095                if (displayId == DEFAULT_DISPLAY) {
19096                    // Override configuration of the default display duplicates global config, so
19097                    // we're calling global config update instead for default display. It will also
19098                    // apply the correct override config.
19099                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19100                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19101                } else {
19102                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19103                }
19104            }
19105
19106            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19107        } finally {
19108            if (mWindowManager != null) {
19109                mWindowManager.continueSurfaceLayout();
19110            }
19111        }
19112
19113        if (result != null) {
19114            result.changes = changes;
19115            result.activityRelaunched = !kept;
19116        }
19117        return kept;
19118    }
19119
19120    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19121            int displayId) {
19122        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19123        final int changes = mTempConfig.updateFrom(values);
19124        if (changes == 0) {
19125            return 0;
19126        }
19127
19128        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19129                + " for displayId=" + displayId);
19130        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19131
19132        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19133        if (isDensityChange) {
19134            // Reset the unsupported display size dialog.
19135            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19136
19137            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19138        }
19139
19140        // Update the configuration with WM first and check if any of the stacks need to be resized
19141        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19142        // necessary. This way we don't need to relaunch again afterwards in
19143        // ensureActivityConfigurationLocked().
19144        if (mWindowManager != null) {
19145            final int[] resizedStacks =
19146                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19147            if (resizedStacks != null) {
19148                for (int stackId : resizedStacks) {
19149                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19150                }
19151            }
19152        }
19153
19154        return changes;
19155    }
19156
19157    /** Applies latest configuration and/or visibility updates if needed. */
19158    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19159        boolean kept = true;
19160        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19161        // mainStack is null during startup.
19162        if (mainStack != null) {
19163            if (changes != 0 && starting == null) {
19164                // If the configuration changed, and the caller is not already
19165                // in the process of starting an activity, then find the top
19166                // activity to check if its configuration needs to change.
19167                starting = mainStack.topRunningActivityLocked();
19168            }
19169
19170            if (starting != null) {
19171                kept = starting.ensureActivityConfigurationLocked(changes,
19172                        false /* preserveWindow */);
19173                // And we need to make sure at this point that all other activities
19174                // are made visible with the correct configuration.
19175                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19176                        !PRESERVE_WINDOWS);
19177            }
19178        }
19179
19180        return kept;
19181    }
19182
19183    /** Helper method that requests bounds from WM and applies them to stack. */
19184    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19185        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19186        mStackSupervisor.resizeStackLocked(
19187                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19188                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19189    }
19190
19191    /**
19192     * Decide based on the configuration whether we should show the ANR,
19193     * crash, etc dialogs.  The idea is that if there is no affordance to
19194     * press the on-screen buttons, or the user experience would be more
19195     * greatly impacted than the crash itself, we shouldn't show the dialog.
19196     *
19197     * A thought: SystemUI might also want to get told about this, the Power
19198     * dialog / global actions also might want different behaviors.
19199     */
19200    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19201        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19202                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19203                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19204        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19205        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19206                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19207        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19208    }
19209
19210    @Override
19211    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19212        synchronized (this) {
19213            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19214            if (srec != null) {
19215                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19216            }
19217        }
19218        return false;
19219    }
19220
19221    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19222            Intent resultData) {
19223
19224        synchronized (this) {
19225            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19226            if (r != null) {
19227                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19228            }
19229            return false;
19230        }
19231    }
19232
19233    public int getLaunchedFromUid(IBinder activityToken) {
19234        ActivityRecord srec;
19235        synchronized (this) {
19236            srec = ActivityRecord.forTokenLocked(activityToken);
19237        }
19238        if (srec == null) {
19239            return -1;
19240        }
19241        return srec.launchedFromUid;
19242    }
19243
19244    public String getLaunchedFromPackage(IBinder activityToken) {
19245        ActivityRecord srec;
19246        synchronized (this) {
19247            srec = ActivityRecord.forTokenLocked(activityToken);
19248        }
19249        if (srec == null) {
19250            return null;
19251        }
19252        return srec.launchedFromPackage;
19253    }
19254
19255    // =========================================================
19256    // LIFETIME MANAGEMENT
19257    // =========================================================
19258
19259    // Returns whether the app is receiving broadcast.
19260    // If receiving, fetch all broadcast queues which the app is
19261    // the current [or imminent] receiver on.
19262    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19263            ArraySet<BroadcastQueue> receivingQueues) {
19264        if (!app.curReceivers.isEmpty()) {
19265            for (BroadcastRecord r : app.curReceivers) {
19266                receivingQueues.add(r.queue);
19267            }
19268            return true;
19269        }
19270
19271        // It's not the current receiver, but it might be starting up to become one
19272        for (BroadcastQueue queue : mBroadcastQueues) {
19273            final BroadcastRecord r = queue.mPendingBroadcast;
19274            if (r != null && r.curApp == app) {
19275                // found it; report which queue it's in
19276                receivingQueues.add(queue);
19277            }
19278        }
19279
19280        return !receivingQueues.isEmpty();
19281    }
19282
19283    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19284            int targetUid, ComponentName targetComponent, String targetProcess) {
19285        if (!mTrackingAssociations) {
19286            return null;
19287        }
19288        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19289                = mAssociations.get(targetUid);
19290        if (components == null) {
19291            components = new ArrayMap<>();
19292            mAssociations.put(targetUid, components);
19293        }
19294        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19295        if (sourceUids == null) {
19296            sourceUids = new SparseArray<>();
19297            components.put(targetComponent, sourceUids);
19298        }
19299        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19300        if (sourceProcesses == null) {
19301            sourceProcesses = new ArrayMap<>();
19302            sourceUids.put(sourceUid, sourceProcesses);
19303        }
19304        Association ass = sourceProcesses.get(sourceProcess);
19305        if (ass == null) {
19306            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19307                    targetProcess);
19308            sourceProcesses.put(sourceProcess, ass);
19309        }
19310        ass.mCount++;
19311        ass.mNesting++;
19312        if (ass.mNesting == 1) {
19313            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19314            ass.mLastState = sourceState;
19315        }
19316        return ass;
19317    }
19318
19319    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19320            ComponentName targetComponent) {
19321        if (!mTrackingAssociations) {
19322            return;
19323        }
19324        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19325                = mAssociations.get(targetUid);
19326        if (components == null) {
19327            return;
19328        }
19329        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19330        if (sourceUids == null) {
19331            return;
19332        }
19333        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19334        if (sourceProcesses == null) {
19335            return;
19336        }
19337        Association ass = sourceProcesses.get(sourceProcess);
19338        if (ass == null || ass.mNesting <= 0) {
19339            return;
19340        }
19341        ass.mNesting--;
19342        if (ass.mNesting == 0) {
19343            long uptime = SystemClock.uptimeMillis();
19344            ass.mTime += uptime - ass.mStartTime;
19345            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19346                    += uptime - ass.mLastStateUptime;
19347            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19348        }
19349    }
19350
19351    private void noteUidProcessState(final int uid, final int state) {
19352        mBatteryStatsService.noteUidProcessState(uid, state);
19353        if (mTrackingAssociations) {
19354            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19355                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19356                        = mAssociations.valueAt(i1);
19357                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19358                    SparseArray<ArrayMap<String, Association>> sourceUids
19359                            = targetComponents.valueAt(i2);
19360                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19361                    if (sourceProcesses != null) {
19362                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19363                            Association ass = sourceProcesses.valueAt(i4);
19364                            if (ass.mNesting >= 1) {
19365                                // currently associated
19366                                long uptime = SystemClock.uptimeMillis();
19367                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19368                                        += uptime - ass.mLastStateUptime;
19369                                ass.mLastState = state;
19370                                ass.mLastStateUptime = uptime;
19371                            }
19372                        }
19373                    }
19374                }
19375            }
19376        }
19377    }
19378
19379    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19380            boolean doingAll, long now) {
19381        if (mAdjSeq == app.adjSeq) {
19382            // This adjustment has already been computed.
19383            return app.curRawAdj;
19384        }
19385
19386        if (app.thread == null) {
19387            app.adjSeq = mAdjSeq;
19388            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19389            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19390            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19391        }
19392
19393        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19394        app.adjSource = null;
19395        app.adjTarget = null;
19396        app.empty = false;
19397        app.cached = false;
19398
19399        final int activitiesSize = app.activities.size();
19400
19401        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19402            // The max adjustment doesn't allow this app to be anything
19403            // below foreground, so it is not worth doing work for it.
19404            app.adjType = "fixed";
19405            app.adjSeq = mAdjSeq;
19406            app.curRawAdj = app.maxAdj;
19407            app.foregroundActivities = false;
19408            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19409            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19410            // System processes can do UI, and when they do we want to have
19411            // them trim their memory after the user leaves the UI.  To
19412            // facilitate this, here we need to determine whether or not it
19413            // is currently showing UI.
19414            app.systemNoUi = true;
19415            if (app == TOP_APP) {
19416                app.systemNoUi = false;
19417                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19418                app.adjType = "pers-top-activity";
19419            } else if (app.hasTopUi) {
19420                app.systemNoUi = false;
19421                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19422                app.adjType = "pers-top-ui";
19423            } else if (activitiesSize > 0) {
19424                for (int j = 0; j < activitiesSize; j++) {
19425                    final ActivityRecord r = app.activities.get(j);
19426                    if (r.visible) {
19427                        app.systemNoUi = false;
19428                    }
19429                }
19430            }
19431            if (!app.systemNoUi) {
19432                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19433            }
19434            return (app.curAdj=app.maxAdj);
19435        }
19436
19437        app.systemNoUi = false;
19438
19439        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19440
19441        // Determine the importance of the process, starting with most
19442        // important to least, and assign an appropriate OOM adjustment.
19443        int adj;
19444        int schedGroup;
19445        int procState;
19446        boolean foregroundActivities = false;
19447        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19448        if (app == TOP_APP) {
19449            // The last app on the list is the foreground app.
19450            adj = ProcessList.FOREGROUND_APP_ADJ;
19451            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19452            app.adjType = "top-activity";
19453            foregroundActivities = true;
19454            procState = PROCESS_STATE_CUR_TOP;
19455        } else if (app.instrumentationClass != null) {
19456            // Don't want to kill running instrumentation.
19457            adj = ProcessList.FOREGROUND_APP_ADJ;
19458            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19459            app.adjType = "instrumentation";
19460            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19461        } else if (isReceivingBroadcastLocked(app, queues)) {
19462            // An app that is currently receiving a broadcast also
19463            // counts as being in the foreground for OOM killer purposes.
19464            // It's placed in a sched group based on the nature of the
19465            // broadcast as reflected by which queue it's active in.
19466            adj = ProcessList.FOREGROUND_APP_ADJ;
19467            schedGroup = (queues.contains(mFgBroadcastQueue))
19468                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19469            app.adjType = "broadcast";
19470            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19471        } else if (app.executingServices.size() > 0) {
19472            // An app that is currently executing a service callback also
19473            // counts as being in the foreground.
19474            adj = ProcessList.FOREGROUND_APP_ADJ;
19475            schedGroup = app.execServicesFg ?
19476                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19477            app.adjType = "exec-service";
19478            procState = ActivityManager.PROCESS_STATE_SERVICE;
19479            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19480        } else {
19481            // As far as we know the process is empty.  We may change our mind later.
19482            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19483            // At this point we don't actually know the adjustment.  Use the cached adj
19484            // value that the caller wants us to.
19485            adj = cachedAdj;
19486            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19487            app.cached = true;
19488            app.empty = true;
19489            app.adjType = "cch-empty";
19490        }
19491
19492        // Examine all activities if not already foreground.
19493        if (!foregroundActivities && activitiesSize > 0) {
19494            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19495            for (int j = 0; j < activitiesSize; j++) {
19496                final ActivityRecord r = app.activities.get(j);
19497                if (r.app != app) {
19498                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19499                            + " instead of expected " + app);
19500                    if (r.app == null || (r.app.uid == app.uid)) {
19501                        // Only fix things up when they look sane
19502                        r.app = app;
19503                    } else {
19504                        continue;
19505                    }
19506                }
19507                if (r.visible) {
19508                    // App has a visible activity; only upgrade adjustment.
19509                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19510                        adj = ProcessList.VISIBLE_APP_ADJ;
19511                        app.adjType = "visible";
19512                    }
19513                    if (procState > PROCESS_STATE_CUR_TOP) {
19514                        procState = PROCESS_STATE_CUR_TOP;
19515                    }
19516                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19517                    app.cached = false;
19518                    app.empty = false;
19519                    foregroundActivities = true;
19520                    if (r.task != null && minLayer > 0) {
19521                        final int layer = r.task.mLayerRank;
19522                        if (layer >= 0 && minLayer > layer) {
19523                            minLayer = layer;
19524                        }
19525                    }
19526                    break;
19527                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19528                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19529                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19530                        app.adjType = "pausing";
19531                    }
19532                    if (procState > PROCESS_STATE_CUR_TOP) {
19533                        procState = PROCESS_STATE_CUR_TOP;
19534                    }
19535                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19536                    app.cached = false;
19537                    app.empty = false;
19538                    foregroundActivities = true;
19539                } else if (r.state == ActivityState.STOPPING) {
19540                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19541                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19542                        app.adjType = "stopping";
19543                    }
19544                    // For the process state, we will at this point consider the
19545                    // process to be cached.  It will be cached either as an activity
19546                    // or empty depending on whether the activity is finishing.  We do
19547                    // this so that we can treat the process as cached for purposes of
19548                    // memory trimming (determing current memory level, trim command to
19549                    // send to process) since there can be an arbitrary number of stopping
19550                    // processes and they should soon all go into the cached state.
19551                    if (!r.finishing) {
19552                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19553                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19554                        }
19555                    }
19556                    app.cached = false;
19557                    app.empty = false;
19558                    foregroundActivities = true;
19559                } else {
19560                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19561                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19562                        app.adjType = "cch-act";
19563                    }
19564                }
19565            }
19566            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19567                adj += minLayer;
19568            }
19569        }
19570
19571        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19572                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19573            if (app.foregroundServices) {
19574                // The user is aware of this app, so make it visible.
19575                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19576                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19577                app.cached = false;
19578                app.adjType = "fg-service";
19579                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19580            } else if (app.forcingToForeground != null) {
19581                // The user is aware of this app, so make it visible.
19582                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19583                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19584                app.cached = false;
19585                app.adjType = "force-fg";
19586                app.adjSource = app.forcingToForeground;
19587                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19588            }
19589        }
19590
19591        if (app == mHeavyWeightProcess) {
19592            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19593                // We don't want to kill the current heavy-weight process.
19594                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19595                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19596                app.cached = false;
19597                app.adjType = "heavy";
19598            }
19599            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19600                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19601            }
19602        }
19603
19604        if (app == mHomeProcess) {
19605            if (adj > ProcessList.HOME_APP_ADJ) {
19606                // This process is hosting what we currently consider to be the
19607                // home app, so we don't want to let it go into the background.
19608                adj = ProcessList.HOME_APP_ADJ;
19609                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19610                app.cached = false;
19611                app.adjType = "home";
19612            }
19613            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19614                procState = ActivityManager.PROCESS_STATE_HOME;
19615            }
19616        }
19617
19618        if (app == mPreviousProcess && app.activities.size() > 0) {
19619            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19620                // This was the previous process that showed UI to the user.
19621                // We want to try to keep it around more aggressively, to give
19622                // a good experience around switching between two apps.
19623                adj = ProcessList.PREVIOUS_APP_ADJ;
19624                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19625                app.cached = false;
19626                app.adjType = "previous";
19627            }
19628            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19629                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19630            }
19631        }
19632
19633        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19634                + " reason=" + app.adjType);
19635
19636        // By default, we use the computed adjustment.  It may be changed if
19637        // there are applications dependent on our services or providers, but
19638        // this gives us a baseline and makes sure we don't get into an
19639        // infinite recursion.
19640        app.adjSeq = mAdjSeq;
19641        app.curRawAdj = adj;
19642        app.hasStartedServices = false;
19643
19644        if (mBackupTarget != null && app == mBackupTarget.app) {
19645            // If possible we want to avoid killing apps while they're being backed up
19646            if (adj > ProcessList.BACKUP_APP_ADJ) {
19647                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19648                adj = ProcessList.BACKUP_APP_ADJ;
19649                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19650                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19651                }
19652                app.adjType = "backup";
19653                app.cached = false;
19654            }
19655            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19656                procState = ActivityManager.PROCESS_STATE_BACKUP;
19657            }
19658        }
19659
19660        boolean mayBeTop = false;
19661
19662        for (int is = app.services.size()-1;
19663                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19664                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19665                        || procState > ActivityManager.PROCESS_STATE_TOP);
19666                is--) {
19667            ServiceRecord s = app.services.valueAt(is);
19668            if (s.startRequested) {
19669                app.hasStartedServices = true;
19670                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19671                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19672                }
19673                if (app.hasShownUi && app != mHomeProcess) {
19674                    // If this process has shown some UI, let it immediately
19675                    // go to the LRU list because it may be pretty heavy with
19676                    // UI stuff.  We'll tag it with a label just to help
19677                    // debug and understand what is going on.
19678                    if (adj > ProcessList.SERVICE_ADJ) {
19679                        app.adjType = "cch-started-ui-services";
19680                    }
19681                } else {
19682                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19683                        // This service has seen some activity within
19684                        // recent memory, so we will keep its process ahead
19685                        // of the background processes.
19686                        if (adj > ProcessList.SERVICE_ADJ) {
19687                            adj = ProcessList.SERVICE_ADJ;
19688                            app.adjType = "started-services";
19689                            app.cached = false;
19690                        }
19691                    }
19692                    // If we have let the service slide into the background
19693                    // state, still have some text describing what it is doing
19694                    // even though the service no longer has an impact.
19695                    if (adj > ProcessList.SERVICE_ADJ) {
19696                        app.adjType = "cch-started-services";
19697                    }
19698                }
19699            }
19700
19701            for (int conni = s.connections.size()-1;
19702                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19703                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19704                            || procState > ActivityManager.PROCESS_STATE_TOP);
19705                    conni--) {
19706                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19707                for (int i = 0;
19708                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19709                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19710                                || procState > ActivityManager.PROCESS_STATE_TOP);
19711                        i++) {
19712                    // XXX should compute this based on the max of
19713                    // all connected clients.
19714                    ConnectionRecord cr = clist.get(i);
19715                    if (cr.binding.client == app) {
19716                        // Binding to ourself is not interesting.
19717                        continue;
19718                    }
19719
19720                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19721                        ProcessRecord client = cr.binding.client;
19722                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19723                                TOP_APP, doingAll, now);
19724                        int clientProcState = client.curProcState;
19725                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19726                            // If the other app is cached for any reason, for purposes here
19727                            // we are going to consider it empty.  The specific cached state
19728                            // doesn't propagate except under certain conditions.
19729                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19730                        }
19731                        String adjType = null;
19732                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19733                            // Not doing bind OOM management, so treat
19734                            // this guy more like a started service.
19735                            if (app.hasShownUi && app != mHomeProcess) {
19736                                // If this process has shown some UI, let it immediately
19737                                // go to the LRU list because it may be pretty heavy with
19738                                // UI stuff.  We'll tag it with a label just to help
19739                                // debug and understand what is going on.
19740                                if (adj > clientAdj) {
19741                                    adjType = "cch-bound-ui-services";
19742                                }
19743                                app.cached = false;
19744                                clientAdj = adj;
19745                                clientProcState = procState;
19746                            } else {
19747                                if (now >= (s.lastActivity
19748                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19749                                    // This service has not seen activity within
19750                                    // recent memory, so allow it to drop to the
19751                                    // LRU list if there is no other reason to keep
19752                                    // it around.  We'll also tag it with a label just
19753                                    // to help debug and undertand what is going on.
19754                                    if (adj > clientAdj) {
19755                                        adjType = "cch-bound-services";
19756                                    }
19757                                    clientAdj = adj;
19758                                }
19759                            }
19760                        }
19761                        if (adj > clientAdj) {
19762                            // If this process has recently shown UI, and
19763                            // the process that is binding to it is less
19764                            // important than being visible, then we don't
19765                            // care about the binding as much as we care
19766                            // about letting this process get into the LRU
19767                            // list to be killed and restarted if needed for
19768                            // memory.
19769                            if (app.hasShownUi && app != mHomeProcess
19770                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19771                                adjType = "cch-bound-ui-services";
19772                            } else {
19773                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19774                                        |Context.BIND_IMPORTANT)) != 0) {
19775                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19776                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19777                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19778                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19779                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19780                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19781                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19782                                    adj = clientAdj;
19783                                } else {
19784                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19785                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19786                                    }
19787                                }
19788                                if (!client.cached) {
19789                                    app.cached = false;
19790                                }
19791                                adjType = "service";
19792                            }
19793                        }
19794                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19795                            // This will treat important bound services identically to
19796                            // the top app, which may behave differently than generic
19797                            // foreground work.
19798                            if (client.curSchedGroup > schedGroup) {
19799                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19800                                    schedGroup = client.curSchedGroup;
19801                                } else {
19802                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19803                                }
19804                            }
19805                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19806                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19807                                    // Special handling of clients who are in the top state.
19808                                    // We *may* want to consider this process to be in the
19809                                    // top state as well, but only if there is not another
19810                                    // reason for it to be running.  Being on the top is a
19811                                    // special state, meaning you are specifically running
19812                                    // for the current top app.  If the process is already
19813                                    // running in the background for some other reason, it
19814                                    // is more important to continue considering it to be
19815                                    // in the background state.
19816                                    mayBeTop = true;
19817                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19818                                } else {
19819                                    // Special handling for above-top states (persistent
19820                                    // processes).  These should not bring the current process
19821                                    // into the top state, since they are not on top.  Instead
19822                                    // give them the best state after that.
19823                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19824                                        clientProcState =
19825                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19826                                    } else if (mWakefulness
19827                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19828                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19829                                                    != 0) {
19830                                        clientProcState =
19831                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19832                                    } else {
19833                                        clientProcState =
19834                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19835                                    }
19836                                }
19837                            }
19838                        } else {
19839                            if (clientProcState <
19840                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19841                                clientProcState =
19842                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19843                            }
19844                        }
19845                        if (procState > clientProcState) {
19846                            procState = clientProcState;
19847                        }
19848                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19849                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19850                            app.pendingUiClean = true;
19851                        }
19852                        if (adjType != null) {
19853                            app.adjType = adjType;
19854                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19855                                    .REASON_SERVICE_IN_USE;
19856                            app.adjSource = cr.binding.client;
19857                            app.adjSourceProcState = clientProcState;
19858                            app.adjTarget = s.name;
19859                        }
19860                    }
19861                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19862                        app.treatLikeActivity = true;
19863                    }
19864                    final ActivityRecord a = cr.activity;
19865                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19866                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19867                            (a.visible || a.state == ActivityState.RESUMED ||
19868                             a.state == ActivityState.PAUSING)) {
19869                            adj = ProcessList.FOREGROUND_APP_ADJ;
19870                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19871                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19872                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19873                                } else {
19874                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19875                                }
19876                            }
19877                            app.cached = false;
19878                            app.adjType = "service";
19879                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19880                                    .REASON_SERVICE_IN_USE;
19881                            app.adjSource = a;
19882                            app.adjSourceProcState = procState;
19883                            app.adjTarget = s.name;
19884                        }
19885                    }
19886                }
19887            }
19888        }
19889
19890        for (int provi = app.pubProviders.size()-1;
19891                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19892                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19893                        || procState > ActivityManager.PROCESS_STATE_TOP);
19894                provi--) {
19895            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19896            for (int i = cpr.connections.size()-1;
19897                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19898                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19899                            || procState > ActivityManager.PROCESS_STATE_TOP);
19900                    i--) {
19901                ContentProviderConnection conn = cpr.connections.get(i);
19902                ProcessRecord client = conn.client;
19903                if (client == app) {
19904                    // Being our own client is not interesting.
19905                    continue;
19906                }
19907                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19908                int clientProcState = client.curProcState;
19909                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19910                    // If the other app is cached for any reason, for purposes here
19911                    // we are going to consider it empty.
19912                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19913                }
19914                if (adj > clientAdj) {
19915                    if (app.hasShownUi && app != mHomeProcess
19916                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19917                        app.adjType = "cch-ui-provider";
19918                    } else {
19919                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19920                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19921                        app.adjType = "provider";
19922                    }
19923                    app.cached &= client.cached;
19924                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19925                            .REASON_PROVIDER_IN_USE;
19926                    app.adjSource = client;
19927                    app.adjSourceProcState = clientProcState;
19928                    app.adjTarget = cpr.name;
19929                }
19930                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19931                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19932                        // Special handling of clients who are in the top state.
19933                        // We *may* want to consider this process to be in the
19934                        // top state as well, but only if there is not another
19935                        // reason for it to be running.  Being on the top is a
19936                        // special state, meaning you are specifically running
19937                        // for the current top app.  If the process is already
19938                        // running in the background for some other reason, it
19939                        // is more important to continue considering it to be
19940                        // in the background state.
19941                        mayBeTop = true;
19942                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19943                    } else {
19944                        // Special handling for above-top states (persistent
19945                        // processes).  These should not bring the current process
19946                        // into the top state, since they are not on top.  Instead
19947                        // give them the best state after that.
19948                        clientProcState =
19949                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19950                    }
19951                }
19952                if (procState > clientProcState) {
19953                    procState = clientProcState;
19954                }
19955                if (client.curSchedGroup > schedGroup) {
19956                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19957                }
19958            }
19959            // If the provider has external (non-framework) process
19960            // dependencies, ensure that its adjustment is at least
19961            // FOREGROUND_APP_ADJ.
19962            if (cpr.hasExternalProcessHandles()) {
19963                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19964                    adj = ProcessList.FOREGROUND_APP_ADJ;
19965                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19966                    app.cached = false;
19967                    app.adjType = "provider";
19968                    app.adjTarget = cpr.name;
19969                }
19970                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19971                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19972                }
19973            }
19974        }
19975
19976        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19977            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19978                adj = ProcessList.PREVIOUS_APP_ADJ;
19979                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19980                app.cached = false;
19981                app.adjType = "provider";
19982            }
19983            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19984                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19985            }
19986        }
19987
19988        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19989            // A client of one of our services or providers is in the top state.  We
19990            // *may* want to be in the top state, but not if we are already running in
19991            // the background for some other reason.  For the decision here, we are going
19992            // to pick out a few specific states that we want to remain in when a client
19993            // is top (states that tend to be longer-term) and otherwise allow it to go
19994            // to the top state.
19995            switch (procState) {
19996                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19997                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19998                case ActivityManager.PROCESS_STATE_SERVICE:
19999                    // These all are longer-term states, so pull them up to the top
20000                    // of the background states, but not all the way to the top state.
20001                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20002                    break;
20003                default:
20004                    // Otherwise, top is a better choice, so take it.
20005                    procState = ActivityManager.PROCESS_STATE_TOP;
20006                    break;
20007            }
20008        }
20009
20010        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20011            if (app.hasClientActivities) {
20012                // This is a cached process, but with client activities.  Mark it so.
20013                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20014                app.adjType = "cch-client-act";
20015            } else if (app.treatLikeActivity) {
20016                // This is a cached process, but somebody wants us to treat it like it has
20017                // an activity, okay!
20018                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20019                app.adjType = "cch-as-act";
20020            }
20021        }
20022
20023        if (adj == ProcessList.SERVICE_ADJ) {
20024            if (doingAll) {
20025                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20026                mNewNumServiceProcs++;
20027                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20028                if (!app.serviceb) {
20029                    // This service isn't far enough down on the LRU list to
20030                    // normally be a B service, but if we are low on RAM and it
20031                    // is large we want to force it down since we would prefer to
20032                    // keep launcher over it.
20033                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20034                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20035                        app.serviceHighRam = true;
20036                        app.serviceb = true;
20037                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20038                    } else {
20039                        mNewNumAServiceProcs++;
20040                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20041                    }
20042                } else {
20043                    app.serviceHighRam = false;
20044                }
20045            }
20046            if (app.serviceb) {
20047                adj = ProcessList.SERVICE_B_ADJ;
20048            }
20049        }
20050
20051        app.curRawAdj = adj;
20052
20053        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20054        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20055        if (adj > app.maxAdj) {
20056            adj = app.maxAdj;
20057            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20058                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20059            }
20060        }
20061
20062        // Do final modification to adj.  Everything we do between here and applying
20063        // the final setAdj must be done in this function, because we will also use
20064        // it when computing the final cached adj later.  Note that we don't need to
20065        // worry about this for max adj above, since max adj will always be used to
20066        // keep it out of the cached vaues.
20067        app.curAdj = app.modifyRawOomAdj(adj);
20068        app.curSchedGroup = schedGroup;
20069        app.curProcState = procState;
20070        app.foregroundActivities = foregroundActivities;
20071
20072        return app.curRawAdj;
20073    }
20074
20075    /**
20076     * Record new PSS sample for a process.
20077     */
20078    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20079            long now) {
20080        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20081                swapPss * 1024);
20082        proc.lastPssTime = now;
20083        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20084        if (DEBUG_PSS) Slog.d(TAG_PSS,
20085                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20086                + " state=" + ProcessList.makeProcStateString(procState));
20087        if (proc.initialIdlePss == 0) {
20088            proc.initialIdlePss = pss;
20089        }
20090        proc.lastPss = pss;
20091        proc.lastSwapPss = swapPss;
20092        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20093            proc.lastCachedPss = pss;
20094            proc.lastCachedSwapPss = swapPss;
20095        }
20096
20097        final SparseArray<Pair<Long, String>> watchUids
20098                = mMemWatchProcesses.getMap().get(proc.processName);
20099        Long check = null;
20100        if (watchUids != null) {
20101            Pair<Long, String> val = watchUids.get(proc.uid);
20102            if (val == null) {
20103                val = watchUids.get(0);
20104            }
20105            if (val != null) {
20106                check = val.first;
20107            }
20108        }
20109        if (check != null) {
20110            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20111                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20112                if (!isDebuggable) {
20113                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20114                        isDebuggable = true;
20115                    }
20116                }
20117                if (isDebuggable) {
20118                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20119                    final ProcessRecord myProc = proc;
20120                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20121                    mMemWatchDumpProcName = proc.processName;
20122                    mMemWatchDumpFile = heapdumpFile.toString();
20123                    mMemWatchDumpPid = proc.pid;
20124                    mMemWatchDumpUid = proc.uid;
20125                    BackgroundThread.getHandler().post(new Runnable() {
20126                        @Override
20127                        public void run() {
20128                            revokeUriPermission(ActivityThread.currentActivityThread()
20129                                            .getApplicationThread(),
20130                                    DumpHeapActivity.JAVA_URI,
20131                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20132                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20133                                    UserHandle.myUserId());
20134                            ParcelFileDescriptor fd = null;
20135                            try {
20136                                heapdumpFile.delete();
20137                                fd = ParcelFileDescriptor.open(heapdumpFile,
20138                                        ParcelFileDescriptor.MODE_CREATE |
20139                                                ParcelFileDescriptor.MODE_TRUNCATE |
20140                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20141                                                ParcelFileDescriptor.MODE_APPEND);
20142                                IApplicationThread thread = myProc.thread;
20143                                if (thread != null) {
20144                                    try {
20145                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20146                                                "Requesting dump heap from "
20147                                                + myProc + " to " + heapdumpFile);
20148                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20149                                    } catch (RemoteException e) {
20150                                    }
20151                                }
20152                            } catch (FileNotFoundException e) {
20153                                e.printStackTrace();
20154                            } finally {
20155                                if (fd != null) {
20156                                    try {
20157                                        fd.close();
20158                                    } catch (IOException e) {
20159                                    }
20160                                }
20161                            }
20162                        }
20163                    });
20164                } else {
20165                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20166                            + ", but debugging not enabled");
20167                }
20168            }
20169        }
20170    }
20171
20172    /**
20173     * Schedule PSS collection of a process.
20174     */
20175    void requestPssLocked(ProcessRecord proc, int procState) {
20176        if (mPendingPssProcesses.contains(proc)) {
20177            return;
20178        }
20179        if (mPendingPssProcesses.size() == 0) {
20180            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20181        }
20182        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20183        proc.pssProcState = procState;
20184        mPendingPssProcesses.add(proc);
20185    }
20186
20187    /**
20188     * Schedule PSS collection of all processes.
20189     */
20190    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20191        if (!always) {
20192            if (now < (mLastFullPssTime +
20193                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20194                return;
20195            }
20196        }
20197        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20198        mLastFullPssTime = now;
20199        mFullPssPending = true;
20200        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20201        mPendingPssProcesses.clear();
20202        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20203            ProcessRecord app = mLruProcesses.get(i);
20204            if (app.thread == null
20205                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20206                continue;
20207            }
20208            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20209                app.pssProcState = app.setProcState;
20210                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20211                        mTestPssMode, isSleepingLocked(), now);
20212                mPendingPssProcesses.add(app);
20213            }
20214        }
20215        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20216    }
20217
20218    public void setTestPssMode(boolean enabled) {
20219        synchronized (this) {
20220            mTestPssMode = enabled;
20221            if (enabled) {
20222                // Whenever we enable the mode, we want to take a snapshot all of current
20223                // process mem use.
20224                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20225            }
20226        }
20227    }
20228
20229    /**
20230     * Ask a given process to GC right now.
20231     */
20232    final void performAppGcLocked(ProcessRecord app) {
20233        try {
20234            app.lastRequestedGc = SystemClock.uptimeMillis();
20235            if (app.thread != null) {
20236                if (app.reportLowMemory) {
20237                    app.reportLowMemory = false;
20238                    app.thread.scheduleLowMemory();
20239                } else {
20240                    app.thread.processInBackground();
20241                }
20242            }
20243        } catch (Exception e) {
20244            // whatever.
20245        }
20246    }
20247
20248    /**
20249     * Returns true if things are idle enough to perform GCs.
20250     */
20251    private final boolean canGcNowLocked() {
20252        boolean processingBroadcasts = false;
20253        for (BroadcastQueue q : mBroadcastQueues) {
20254            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20255                processingBroadcasts = true;
20256            }
20257        }
20258        return !processingBroadcasts
20259                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20260    }
20261
20262    /**
20263     * Perform GCs on all processes that are waiting for it, but only
20264     * if things are idle.
20265     */
20266    final void performAppGcsLocked() {
20267        final int N = mProcessesToGc.size();
20268        if (N <= 0) {
20269            return;
20270        }
20271        if (canGcNowLocked()) {
20272            while (mProcessesToGc.size() > 0) {
20273                ProcessRecord proc = mProcessesToGc.remove(0);
20274                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20275                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20276                            <= SystemClock.uptimeMillis()) {
20277                        // To avoid spamming the system, we will GC processes one
20278                        // at a time, waiting a few seconds between each.
20279                        performAppGcLocked(proc);
20280                        scheduleAppGcsLocked();
20281                        return;
20282                    } else {
20283                        // It hasn't been long enough since we last GCed this
20284                        // process...  put it in the list to wait for its time.
20285                        addProcessToGcListLocked(proc);
20286                        break;
20287                    }
20288                }
20289            }
20290
20291            scheduleAppGcsLocked();
20292        }
20293    }
20294
20295    /**
20296     * If all looks good, perform GCs on all processes waiting for them.
20297     */
20298    final void performAppGcsIfAppropriateLocked() {
20299        if (canGcNowLocked()) {
20300            performAppGcsLocked();
20301            return;
20302        }
20303        // Still not idle, wait some more.
20304        scheduleAppGcsLocked();
20305    }
20306
20307    /**
20308     * Schedule the execution of all pending app GCs.
20309     */
20310    final void scheduleAppGcsLocked() {
20311        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20312
20313        if (mProcessesToGc.size() > 0) {
20314            // Schedule a GC for the time to the next process.
20315            ProcessRecord proc = mProcessesToGc.get(0);
20316            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20317
20318            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20319            long now = SystemClock.uptimeMillis();
20320            if (when < (now+GC_TIMEOUT)) {
20321                when = now + GC_TIMEOUT;
20322            }
20323            mHandler.sendMessageAtTime(msg, when);
20324        }
20325    }
20326
20327    /**
20328     * Add a process to the array of processes waiting to be GCed.  Keeps the
20329     * list in sorted order by the last GC time.  The process can't already be
20330     * on the list.
20331     */
20332    final void addProcessToGcListLocked(ProcessRecord proc) {
20333        boolean added = false;
20334        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20335            if (mProcessesToGc.get(i).lastRequestedGc <
20336                    proc.lastRequestedGc) {
20337                added = true;
20338                mProcessesToGc.add(i+1, proc);
20339                break;
20340            }
20341        }
20342        if (!added) {
20343            mProcessesToGc.add(0, proc);
20344        }
20345    }
20346
20347    /**
20348     * Set up to ask a process to GC itself.  This will either do it
20349     * immediately, or put it on the list of processes to gc the next
20350     * time things are idle.
20351     */
20352    final void scheduleAppGcLocked(ProcessRecord app) {
20353        long now = SystemClock.uptimeMillis();
20354        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20355            return;
20356        }
20357        if (!mProcessesToGc.contains(app)) {
20358            addProcessToGcListLocked(app);
20359            scheduleAppGcsLocked();
20360        }
20361    }
20362
20363    final void checkExcessivePowerUsageLocked(boolean doKills) {
20364        updateCpuStatsNow();
20365
20366        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20367        boolean doWakeKills = doKills;
20368        boolean doCpuKills = doKills;
20369        if (mLastPowerCheckRealtime == 0) {
20370            doWakeKills = false;
20371        }
20372        if (mLastPowerCheckUptime == 0) {
20373            doCpuKills = false;
20374        }
20375        if (stats.isScreenOn()) {
20376            doWakeKills = false;
20377        }
20378        final long curRealtime = SystemClock.elapsedRealtime();
20379        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20380        final long curUptime = SystemClock.uptimeMillis();
20381        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20382        mLastPowerCheckRealtime = curRealtime;
20383        mLastPowerCheckUptime = curUptime;
20384        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20385            doWakeKills = false;
20386        }
20387        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20388            doCpuKills = false;
20389        }
20390        int i = mLruProcesses.size();
20391        while (i > 0) {
20392            i--;
20393            ProcessRecord app = mLruProcesses.get(i);
20394            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20395                long wtime;
20396                synchronized (stats) {
20397                    wtime = stats.getProcessWakeTime(app.info.uid,
20398                            app.pid, curRealtime);
20399                }
20400                long wtimeUsed = wtime - app.lastWakeTime;
20401                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20402                if (DEBUG_POWER) {
20403                    StringBuilder sb = new StringBuilder(128);
20404                    sb.append("Wake for ");
20405                    app.toShortString(sb);
20406                    sb.append(": over ");
20407                    TimeUtils.formatDuration(realtimeSince, sb);
20408                    sb.append(" used ");
20409                    TimeUtils.formatDuration(wtimeUsed, sb);
20410                    sb.append(" (");
20411                    sb.append((wtimeUsed*100)/realtimeSince);
20412                    sb.append("%)");
20413                    Slog.i(TAG_POWER, sb.toString());
20414                    sb.setLength(0);
20415                    sb.append("CPU for ");
20416                    app.toShortString(sb);
20417                    sb.append(": over ");
20418                    TimeUtils.formatDuration(uptimeSince, sb);
20419                    sb.append(" used ");
20420                    TimeUtils.formatDuration(cputimeUsed, sb);
20421                    sb.append(" (");
20422                    sb.append((cputimeUsed*100)/uptimeSince);
20423                    sb.append("%)");
20424                    Slog.i(TAG_POWER, sb.toString());
20425                }
20426                // If a process has held a wake lock for more
20427                // than 50% of the time during this period,
20428                // that sounds bad.  Kill!
20429                if (doWakeKills && realtimeSince > 0
20430                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20431                    synchronized (stats) {
20432                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20433                                realtimeSince, wtimeUsed);
20434                    }
20435                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20436                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20437                } else if (doCpuKills && uptimeSince > 0
20438                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20439                    synchronized (stats) {
20440                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20441                                uptimeSince, cputimeUsed);
20442                    }
20443                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20444                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20445                } else {
20446                    app.lastWakeTime = wtime;
20447                    app.lastCpuTime = app.curCpuTime;
20448                }
20449            }
20450        }
20451    }
20452
20453    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20454            long nowElapsed) {
20455        boolean success = true;
20456
20457        if (app.curRawAdj != app.setRawAdj) {
20458            app.setRawAdj = app.curRawAdj;
20459        }
20460
20461        int changes = 0;
20462
20463        if (app.curAdj != app.setAdj) {
20464            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20465            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20466                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20467                    + app.adjType);
20468            app.setAdj = app.curAdj;
20469            app.verifiedAdj = ProcessList.INVALID_ADJ;
20470        }
20471
20472        if (app.setSchedGroup != app.curSchedGroup) {
20473            int oldSchedGroup = app.setSchedGroup;
20474            app.setSchedGroup = app.curSchedGroup;
20475            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20476                    "Setting sched group of " + app.processName
20477                    + " to " + app.curSchedGroup);
20478            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20479                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20480                app.kill(app.waitingToKill, true);
20481                success = false;
20482            } else {
20483                int processGroup;
20484                switch (app.curSchedGroup) {
20485                    case ProcessList.SCHED_GROUP_BACKGROUND:
20486                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20487                        break;
20488                    case ProcessList.SCHED_GROUP_TOP_APP:
20489                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20490                        processGroup = Process.THREAD_GROUP_TOP_APP;
20491                        break;
20492                    default:
20493                        processGroup = Process.THREAD_GROUP_DEFAULT;
20494                        break;
20495                }
20496                long oldId = Binder.clearCallingIdentity();
20497                try {
20498                    Process.setProcessGroup(app.pid, processGroup);
20499                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20500                        // do nothing if we already switched to RT
20501                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20502                            // Switch VR thread for app to SCHED_FIFO
20503                            if (mInVrMode && app.vrThreadTid != 0) {
20504                                try {
20505                                    Process.setThreadScheduler(app.vrThreadTid,
20506                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20507                                } catch (IllegalArgumentException e) {
20508                                    // thread died, ignore
20509                                }
20510                            }
20511                            if (mUseFifoUiScheduling) {
20512                                // Switch UI pipeline for app to SCHED_FIFO
20513                                app.savedPriority = Process.getThreadPriority(app.pid);
20514                                try {
20515                                    Process.setThreadScheduler(app.pid,
20516                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20517                                } catch (IllegalArgumentException e) {
20518                                    // thread died, ignore
20519                                }
20520                                if (app.renderThreadTid != 0) {
20521                                    try {
20522                                        Process.setThreadScheduler(app.renderThreadTid,
20523                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20524                                    } catch (IllegalArgumentException e) {
20525                                        // thread died, ignore
20526                                    }
20527                                    if (DEBUG_OOM_ADJ) {
20528                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20529                                            app.renderThreadTid + ") to FIFO");
20530                                    }
20531                                } else {
20532                                    if (DEBUG_OOM_ADJ) {
20533                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20534                                    }
20535                                }
20536                            } else {
20537                                // Boost priority for top app UI and render threads
20538                                Process.setThreadPriority(app.pid, -10);
20539                                if (app.renderThreadTid != 0) {
20540                                    try {
20541                                        Process.setThreadPriority(app.renderThreadTid, -10);
20542                                    } catch (IllegalArgumentException e) {
20543                                        // thread died, ignore
20544                                    }
20545                                }
20546                            }
20547                        }
20548                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20549                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20550                        // Reset VR thread to SCHED_OTHER
20551                        // Safe to do even if we're not in VR mode
20552                        if (app.vrThreadTid != 0) {
20553                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20554                        }
20555                        if (mUseFifoUiScheduling) {
20556                            // Reset UI pipeline to SCHED_OTHER
20557                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20558                            Process.setThreadPriority(app.pid, app.savedPriority);
20559                            if (app.renderThreadTid != 0) {
20560                                Process.setThreadScheduler(app.renderThreadTid,
20561                                    Process.SCHED_OTHER, 0);
20562                                Process.setThreadPriority(app.renderThreadTid, -4);
20563                            }
20564                        } else {
20565                            // Reset priority for top app UI and render threads
20566                            Process.setThreadPriority(app.pid, 0);
20567                            if (app.renderThreadTid != 0) {
20568                                Process.setThreadPriority(app.renderThreadTid, 0);
20569                            }
20570                        }
20571                    }
20572                } catch (Exception e) {
20573                    Slog.w(TAG, "Failed setting process group of " + app.pid
20574                            + " to " + app.curSchedGroup);
20575                    e.printStackTrace();
20576                } finally {
20577                    Binder.restoreCallingIdentity(oldId);
20578                }
20579            }
20580        }
20581        if (app.repForegroundActivities != app.foregroundActivities) {
20582            app.repForegroundActivities = app.foregroundActivities;
20583            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20584        }
20585        if (app.repProcState != app.curProcState) {
20586            app.repProcState = app.curProcState;
20587            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20588            if (app.thread != null) {
20589                try {
20590                    if (false) {
20591                        //RuntimeException h = new RuntimeException("here");
20592                        Slog.i(TAG, "Sending new process state " + app.repProcState
20593                                + " to " + app /*, h*/);
20594                    }
20595                    app.thread.setProcessState(app.repProcState);
20596                } catch (RemoteException e) {
20597                }
20598            }
20599        }
20600        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20601                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20602            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20603                // Experimental code to more aggressively collect pss while
20604                // running test...  the problem is that this tends to collect
20605                // the data right when a process is transitioning between process
20606                // states, which well tend to give noisy data.
20607                long start = SystemClock.uptimeMillis();
20608                long pss = Debug.getPss(app.pid, mTmpLong, null);
20609                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20610                mPendingPssProcesses.remove(app);
20611                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20612                        + " to " + app.curProcState + ": "
20613                        + (SystemClock.uptimeMillis()-start) + "ms");
20614            }
20615            app.lastStateTime = now;
20616            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20617                    mTestPssMode, isSleepingLocked(), now);
20618            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20619                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20620                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20621                    + (app.nextPssTime-now) + ": " + app);
20622        } else {
20623            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20624                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20625                    mTestPssMode)))) {
20626                requestPssLocked(app, app.setProcState);
20627                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20628                        mTestPssMode, isSleepingLocked(), now);
20629            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20630                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20631        }
20632        if (app.setProcState != app.curProcState) {
20633            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20634                    "Proc state change of " + app.processName
20635                            + " to " + app.curProcState);
20636            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20637            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20638            if (setImportant && !curImportant) {
20639                // This app is no longer something we consider important enough to allow to
20640                // use arbitrary amounts of battery power.  Note
20641                // its current wake lock time to later know to kill it if
20642                // it is not behaving well.
20643                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20644                synchronized (stats) {
20645                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20646                            app.pid, nowElapsed);
20647                }
20648                app.lastCpuTime = app.curCpuTime;
20649
20650            }
20651            // Inform UsageStats of important process state change
20652            // Must be called before updating setProcState
20653            maybeUpdateUsageStatsLocked(app, nowElapsed);
20654
20655            app.setProcState = app.curProcState;
20656            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20657                app.notCachedSinceIdle = false;
20658            }
20659            if (!doingAll) {
20660                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20661            } else {
20662                app.procStateChanged = true;
20663            }
20664        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20665                > USAGE_STATS_INTERACTION_INTERVAL) {
20666            // For apps that sit around for a long time in the interactive state, we need
20667            // to report this at least once a day so they don't go idle.
20668            maybeUpdateUsageStatsLocked(app, nowElapsed);
20669        }
20670
20671        if (changes != 0) {
20672            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20673                    "Changes in " + app + ": " + changes);
20674            int i = mPendingProcessChanges.size()-1;
20675            ProcessChangeItem item = null;
20676            while (i >= 0) {
20677                item = mPendingProcessChanges.get(i);
20678                if (item.pid == app.pid) {
20679                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20680                            "Re-using existing item: " + item);
20681                    break;
20682                }
20683                i--;
20684            }
20685            if (i < 0) {
20686                // No existing item in pending changes; need a new one.
20687                final int NA = mAvailProcessChanges.size();
20688                if (NA > 0) {
20689                    item = mAvailProcessChanges.remove(NA-1);
20690                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20691                            "Retrieving available item: " + item);
20692                } else {
20693                    item = new ProcessChangeItem();
20694                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20695                            "Allocating new item: " + item);
20696                }
20697                item.changes = 0;
20698                item.pid = app.pid;
20699                item.uid = app.info.uid;
20700                if (mPendingProcessChanges.size() == 0) {
20701                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20702                            "*** Enqueueing dispatch processes changed!");
20703                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20704                }
20705                mPendingProcessChanges.add(item);
20706            }
20707            item.changes |= changes;
20708            item.processState = app.repProcState;
20709            item.foregroundActivities = app.repForegroundActivities;
20710            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20711                    "Item " + Integer.toHexString(System.identityHashCode(item))
20712                    + " " + app.toShortString() + ": changes=" + item.changes
20713                    + " procState=" + item.processState
20714                    + " foreground=" + item.foregroundActivities
20715                    + " type=" + app.adjType + " source=" + app.adjSource
20716                    + " target=" + app.adjTarget);
20717        }
20718
20719        return success;
20720    }
20721
20722    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20723        final UidRecord.ChangeItem pendingChange;
20724        if (uidRec == null || uidRec.pendingChange == null) {
20725            if (mPendingUidChanges.size() == 0) {
20726                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20727                        "*** Enqueueing dispatch uid changed!");
20728                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20729            }
20730            final int NA = mAvailUidChanges.size();
20731            if (NA > 0) {
20732                pendingChange = mAvailUidChanges.remove(NA-1);
20733                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20734                        "Retrieving available item: " + pendingChange);
20735            } else {
20736                pendingChange = new UidRecord.ChangeItem();
20737                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20738                        "Allocating new item: " + pendingChange);
20739            }
20740            if (uidRec != null) {
20741                uidRec.pendingChange = pendingChange;
20742                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20743                    // If this uid is going away, and we haven't yet reported it is gone,
20744                    // then do so now.
20745                    change = UidRecord.CHANGE_GONE_IDLE;
20746                }
20747            } else if (uid < 0) {
20748                throw new IllegalArgumentException("No UidRecord or uid");
20749            }
20750            pendingChange.uidRecord = uidRec;
20751            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20752            mPendingUidChanges.add(pendingChange);
20753        } else {
20754            pendingChange = uidRec.pendingChange;
20755            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20756                change = UidRecord.CHANGE_GONE_IDLE;
20757            }
20758        }
20759        pendingChange.change = change;
20760        pendingChange.processState = uidRec != null
20761                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20762
20763        // Directly update the power manager, since we sit on top of it and it is critical
20764        // it be kept in sync (so wake locks will be held as soon as appropriate).
20765        if (mLocalPowerManager != null) {
20766            switch (change) {
20767                case UidRecord.CHANGE_GONE:
20768                case UidRecord.CHANGE_GONE_IDLE:
20769                    mLocalPowerManager.uidGone(pendingChange.uid);
20770                    break;
20771                case UidRecord.CHANGE_IDLE:
20772                    mLocalPowerManager.uidIdle(pendingChange.uid);
20773                    break;
20774                case UidRecord.CHANGE_ACTIVE:
20775                    mLocalPowerManager.uidActive(pendingChange.uid);
20776                    break;
20777                default:
20778                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
20779                            pendingChange.processState);
20780                    break;
20781            }
20782        }
20783    }
20784
20785    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20786            String authority) {
20787        if (app == null) return;
20788        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20789            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20790            if (userState == null) return;
20791            final long now = SystemClock.elapsedRealtime();
20792            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20793            if (lastReported == null || lastReported < now - 60 * 1000L) {
20794                if (mSystemReady) {
20795                    // Cannot touch the user stats if not system ready
20796                    mUsageStatsService.reportContentProviderUsage(
20797                            authority, providerPkgName, app.userId);
20798                }
20799                userState.mProviderLastReportedFg.put(authority, now);
20800            }
20801        }
20802    }
20803
20804    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20805        if (DEBUG_USAGE_STATS) {
20806            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20807                    + "] state changes: old = " + app.setProcState + ", new = "
20808                    + app.curProcState);
20809        }
20810        if (mUsageStatsService == null) {
20811            return;
20812        }
20813        boolean isInteraction;
20814        // To avoid some abuse patterns, we are going to be careful about what we consider
20815        // to be an app interaction.  Being the top activity doesn't count while the display
20816        // is sleeping, nor do short foreground services.
20817        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20818            isInteraction = true;
20819            app.fgInteractionTime = 0;
20820        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20821            if (app.fgInteractionTime == 0) {
20822                app.fgInteractionTime = nowElapsed;
20823                isInteraction = false;
20824            } else {
20825                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20826            }
20827        } else {
20828            // If the app was being forced to the foreground, by say a Toast, then
20829            // no need to treat it as an interaction
20830            isInteraction = app.forcingToForeground == null
20831                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20832            app.fgInteractionTime = 0;
20833        }
20834        if (isInteraction && (!app.reportedInteraction
20835                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20836            app.interactionEventTime = nowElapsed;
20837            String[] packages = app.getPackageList();
20838            if (packages != null) {
20839                for (int i = 0; i < packages.length; i++) {
20840                    mUsageStatsService.reportEvent(packages[i], app.userId,
20841                            UsageEvents.Event.SYSTEM_INTERACTION);
20842                }
20843            }
20844        }
20845        app.reportedInteraction = isInteraction;
20846        if (!isInteraction) {
20847            app.interactionEventTime = 0;
20848        }
20849    }
20850
20851    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20852        if (proc.thread != null) {
20853            if (proc.baseProcessTracker != null) {
20854                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20855            }
20856        }
20857    }
20858
20859    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20860            ProcessRecord TOP_APP, boolean doingAll, long now) {
20861        if (app.thread == null) {
20862            return false;
20863        }
20864
20865        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20866
20867        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20868    }
20869
20870    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20871            boolean oomAdj) {
20872        if (isForeground != proc.foregroundServices) {
20873            proc.foregroundServices = isForeground;
20874            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20875                    proc.info.uid);
20876            if (isForeground) {
20877                if (curProcs == null) {
20878                    curProcs = new ArrayList<ProcessRecord>();
20879                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20880                }
20881                if (!curProcs.contains(proc)) {
20882                    curProcs.add(proc);
20883                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20884                            proc.info.packageName, proc.info.uid);
20885                }
20886            } else {
20887                if (curProcs != null) {
20888                    if (curProcs.remove(proc)) {
20889                        mBatteryStatsService.noteEvent(
20890                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20891                                proc.info.packageName, proc.info.uid);
20892                        if (curProcs.size() <= 0) {
20893                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20894                        }
20895                    }
20896                }
20897            }
20898            if (oomAdj) {
20899                updateOomAdjLocked();
20900            }
20901        }
20902    }
20903
20904    private final ActivityRecord resumedAppLocked() {
20905        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
20906        String pkg;
20907        int uid;
20908        if (act != null) {
20909            pkg = act.packageName;
20910            uid = act.info.applicationInfo.uid;
20911        } else {
20912            pkg = null;
20913            uid = -1;
20914        }
20915        // Has the UID or resumed package name changed?
20916        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20917                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20918            if (mCurResumedPackage != null) {
20919                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20920                        mCurResumedPackage, mCurResumedUid);
20921            }
20922            mCurResumedPackage = pkg;
20923            mCurResumedUid = uid;
20924            if (mCurResumedPackage != null) {
20925                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20926                        mCurResumedPackage, mCurResumedUid);
20927            }
20928        }
20929        return act;
20930    }
20931
20932    final boolean updateOomAdjLocked(ProcessRecord app) {
20933        final ActivityRecord TOP_ACT = resumedAppLocked();
20934        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20935        final boolean wasCached = app.cached;
20936
20937        mAdjSeq++;
20938
20939        // This is the desired cached adjusment we want to tell it to use.
20940        // If our app is currently cached, we know it, and that is it.  Otherwise,
20941        // we don't know it yet, and it needs to now be cached we will then
20942        // need to do a complete oom adj.
20943        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20944                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20945        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20946                SystemClock.uptimeMillis());
20947        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20948            // Changed to/from cached state, so apps after it in the LRU
20949            // list may also be changed.
20950            updateOomAdjLocked();
20951        }
20952        return success;
20953    }
20954
20955    final void updateOomAdjLocked() {
20956        final ActivityRecord TOP_ACT = resumedAppLocked();
20957        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20958        final long now = SystemClock.uptimeMillis();
20959        final long nowElapsed = SystemClock.elapsedRealtime();
20960        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20961        final int N = mLruProcesses.size();
20962
20963        if (false) {
20964            RuntimeException e = new RuntimeException();
20965            e.fillInStackTrace();
20966            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20967        }
20968
20969        // Reset state in all uid records.
20970        for (int i=mActiveUids.size()-1; i>=0; i--) {
20971            final UidRecord uidRec = mActiveUids.valueAt(i);
20972            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20973                    "Starting update of " + uidRec);
20974            uidRec.reset();
20975        }
20976
20977        mStackSupervisor.rankTaskLayersIfNeeded();
20978
20979        mAdjSeq++;
20980        mNewNumServiceProcs = 0;
20981        mNewNumAServiceProcs = 0;
20982
20983        final int emptyProcessLimit;
20984        final int cachedProcessLimit;
20985        if (mProcessLimit <= 0) {
20986            emptyProcessLimit = cachedProcessLimit = 0;
20987        } else if (mProcessLimit == 1) {
20988            emptyProcessLimit = 1;
20989            cachedProcessLimit = 0;
20990        } else {
20991            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20992            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20993        }
20994
20995        // Let's determine how many processes we have running vs.
20996        // how many slots we have for background processes; we may want
20997        // to put multiple processes in a slot of there are enough of
20998        // them.
20999        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21000                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21001        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21002        if (numEmptyProcs > cachedProcessLimit) {
21003            // If there are more empty processes than our limit on cached
21004            // processes, then use the cached process limit for the factor.
21005            // This ensures that the really old empty processes get pushed
21006            // down to the bottom, so if we are running low on memory we will
21007            // have a better chance at keeping around more cached processes
21008            // instead of a gazillion empty processes.
21009            numEmptyProcs = cachedProcessLimit;
21010        }
21011        int emptyFactor = numEmptyProcs/numSlots;
21012        if (emptyFactor < 1) emptyFactor = 1;
21013        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21014        if (cachedFactor < 1) cachedFactor = 1;
21015        int stepCached = 0;
21016        int stepEmpty = 0;
21017        int numCached = 0;
21018        int numEmpty = 0;
21019        int numTrimming = 0;
21020
21021        mNumNonCachedProcs = 0;
21022        mNumCachedHiddenProcs = 0;
21023
21024        // First update the OOM adjustment for each of the
21025        // application processes based on their current state.
21026        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21027        int nextCachedAdj = curCachedAdj+1;
21028        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21029        int nextEmptyAdj = curEmptyAdj+2;
21030        for (int i=N-1; i>=0; i--) {
21031            ProcessRecord app = mLruProcesses.get(i);
21032            if (!app.killedByAm && app.thread != null) {
21033                app.procStateChanged = false;
21034                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21035
21036                // If we haven't yet assigned the final cached adj
21037                // to the process, do that now.
21038                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21039                    switch (app.curProcState) {
21040                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21041                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21042                            // This process is a cached process holding activities...
21043                            // assign it the next cached value for that type, and then
21044                            // step that cached level.
21045                            app.curRawAdj = curCachedAdj;
21046                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21047                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21048                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21049                                    + ")");
21050                            if (curCachedAdj != nextCachedAdj) {
21051                                stepCached++;
21052                                if (stepCached >= cachedFactor) {
21053                                    stepCached = 0;
21054                                    curCachedAdj = nextCachedAdj;
21055                                    nextCachedAdj += 2;
21056                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21057                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21058                                    }
21059                                }
21060                            }
21061                            break;
21062                        default:
21063                            // For everything else, assign next empty cached process
21064                            // level and bump that up.  Note that this means that
21065                            // long-running services that have dropped down to the
21066                            // cached level will be treated as empty (since their process
21067                            // state is still as a service), which is what we want.
21068                            app.curRawAdj = curEmptyAdj;
21069                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21070                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21071                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21072                                    + ")");
21073                            if (curEmptyAdj != nextEmptyAdj) {
21074                                stepEmpty++;
21075                                if (stepEmpty >= emptyFactor) {
21076                                    stepEmpty = 0;
21077                                    curEmptyAdj = nextEmptyAdj;
21078                                    nextEmptyAdj += 2;
21079                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21080                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21081                                    }
21082                                }
21083                            }
21084                            break;
21085                    }
21086                }
21087
21088                applyOomAdjLocked(app, true, now, nowElapsed);
21089
21090                // Count the number of process types.
21091                switch (app.curProcState) {
21092                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21093                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21094                        mNumCachedHiddenProcs++;
21095                        numCached++;
21096                        if (numCached > cachedProcessLimit) {
21097                            app.kill("cached #" + numCached, true);
21098                        }
21099                        break;
21100                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21101                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21102                                && app.lastActivityTime < oldTime) {
21103                            app.kill("empty for "
21104                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21105                                    / 1000) + "s", true);
21106                        } else {
21107                            numEmpty++;
21108                            if (numEmpty > emptyProcessLimit) {
21109                                app.kill("empty #" + numEmpty, true);
21110                            }
21111                        }
21112                        break;
21113                    default:
21114                        mNumNonCachedProcs++;
21115                        break;
21116                }
21117
21118                if (app.isolated && app.services.size() <= 0) {
21119                    // If this is an isolated process, and there are no
21120                    // services running in it, then the process is no longer
21121                    // needed.  We agressively kill these because we can by
21122                    // definition not re-use the same process again, and it is
21123                    // good to avoid having whatever code was running in them
21124                    // left sitting around after no longer needed.
21125                    app.kill("isolated not needed", true);
21126                } else {
21127                    // Keeping this process, update its uid.
21128                    final UidRecord uidRec = app.uidRecord;
21129                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21130                        uidRec.curProcState = app.curProcState;
21131                    }
21132                }
21133
21134                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21135                        && !app.killedByAm) {
21136                    numTrimming++;
21137                }
21138            }
21139        }
21140
21141        mNumServiceProcs = mNewNumServiceProcs;
21142
21143        // Now determine the memory trimming level of background processes.
21144        // Unfortunately we need to start at the back of the list to do this
21145        // properly.  We only do this if the number of background apps we
21146        // are managing to keep around is less than half the maximum we desire;
21147        // if we are keeping a good number around, we'll let them use whatever
21148        // memory they want.
21149        final int numCachedAndEmpty = numCached + numEmpty;
21150        int memFactor;
21151        if (numCached <= ProcessList.TRIM_CACHED_APPS
21152                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21153            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21154                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21155            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21156                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21157            } else {
21158                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21159            }
21160        } else {
21161            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21162        }
21163        // We always allow the memory level to go up (better).  We only allow it to go
21164        // down if we are in a state where that is allowed, *and* the total number of processes
21165        // has gone down since last time.
21166        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21167                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21168                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21169        if (memFactor > mLastMemoryLevel) {
21170            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21171                memFactor = mLastMemoryLevel;
21172                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21173            }
21174        }
21175        if (memFactor != mLastMemoryLevel) {
21176            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21177        }
21178        mLastMemoryLevel = memFactor;
21179        mLastNumProcesses = mLruProcesses.size();
21180        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21181        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21182        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21183            if (mLowRamStartTime == 0) {
21184                mLowRamStartTime = now;
21185            }
21186            int step = 0;
21187            int fgTrimLevel;
21188            switch (memFactor) {
21189                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21190                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21191                    break;
21192                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21193                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21194                    break;
21195                default:
21196                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21197                    break;
21198            }
21199            int factor = numTrimming/3;
21200            int minFactor = 2;
21201            if (mHomeProcess != null) minFactor++;
21202            if (mPreviousProcess != null) minFactor++;
21203            if (factor < minFactor) factor = minFactor;
21204            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21205            for (int i=N-1; i>=0; i--) {
21206                ProcessRecord app = mLruProcesses.get(i);
21207                if (allChanged || app.procStateChanged) {
21208                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21209                    app.procStateChanged = false;
21210                }
21211                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21212                        && !app.killedByAm) {
21213                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21214                        try {
21215                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21216                                    "Trimming memory of " + app.processName + " to " + curLevel);
21217                            app.thread.scheduleTrimMemory(curLevel);
21218                        } catch (RemoteException e) {
21219                        }
21220                        if (false) {
21221                            // For now we won't do this; our memory trimming seems
21222                            // to be good enough at this point that destroying
21223                            // activities causes more harm than good.
21224                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21225                                    && app != mHomeProcess && app != mPreviousProcess) {
21226                                // Need to do this on its own message because the stack may not
21227                                // be in a consistent state at this point.
21228                                // For these apps we will also finish their activities
21229                                // to help them free memory.
21230                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21231                            }
21232                        }
21233                    }
21234                    app.trimMemoryLevel = curLevel;
21235                    step++;
21236                    if (step >= factor) {
21237                        step = 0;
21238                        switch (curLevel) {
21239                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21240                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21241                                break;
21242                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21243                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21244                                break;
21245                        }
21246                    }
21247                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21248                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21249                            && app.thread != null) {
21250                        try {
21251                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21252                                    "Trimming memory of heavy-weight " + app.processName
21253                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21254                            app.thread.scheduleTrimMemory(
21255                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21256                        } catch (RemoteException e) {
21257                        }
21258                    }
21259                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21260                } else {
21261                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21262                            || app.systemNoUi) && app.pendingUiClean) {
21263                        // If this application is now in the background and it
21264                        // had done UI, then give it the special trim level to
21265                        // have it free UI resources.
21266                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21267                        if (app.trimMemoryLevel < level && app.thread != null) {
21268                            try {
21269                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21270                                        "Trimming memory of bg-ui " + app.processName
21271                                        + " to " + level);
21272                                app.thread.scheduleTrimMemory(level);
21273                            } catch (RemoteException e) {
21274                            }
21275                        }
21276                        app.pendingUiClean = false;
21277                    }
21278                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21279                        try {
21280                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21281                                    "Trimming memory of fg " + app.processName
21282                                    + " to " + fgTrimLevel);
21283                            app.thread.scheduleTrimMemory(fgTrimLevel);
21284                        } catch (RemoteException e) {
21285                        }
21286                    }
21287                    app.trimMemoryLevel = fgTrimLevel;
21288                }
21289            }
21290        } else {
21291            if (mLowRamStartTime != 0) {
21292                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21293                mLowRamStartTime = 0;
21294            }
21295            for (int i=N-1; i>=0; i--) {
21296                ProcessRecord app = mLruProcesses.get(i);
21297                if (allChanged || app.procStateChanged) {
21298                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21299                    app.procStateChanged = false;
21300                }
21301                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21302                        || app.systemNoUi) && app.pendingUiClean) {
21303                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21304                            && app.thread != null) {
21305                        try {
21306                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21307                                    "Trimming memory of ui hidden " + app.processName
21308                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21309                            app.thread.scheduleTrimMemory(
21310                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21311                        } catch (RemoteException e) {
21312                        }
21313                    }
21314                    app.pendingUiClean = false;
21315                }
21316                app.trimMemoryLevel = 0;
21317            }
21318        }
21319
21320        if (mAlwaysFinishActivities) {
21321            // Need to do this on its own message because the stack may not
21322            // be in a consistent state at this point.
21323            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21324        }
21325
21326        if (allChanged) {
21327            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21328        }
21329
21330        // Update from any uid changes.
21331        if (mLocalPowerManager != null) {
21332            mLocalPowerManager.startUidChanges();
21333        }
21334        for (int i=mActiveUids.size()-1; i>=0; i--) {
21335            final UidRecord uidRec = mActiveUids.valueAt(i);
21336            int uidChange = UidRecord.CHANGE_PROCSTATE;
21337            if (uidRec.setProcState != uidRec.curProcState) {
21338                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21339                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21340                        + " to " + uidRec.curProcState);
21341                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21342                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21343                        uidRec.lastBackgroundTime = nowElapsed;
21344                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21345                            // Note: the background settle time is in elapsed realtime, while
21346                            // the handler time base is uptime.  All this means is that we may
21347                            // stop background uids later than we had intended, but that only
21348                            // happens because the device was sleeping so we are okay anyway.
21349                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21350                        }
21351                    }
21352                } else {
21353                    if (uidRec.idle) {
21354                        uidChange = UidRecord.CHANGE_ACTIVE;
21355                        uidRec.idle = false;
21356                    }
21357                    uidRec.lastBackgroundTime = 0;
21358                }
21359                uidRec.setProcState = uidRec.curProcState;
21360                enqueueUidChangeLocked(uidRec, -1, uidChange);
21361                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21362            }
21363        }
21364        if (mLocalPowerManager != null) {
21365            mLocalPowerManager.finishUidChanges();
21366        }
21367
21368        if (mProcessStats.shouldWriteNowLocked(now)) {
21369            mHandler.post(new Runnable() {
21370                @Override public void run() {
21371                    synchronized (ActivityManagerService.this) {
21372                        mProcessStats.writeStateAsyncLocked();
21373                    }
21374                }
21375            });
21376        }
21377
21378        if (DEBUG_OOM_ADJ) {
21379            final long duration = SystemClock.uptimeMillis() - now;
21380            if (false) {
21381                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21382                        new RuntimeException("here").fillInStackTrace());
21383            } else {
21384                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21385            }
21386        }
21387    }
21388
21389    final void idleUids() {
21390        synchronized (this) {
21391            final int N = mActiveUids.size();
21392            if (N <= 0) {
21393                return;
21394            }
21395            final long nowElapsed = SystemClock.elapsedRealtime();
21396            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21397            long nextTime = 0;
21398            if (mLocalPowerManager != null) {
21399                mLocalPowerManager.startUidChanges();
21400            }
21401            for (int i=N-1; i>=0; i--) {
21402                final UidRecord uidRec = mActiveUids.valueAt(i);
21403                final long bgTime = uidRec.lastBackgroundTime;
21404                if (bgTime > 0 && !uidRec.idle) {
21405                    if (bgTime <= maxBgTime) {
21406                        uidRec.idle = true;
21407                        doStopUidLocked(uidRec.uid, uidRec);
21408                    } else {
21409                        if (nextTime == 0 || nextTime > bgTime) {
21410                            nextTime = bgTime;
21411                        }
21412                    }
21413                }
21414            }
21415            if (mLocalPowerManager != null) {
21416                mLocalPowerManager.finishUidChanges();
21417            }
21418            if (nextTime > 0) {
21419                mHandler.removeMessages(IDLE_UIDS_MSG);
21420                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21421                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21422            }
21423        }
21424    }
21425
21426    final void runInBackgroundDisabled(int uid) {
21427        synchronized (this) {
21428            UidRecord uidRec = mActiveUids.get(uid);
21429            if (uidRec != null) {
21430                // This uid is actually running...  should it be considered background now?
21431                if (uidRec.idle) {
21432                    doStopUidLocked(uidRec.uid, uidRec);
21433                }
21434            } else {
21435                // This uid isn't actually running...  still send a report about it being "stopped".
21436                doStopUidLocked(uid, null);
21437            }
21438        }
21439    }
21440
21441    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21442        mServices.stopInBackgroundLocked(uid);
21443        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21444    }
21445
21446    final void trimApplications() {
21447        synchronized (this) {
21448            int i;
21449
21450            // First remove any unused application processes whose package
21451            // has been removed.
21452            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21453                final ProcessRecord app = mRemovedProcesses.get(i);
21454                if (app.activities.size() == 0
21455                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21456                    Slog.i(
21457                        TAG, "Exiting empty application process "
21458                        + app.toShortString() + " ("
21459                        + (app.thread != null ? app.thread.asBinder() : null)
21460                        + ")\n");
21461                    if (app.pid > 0 && app.pid != MY_PID) {
21462                        app.kill("empty", false);
21463                    } else {
21464                        try {
21465                            app.thread.scheduleExit();
21466                        } catch (Exception e) {
21467                            // Ignore exceptions.
21468                        }
21469                    }
21470                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21471                    mRemovedProcesses.remove(i);
21472
21473                    if (app.persistent) {
21474                        addAppLocked(app.info, false, null /* ABI override */);
21475                    }
21476                }
21477            }
21478
21479            // Now update the oom adj for all processes.
21480            updateOomAdjLocked();
21481        }
21482    }
21483
21484    /** This method sends the specified signal to each of the persistent apps */
21485    public void signalPersistentProcesses(int sig) throws RemoteException {
21486        if (sig != Process.SIGNAL_USR1) {
21487            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21488        }
21489
21490        synchronized (this) {
21491            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21492                    != PackageManager.PERMISSION_GRANTED) {
21493                throw new SecurityException("Requires permission "
21494                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21495            }
21496
21497            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21498                ProcessRecord r = mLruProcesses.get(i);
21499                if (r.thread != null && r.persistent) {
21500                    Process.sendSignal(r.pid, sig);
21501                }
21502            }
21503        }
21504    }
21505
21506    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21507        if (proc == null || proc == mProfileProc) {
21508            proc = mProfileProc;
21509            profileType = mProfileType;
21510            clearProfilerLocked();
21511        }
21512        if (proc == null) {
21513            return;
21514        }
21515        try {
21516            proc.thread.profilerControl(false, null, profileType);
21517        } catch (RemoteException e) {
21518            throw new IllegalStateException("Process disappeared");
21519        }
21520    }
21521
21522    private void clearProfilerLocked() {
21523        if (mProfileFd != null) {
21524            try {
21525                mProfileFd.close();
21526            } catch (IOException e) {
21527            }
21528        }
21529        mProfileApp = null;
21530        mProfileProc = null;
21531        mProfileFile = null;
21532        mProfileType = 0;
21533        mAutoStopProfiler = false;
21534        mSamplingInterval = 0;
21535    }
21536
21537    public boolean profileControl(String process, int userId, boolean start,
21538            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21539
21540        try {
21541            synchronized (this) {
21542                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21543                // its own permission.
21544                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21545                        != PackageManager.PERMISSION_GRANTED) {
21546                    throw new SecurityException("Requires permission "
21547                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21548                }
21549
21550                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21551                    throw new IllegalArgumentException("null profile info or fd");
21552                }
21553
21554                ProcessRecord proc = null;
21555                if (process != null) {
21556                    proc = findProcessLocked(process, userId, "profileControl");
21557                }
21558
21559                if (start && (proc == null || proc.thread == null)) {
21560                    throw new IllegalArgumentException("Unknown process: " + process);
21561                }
21562
21563                if (start) {
21564                    stopProfilerLocked(null, 0);
21565                    setProfileApp(proc.info, proc.processName, profilerInfo);
21566                    mProfileProc = proc;
21567                    mProfileType = profileType;
21568                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21569                    try {
21570                        fd = fd.dup();
21571                    } catch (IOException e) {
21572                        fd = null;
21573                    }
21574                    profilerInfo.profileFd = fd;
21575                    proc.thread.profilerControl(start, profilerInfo, profileType);
21576                    fd = null;
21577                    mProfileFd = null;
21578                } else {
21579                    stopProfilerLocked(proc, profileType);
21580                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21581                        try {
21582                            profilerInfo.profileFd.close();
21583                        } catch (IOException e) {
21584                        }
21585                    }
21586                }
21587
21588                return true;
21589            }
21590        } catch (RemoteException e) {
21591            throw new IllegalStateException("Process disappeared");
21592        } finally {
21593            if (profilerInfo != null && profilerInfo.profileFd != null) {
21594                try {
21595                    profilerInfo.profileFd.close();
21596                } catch (IOException e) {
21597                }
21598            }
21599        }
21600    }
21601
21602    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21603        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21604                userId, true, ALLOW_FULL_ONLY, callName, null);
21605        ProcessRecord proc = null;
21606        try {
21607            int pid = Integer.parseInt(process);
21608            synchronized (mPidsSelfLocked) {
21609                proc = mPidsSelfLocked.get(pid);
21610            }
21611        } catch (NumberFormatException e) {
21612        }
21613
21614        if (proc == null) {
21615            ArrayMap<String, SparseArray<ProcessRecord>> all
21616                    = mProcessNames.getMap();
21617            SparseArray<ProcessRecord> procs = all.get(process);
21618            if (procs != null && procs.size() > 0) {
21619                proc = procs.valueAt(0);
21620                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21621                    for (int i=1; i<procs.size(); i++) {
21622                        ProcessRecord thisProc = procs.valueAt(i);
21623                        if (thisProc.userId == userId) {
21624                            proc = thisProc;
21625                            break;
21626                        }
21627                    }
21628                }
21629            }
21630        }
21631
21632        return proc;
21633    }
21634
21635    public boolean dumpHeap(String process, int userId, boolean managed,
21636            String path, ParcelFileDescriptor fd) throws RemoteException {
21637
21638        try {
21639            synchronized (this) {
21640                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21641                // its own permission (same as profileControl).
21642                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21643                        != PackageManager.PERMISSION_GRANTED) {
21644                    throw new SecurityException("Requires permission "
21645                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21646                }
21647
21648                if (fd == null) {
21649                    throw new IllegalArgumentException("null fd");
21650                }
21651
21652                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21653                if (proc == null || proc.thread == null) {
21654                    throw new IllegalArgumentException("Unknown process: " + process);
21655                }
21656
21657                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21658                if (!isDebuggable) {
21659                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21660                        throw new SecurityException("Process not debuggable: " + proc);
21661                    }
21662                }
21663
21664                proc.thread.dumpHeap(managed, path, fd);
21665                fd = null;
21666                return true;
21667            }
21668        } catch (RemoteException e) {
21669            throw new IllegalStateException("Process disappeared");
21670        } finally {
21671            if (fd != null) {
21672                try {
21673                    fd.close();
21674                } catch (IOException e) {
21675                }
21676            }
21677        }
21678    }
21679
21680    @Override
21681    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21682            String reportPackage) {
21683        if (processName != null) {
21684            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21685                    "setDumpHeapDebugLimit()");
21686        } else {
21687            synchronized (mPidsSelfLocked) {
21688                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21689                if (proc == null) {
21690                    throw new SecurityException("No process found for calling pid "
21691                            + Binder.getCallingPid());
21692                }
21693                if (!Build.IS_DEBUGGABLE
21694                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21695                    throw new SecurityException("Not running a debuggable build");
21696                }
21697                processName = proc.processName;
21698                uid = proc.uid;
21699                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21700                    throw new SecurityException("Package " + reportPackage + " is not running in "
21701                            + proc);
21702                }
21703            }
21704        }
21705        synchronized (this) {
21706            if (maxMemSize > 0) {
21707                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21708            } else {
21709                if (uid != 0) {
21710                    mMemWatchProcesses.remove(processName, uid);
21711                } else {
21712                    mMemWatchProcesses.getMap().remove(processName);
21713                }
21714            }
21715        }
21716    }
21717
21718    @Override
21719    public void dumpHeapFinished(String path) {
21720        synchronized (this) {
21721            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21722                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21723                        + " does not match last pid " + mMemWatchDumpPid);
21724                return;
21725            }
21726            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21727                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21728                        + " does not match last path " + mMemWatchDumpFile);
21729                return;
21730            }
21731            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21732            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21733        }
21734    }
21735
21736    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21737    public void monitor() {
21738        synchronized (this) { }
21739    }
21740
21741    void onCoreSettingsChange(Bundle settings) {
21742        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21743            ProcessRecord processRecord = mLruProcesses.get(i);
21744            try {
21745                if (processRecord.thread != null) {
21746                    processRecord.thread.setCoreSettings(settings);
21747                }
21748            } catch (RemoteException re) {
21749                /* ignore */
21750            }
21751        }
21752    }
21753
21754    // Multi-user methods
21755
21756    /**
21757     * Start user, if its not already running, but don't bring it to foreground.
21758     */
21759    @Override
21760    public boolean startUserInBackground(final int userId) {
21761        return mUserController.startUser(userId, /* foreground */ false);
21762    }
21763
21764    @Override
21765    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21766        return mUserController.unlockUser(userId, token, secret, listener);
21767    }
21768
21769    @Override
21770    public boolean switchUser(final int targetUserId) {
21771        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21772        int currentUserId;
21773        UserInfo targetUserInfo;
21774        synchronized (this) {
21775            currentUserId = mUserController.getCurrentUserIdLocked();
21776            targetUserInfo = mUserController.getUserInfo(targetUserId);
21777            if (targetUserId == currentUserId) {
21778                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
21779                return true;
21780            }
21781            if (targetUserInfo == null) {
21782                Slog.w(TAG, "No user info for user #" + targetUserId);
21783                return false;
21784            }
21785            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21786                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21787                        + " when device is in demo mode");
21788                return false;
21789            }
21790            if (!targetUserInfo.supportsSwitchTo()) {
21791                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21792                return false;
21793            }
21794            if (targetUserInfo.isManagedProfile()) {
21795                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21796                return false;
21797            }
21798            mUserController.setTargetUserIdLocked(targetUserId);
21799        }
21800        if (mUserController.mUserSwitchUiEnabled) {
21801            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
21802            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21803            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21804            mUiHandler.sendMessage(mHandler.obtainMessage(
21805                    START_USER_SWITCH_UI_MSG, userNames));
21806        } else {
21807            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
21808            mHandler.sendMessage(mHandler.obtainMessage(
21809                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
21810        }
21811        return true;
21812    }
21813
21814    void scheduleStartProfilesLocked() {
21815        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21816            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21817                    DateUtils.SECOND_IN_MILLIS);
21818        }
21819    }
21820
21821    @Override
21822    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21823        return mUserController.stopUser(userId, force, callback);
21824    }
21825
21826    @Override
21827    public UserInfo getCurrentUser() {
21828        return mUserController.getCurrentUser();
21829    }
21830
21831    String getStartedUserState(int userId) {
21832        synchronized (this) {
21833            final UserState userState = mUserController.getStartedUserStateLocked(userId);
21834            return UserState.stateToString(userState.state);
21835        }
21836    }
21837
21838    @Override
21839    public boolean isUserRunning(int userId, int flags) {
21840        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21841                && checkCallingPermission(INTERACT_ACROSS_USERS)
21842                    != PackageManager.PERMISSION_GRANTED) {
21843            String msg = "Permission Denial: isUserRunning() from pid="
21844                    + Binder.getCallingPid()
21845                    + ", uid=" + Binder.getCallingUid()
21846                    + " requires " + INTERACT_ACROSS_USERS;
21847            Slog.w(TAG, msg);
21848            throw new SecurityException(msg);
21849        }
21850        synchronized (this) {
21851            return mUserController.isUserRunningLocked(userId, flags);
21852        }
21853    }
21854
21855    @Override
21856    public int[] getRunningUserIds() {
21857        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21858                != PackageManager.PERMISSION_GRANTED) {
21859            String msg = "Permission Denial: isUserRunning() from pid="
21860                    + Binder.getCallingPid()
21861                    + ", uid=" + Binder.getCallingUid()
21862                    + " requires " + INTERACT_ACROSS_USERS;
21863            Slog.w(TAG, msg);
21864            throw new SecurityException(msg);
21865        }
21866        synchronized (this) {
21867            return mUserController.getStartedUserArrayLocked();
21868        }
21869    }
21870
21871    @Override
21872    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21873        mUserController.registerUserSwitchObserver(observer, name);
21874    }
21875
21876    @Override
21877    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21878        mUserController.unregisterUserSwitchObserver(observer);
21879    }
21880
21881    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21882        if (info == null) return null;
21883        ApplicationInfo newInfo = new ApplicationInfo(info);
21884        newInfo.initForUser(userId);
21885        return newInfo;
21886    }
21887
21888    public boolean isUserStopped(int userId) {
21889        synchronized (this) {
21890            return mUserController.getStartedUserStateLocked(userId) == null;
21891        }
21892    }
21893
21894    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21895        if (aInfo == null
21896                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21897            return aInfo;
21898        }
21899
21900        ActivityInfo info = new ActivityInfo(aInfo);
21901        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21902        return info;
21903    }
21904
21905    private boolean processSanityChecksLocked(ProcessRecord process) {
21906        if (process == null || process.thread == null) {
21907            return false;
21908        }
21909
21910        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21911        if (!isDebuggable) {
21912            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21913                return false;
21914            }
21915        }
21916
21917        return true;
21918    }
21919
21920    public boolean startBinderTracking() throws RemoteException {
21921        synchronized (this) {
21922            mBinderTransactionTrackingEnabled = true;
21923            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21924            // permission (same as profileControl).
21925            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21926                    != PackageManager.PERMISSION_GRANTED) {
21927                throw new SecurityException("Requires permission "
21928                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21929            }
21930
21931            for (int i = 0; i < mLruProcesses.size(); i++) {
21932                ProcessRecord process = mLruProcesses.get(i);
21933                if (!processSanityChecksLocked(process)) {
21934                    continue;
21935                }
21936                try {
21937                    process.thread.startBinderTracking();
21938                } catch (RemoteException e) {
21939                    Log.v(TAG, "Process disappared");
21940                }
21941            }
21942            return true;
21943        }
21944    }
21945
21946    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21947        try {
21948            synchronized (this) {
21949                mBinderTransactionTrackingEnabled = false;
21950                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21951                // permission (same as profileControl).
21952                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21953                        != PackageManager.PERMISSION_GRANTED) {
21954                    throw new SecurityException("Requires permission "
21955                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21956                }
21957
21958                if (fd == null) {
21959                    throw new IllegalArgumentException("null fd");
21960                }
21961
21962                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21963                pw.println("Binder transaction traces for all processes.\n");
21964                for (ProcessRecord process : mLruProcesses) {
21965                    if (!processSanityChecksLocked(process)) {
21966                        continue;
21967                    }
21968
21969                    pw.println("Traces for process: " + process.processName);
21970                    pw.flush();
21971                    try {
21972                        TransferPipe tp = new TransferPipe();
21973                        try {
21974                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
21975                            tp.go(fd.getFileDescriptor());
21976                        } finally {
21977                            tp.kill();
21978                        }
21979                    } catch (IOException e) {
21980                        pw.println("Failure while dumping IPC traces from " + process +
21981                                ".  Exception: " + e);
21982                        pw.flush();
21983                    } catch (RemoteException e) {
21984                        pw.println("Got a RemoteException while dumping IPC traces from " +
21985                                process + ".  Exception: " + e);
21986                        pw.flush();
21987                    }
21988                }
21989                fd = null;
21990                return true;
21991            }
21992        } finally {
21993            if (fd != null) {
21994                try {
21995                    fd.close();
21996                } catch (IOException e) {
21997                }
21998            }
21999        }
22000    }
22001
22002    private final class LocalService extends ActivityManagerInternal {
22003        @Override
22004        public void onWakefulnessChanged(int wakefulness) {
22005            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22006        }
22007
22008        @Override
22009        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22010                String processName, String abiOverride, int uid, Runnable crashHandler) {
22011            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22012                    processName, abiOverride, uid, crashHandler);
22013        }
22014
22015        @Override
22016        public SleepToken acquireSleepToken(String tag) {
22017            Preconditions.checkNotNull(tag);
22018
22019            ComponentName requestedVrService = null;
22020            ComponentName callingVrActivity = null;
22021            int userId = -1;
22022            synchronized (ActivityManagerService.this) {
22023                final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
22024                if (resumedActivity != null) {
22025                    requestedVrService = resumedActivity.requestedVrComponent;
22026                    callingVrActivity = resumedActivity.info.getComponentName();
22027                    userId = resumedActivity.userId;
22028                }
22029            }
22030
22031            if (requestedVrService != null) {
22032                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
22033            }
22034
22035            synchronized (ActivityManagerService.this) {
22036                SleepTokenImpl token = new SleepTokenImpl(tag);
22037                mSleepTokens.add(token);
22038                updateSleepIfNeededLocked();
22039                return token;
22040            }
22041        }
22042
22043        @Override
22044        public ComponentName getHomeActivityForUser(int userId) {
22045            synchronized (ActivityManagerService.this) {
22046                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22047                return homeActivity == null ? null : homeActivity.realActivity;
22048            }
22049        }
22050
22051        @Override
22052        public void onUserRemoved(int userId) {
22053            synchronized (ActivityManagerService.this) {
22054                ActivityManagerService.this.onUserStoppedLocked(userId);
22055            }
22056        }
22057
22058        @Override
22059        public void onLocalVoiceInteractionStarted(IBinder activity,
22060                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22061            synchronized (ActivityManagerService.this) {
22062                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22063                        voiceSession, voiceInteractor);
22064            }
22065        }
22066
22067        @Override
22068        public void notifyStartingWindowDrawn() {
22069            synchronized (ActivityManagerService.this) {
22070                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22071            }
22072        }
22073
22074        @Override
22075        public void notifyAppTransitionStarting(int reason) {
22076            synchronized (ActivityManagerService.this) {
22077                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22078            }
22079        }
22080
22081        @Override
22082        public void notifyAppTransitionFinished() {
22083            synchronized (ActivityManagerService.this) {
22084                mStackSupervisor.notifyAppTransitionDone();
22085            }
22086        }
22087
22088        @Override
22089        public void notifyAppTransitionCancelled() {
22090            synchronized (ActivityManagerService.this) {
22091                mStackSupervisor.notifyAppTransitionDone();
22092            }
22093        }
22094
22095        @Override
22096        public List<IBinder> getTopVisibleActivities() {
22097            synchronized (ActivityManagerService.this) {
22098                return mStackSupervisor.getTopVisibleActivities();
22099            }
22100        }
22101
22102        @Override
22103        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22104            synchronized (ActivityManagerService.this) {
22105                mStackSupervisor.setDockedStackMinimized(minimized);
22106            }
22107        }
22108
22109        @Override
22110        public void killForegroundAppsForUser(int userHandle) {
22111            synchronized (ActivityManagerService.this) {
22112                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22113                final int NP = mProcessNames.getMap().size();
22114                for (int ip = 0; ip < NP; ip++) {
22115                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22116                    final int NA = apps.size();
22117                    for (int ia = 0; ia < NA; ia++) {
22118                        final ProcessRecord app = apps.valueAt(ia);
22119                        if (app.persistent) {
22120                            // We don't kill persistent processes.
22121                            continue;
22122                        }
22123                        if (app.removed) {
22124                            procs.add(app);
22125                        } else if (app.userId == userHandle && app.foregroundActivities) {
22126                            app.removed = true;
22127                            procs.add(app);
22128                        }
22129                    }
22130                }
22131
22132                final int N = procs.size();
22133                for (int i = 0; i < N; i++) {
22134                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22135                }
22136            }
22137        }
22138
22139        @Override
22140        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22141            if (!(target instanceof PendingIntentRecord)) {
22142                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22143                return;
22144            }
22145            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22146        }
22147
22148        @Override
22149        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22150                int userId) {
22151            Preconditions.checkNotNull(values, "Configuration must not be null");
22152            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22153            synchronized (ActivityManagerService.this) {
22154                updateConfigurationLocked(values, null, false, true, userId,
22155                        false /* deferResume */);
22156            }
22157        }
22158
22159        @Override
22160        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22161                Bundle bOptions) {
22162            Preconditions.checkNotNull(intents, "intents");
22163            final String[] resolvedTypes = new String[intents.length];
22164            for (int i = 0; i < intents.length; i++) {
22165                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22166            }
22167
22168            // UID of the package on user userId.
22169            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22170            // packageUid may not be initialized.
22171            int packageUid = 0;
22172            try {
22173                packageUid = AppGlobals.getPackageManager().getPackageUid(
22174                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22175            } catch (RemoteException e) {
22176                // Shouldn't happen.
22177            }
22178
22179            synchronized (ActivityManagerService.this) {
22180                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22181                        /*resultTo*/ null, bOptions, userId);
22182            }
22183        }
22184
22185        @Override
22186        public int getUidProcessState(int uid) {
22187            return getUidState(uid);
22188        }
22189    }
22190
22191    private final class SleepTokenImpl extends SleepToken {
22192        private final String mTag;
22193        private final long mAcquireTime;
22194
22195        public SleepTokenImpl(String tag) {
22196            mTag = tag;
22197            mAcquireTime = SystemClock.uptimeMillis();
22198        }
22199
22200        @Override
22201        public void release() {
22202            synchronized (ActivityManagerService.this) {
22203                if (mSleepTokens.remove(this)) {
22204                    updateSleepIfNeededLocked();
22205                }
22206            }
22207        }
22208
22209        @Override
22210        public String toString() {
22211            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22212        }
22213    }
22214
22215    /**
22216     * An implementation of IAppTask, that allows an app to manage its own tasks via
22217     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22218     * only the process that calls getAppTasks() can call the AppTask methods.
22219     */
22220    class AppTaskImpl extends IAppTask.Stub {
22221        private int mTaskId;
22222        private int mCallingUid;
22223
22224        public AppTaskImpl(int taskId, int callingUid) {
22225            mTaskId = taskId;
22226            mCallingUid = callingUid;
22227        }
22228
22229        private void checkCaller() {
22230            if (mCallingUid != Binder.getCallingUid()) {
22231                throw new SecurityException("Caller " + mCallingUid
22232                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22233            }
22234        }
22235
22236        @Override
22237        public void finishAndRemoveTask() {
22238            checkCaller();
22239
22240            synchronized (ActivityManagerService.this) {
22241                long origId = Binder.clearCallingIdentity();
22242                try {
22243                    // We remove the task from recents to preserve backwards
22244                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22245                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22246                    }
22247                } finally {
22248                    Binder.restoreCallingIdentity(origId);
22249                }
22250            }
22251        }
22252
22253        @Override
22254        public ActivityManager.RecentTaskInfo getTaskInfo() {
22255            checkCaller();
22256
22257            synchronized (ActivityManagerService.this) {
22258                long origId = Binder.clearCallingIdentity();
22259                try {
22260                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22261                    if (tr == null) {
22262                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22263                    }
22264                    return createRecentTaskInfoFromTaskRecord(tr);
22265                } finally {
22266                    Binder.restoreCallingIdentity(origId);
22267                }
22268            }
22269        }
22270
22271        @Override
22272        public void moveToFront() {
22273            checkCaller();
22274            // Will bring task to front if it already has a root activity.
22275            final long origId = Binder.clearCallingIdentity();
22276            try {
22277                synchronized (this) {
22278                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22279                }
22280            } finally {
22281                Binder.restoreCallingIdentity(origId);
22282            }
22283        }
22284
22285        @Override
22286        public int startActivity(IBinder whoThread, String callingPackage,
22287                Intent intent, String resolvedType, Bundle bOptions) {
22288            checkCaller();
22289
22290            int callingUser = UserHandle.getCallingUserId();
22291            TaskRecord tr;
22292            IApplicationThread appThread;
22293            synchronized (ActivityManagerService.this) {
22294                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22295                if (tr == null) {
22296                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22297                }
22298                appThread = IApplicationThread.Stub.asInterface(whoThread);
22299                if (appThread == null) {
22300                    throw new IllegalArgumentException("Bad app thread " + appThread);
22301                }
22302            }
22303            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22304                    resolvedType, null, null, null, null, 0, 0, null, null,
22305                    null, bOptions, false, callingUser, null, tr);
22306        }
22307
22308        @Override
22309        public void setExcludeFromRecents(boolean exclude) {
22310            checkCaller();
22311
22312            synchronized (ActivityManagerService.this) {
22313                long origId = Binder.clearCallingIdentity();
22314                try {
22315                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22316                    if (tr == null) {
22317                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22318                    }
22319                    Intent intent = tr.getBaseIntent();
22320                    if (exclude) {
22321                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22322                    } else {
22323                        intent.setFlags(intent.getFlags()
22324                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22325                    }
22326                } finally {
22327                    Binder.restoreCallingIdentity(origId);
22328                }
22329            }
22330        }
22331    }
22332
22333    /**
22334     * Kill processes for the user with id userId and that depend on the package named packageName
22335     */
22336    @Override
22337    public void killPackageDependents(String packageName, int userId) {
22338        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22339        if (packageName == null) {
22340            throw new NullPointerException(
22341                    "Cannot kill the dependents of a package without its name.");
22342        }
22343
22344        long callingId = Binder.clearCallingIdentity();
22345        IPackageManager pm = AppGlobals.getPackageManager();
22346        int pkgUid = -1;
22347        try {
22348            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22349        } catch (RemoteException e) {
22350        }
22351        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22352            throw new IllegalArgumentException(
22353                    "Cannot kill dependents of non-existing package " + packageName);
22354        }
22355        try {
22356            synchronized(this) {
22357                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22358                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22359                        "dep: " + packageName);
22360            }
22361        } finally {
22362            Binder.restoreCallingIdentity(callingId);
22363        }
22364    }
22365
22366    @Override
22367    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22368        final int userId = intent.getCreatorUserHandle().getIdentifier();
22369        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22370            return false;
22371        }
22372        IIntentSender target = intent.getTarget();
22373        if (!(target instanceof PendingIntentRecord)) {
22374            return false;
22375        }
22376        final PendingIntentRecord record = (PendingIntentRecord) target;
22377        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22378                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22379        // For direct boot aware activities, they can be shown without triggering a work challenge
22380        // before the profile user is unlocked.
22381        return rInfo != null && rInfo.activityInfo != null;
22382    }
22383
22384    /**
22385     * Attach an agent to the specified process (proces name or PID)
22386     */
22387    public void attachAgent(String process, String path) {
22388        try {
22389            synchronized (this) {
22390                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22391                if (proc == null || proc.thread == null) {
22392                    throw new IllegalArgumentException("Unknown process: " + process);
22393                }
22394
22395                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22396                if (!isDebuggable) {
22397                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22398                        throw new SecurityException("Process not debuggable: " + proc);
22399                    }
22400                }
22401
22402                proc.thread.attachAgent(path);
22403            }
22404        } catch (RemoteException e) {
22405            throw new IllegalStateException("Process disappeared");
22406        }
22407    }
22408}
22409