ActivityManagerService.java revision 5820f7fff57b32aec694116c41e3babdb8418539
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    // it's a semaphore; boost when 0->1, reset when 1->0
644    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
645        @Override protected Integer initialValue() {
646            return 0;
647        }
648    };
649
650    static void boostPriorityForLockedSection() {
651        if (sIsBoosted.get() == 0) {
652            // boost to prio 118 while holding a global lock
653            Process.setThreadPriority(Process.myTid(), -2);
654            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
655        }
656        int cur = sIsBoosted.get();
657        sIsBoosted.set(cur + 1);
658    }
659
660    static void resetPriorityAfterLockedSection() {
661        sIsBoosted.set(sIsBoosted.get() - 1);
662        if (sIsBoosted.get() == 0) {
663            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
664            Process.setThreadPriority(Process.myTid(), 0);
665        }
666    }
667    public class PendingAssistExtras extends Binder implements Runnable {
668        public final ActivityRecord activity;
669        public final Bundle extras;
670        public final Intent intent;
671        public final String hint;
672        public final IResultReceiver receiver;
673        public final int userHandle;
674        public boolean haveResult = false;
675        public Bundle result = null;
676        public AssistStructure structure = null;
677        public AssistContent content = null;
678        public Bundle receiverExtras;
679
680        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
681                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
682            activity = _activity;
683            extras = _extras;
684            intent = _intent;
685            hint = _hint;
686            receiver = _receiver;
687            receiverExtras = _receiverExtras;
688            userHandle = _userHandle;
689        }
690        @Override
691        public void run() {
692            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
693            synchronized (this) {
694                haveResult = true;
695                notifyAll();
696            }
697            pendingAssistExtrasTimedOut(this);
698        }
699    }
700
701    final ArrayList<PendingAssistExtras> mPendingAssistExtras
702            = new ArrayList<PendingAssistExtras>();
703
704    /**
705     * Process management.
706     */
707    final ProcessList mProcessList = new ProcessList();
708
709    /**
710     * All of the applications we currently have running organized by name.
711     * The keys are strings of the application package name (as
712     * returned by the package manager), and the keys are ApplicationRecord
713     * objects.
714     */
715    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
716
717    /**
718     * Tracking long-term execution of processes to look for abuse and other
719     * bad app behavior.
720     */
721    final ProcessStatsService mProcessStats;
722
723    /**
724     * The currently running isolated processes.
725     */
726    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
727
728    /**
729     * Counter for assigning isolated process uids, to avoid frequently reusing the
730     * same ones.
731     */
732    int mNextIsolatedProcessUid = 0;
733
734    /**
735     * The currently running heavy-weight process, if any.
736     */
737    ProcessRecord mHeavyWeightProcess = null;
738
739    /**
740     * All of the processes we currently have running organized by pid.
741     * The keys are the pid running the application.
742     *
743     * <p>NOTE: This object is protected by its own lock, NOT the global
744     * activity manager lock!
745     */
746    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
747
748    /**
749     * All of the processes that have been forced to be foreground.  The key
750     * is the pid of the caller who requested it (we hold a death
751     * link on it).
752     */
753    abstract class ForegroundToken implements IBinder.DeathRecipient {
754        int pid;
755        IBinder token;
756    }
757    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
758
759    /**
760     * List of records for processes that someone had tried to start before the
761     * system was ready.  We don't start them at that point, but ensure they
762     * are started by the time booting is complete.
763     */
764    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of persistent applications that are in the process
768     * of being started.
769     */
770    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Processes that are being forcibly torn down.
774     */
775    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of running applications, sorted by recent usage.
779     * The first entry in the list is the least recently used.
780     */
781    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Where in mLruProcesses that the processes hosting activities start.
785     */
786    int mLruProcessActivityStart = 0;
787
788    /**
789     * Where in mLruProcesses that the processes hosting services start.
790     * This is after (lower index) than mLruProcessesActivityStart.
791     */
792    int mLruProcessServiceStart = 0;
793
794    /**
795     * List of processes that should gc as soon as things are idle.
796     */
797    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
798
799    /**
800     * Processes we want to collect PSS data from.
801     */
802    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
803
804    private boolean mBinderTransactionTrackingEnabled = false;
805
806    /**
807     * Last time we requested PSS data of all processes.
808     */
809    long mLastFullPssTime = SystemClock.uptimeMillis();
810
811    /**
812     * If set, the next time we collect PSS data we should do a full collection
813     * with data from native processes and the kernel.
814     */
815    boolean mFullPssPending = false;
816
817    /**
818     * This is the process holding what we currently consider to be
819     * the "home" activity.
820     */
821    ProcessRecord mHomeProcess;
822
823    /**
824     * This is the process holding the activity the user last visited that
825     * is in a different process from the one they are currently in.
826     */
827    ProcessRecord mPreviousProcess;
828
829    /**
830     * The time at which the previous process was last visible.
831     */
832    long mPreviousProcessVisibleTime;
833
834    /**
835     * Track all uids that have actively running processes.
836     */
837    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
838
839    /**
840     * This is for verifying the UID report flow.
841     */
842    static final boolean VALIDATE_UID_STATES = true;
843    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
844
845    /**
846     * Packages that the user has asked to have run in screen size
847     * compatibility mode instead of filling the screen.
848     */
849    final CompatModePackages mCompatModePackages;
850
851    /**
852     * Set of IntentSenderRecord objects that are currently active.
853     */
854    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
855            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
856
857    /**
858     * Fingerprints (hashCode()) of stack traces that we've
859     * already logged DropBox entries for.  Guarded by itself.  If
860     * something (rogue user app) forces this over
861     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
862     */
863    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
864    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
865
866    /**
867     * Strict Mode background batched logging state.
868     *
869     * The string buffer is guarded by itself, and its lock is also
870     * used to determine if another batched write is already
871     * in-flight.
872     */
873    private final StringBuilder mStrictModeBuffer = new StringBuilder();
874
875    /**
876     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
877     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
878     */
879    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
880
881    /**
882     * Resolver for broadcast intents to registered receivers.
883     * Holds BroadcastFilter (subclass of IntentFilter).
884     */
885    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
886            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
887        @Override
888        protected boolean allowFilterResult(
889                BroadcastFilter filter, List<BroadcastFilter> dest) {
890            IBinder target = filter.receiverList.receiver.asBinder();
891            for (int i = dest.size() - 1; i >= 0; i--) {
892                if (dest.get(i).receiverList.receiver.asBinder() == target) {
893                    return false;
894                }
895            }
896            return true;
897        }
898
899        @Override
900        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
901            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
902                    || userId == filter.owningUserId) {
903                return super.newResult(filter, match, userId);
904            }
905            return null;
906        }
907
908        @Override
909        protected BroadcastFilter[] newArray(int size) {
910            return new BroadcastFilter[size];
911        }
912
913        @Override
914        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
915            return packageName.equals(filter.packageName);
916        }
917    };
918
919    /**
920     * State of all active sticky broadcasts per user.  Keys are the action of the
921     * sticky Intent, values are an ArrayList of all broadcasted intents with
922     * that action (which should usually be one).  The SparseArray is keyed
923     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
924     * for stickies that are sent to all users.
925     */
926    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
927            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
928
929    final ActiveServices mServices;
930
931    final static class Association {
932        final int mSourceUid;
933        final String mSourceProcess;
934        final int mTargetUid;
935        final ComponentName mTargetComponent;
936        final String mTargetProcess;
937
938        int mCount;
939        long mTime;
940
941        int mNesting;
942        long mStartTime;
943
944        // states of the source process when the bind occurred.
945        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
946        long mLastStateUptime;
947        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
948                - ActivityManager.MIN_PROCESS_STATE+1];
949
950        Association(int sourceUid, String sourceProcess, int targetUid,
951                ComponentName targetComponent, String targetProcess) {
952            mSourceUid = sourceUid;
953            mSourceProcess = sourceProcess;
954            mTargetUid = targetUid;
955            mTargetComponent = targetComponent;
956            mTargetProcess = targetProcess;
957        }
958    }
959
960    /**
961     * When service association tracking is enabled, this is all of the associations we
962     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
963     * -> association data.
964     */
965    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
966            mAssociations = new SparseArray<>();
967    boolean mTrackingAssociations;
968
969    /**
970     * Backup/restore process management
971     */
972    String mBackupAppName = null;
973    BackupRecord mBackupTarget = null;
974
975    final ProviderMap mProviderMap;
976
977    /**
978     * List of content providers who have clients waiting for them.  The
979     * application is currently being launched and the provider will be
980     * removed from this list once it is published.
981     */
982    final ArrayList<ContentProviderRecord> mLaunchingProviders
983            = new ArrayList<ContentProviderRecord>();
984
985    /**
986     * File storing persisted {@link #mGrantedUriPermissions}.
987     */
988    private final AtomicFile mGrantFile;
989
990    /** XML constants used in {@link #mGrantFile} */
991    private static final String TAG_URI_GRANTS = "uri-grants";
992    private static final String TAG_URI_GRANT = "uri-grant";
993    private static final String ATTR_USER_HANDLE = "userHandle";
994    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
995    private static final String ATTR_TARGET_USER_ID = "targetUserId";
996    private static final String ATTR_SOURCE_PKG = "sourcePkg";
997    private static final String ATTR_TARGET_PKG = "targetPkg";
998    private static final String ATTR_URI = "uri";
999    private static final String ATTR_MODE_FLAGS = "modeFlags";
1000    private static final String ATTR_CREATED_TIME = "createdTime";
1001    private static final String ATTR_PREFIX = "prefix";
1002
1003    /**
1004     * Global set of specific {@link Uri} permissions that have been granted.
1005     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1006     * to {@link UriPermission#uri} to {@link UriPermission}.
1007     */
1008    @GuardedBy("this")
1009    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1010            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1011
1012    public static class GrantUri {
1013        public final int sourceUserId;
1014        public final Uri uri;
1015        public boolean prefix;
1016
1017        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1018            this.sourceUserId = sourceUserId;
1019            this.uri = uri;
1020            this.prefix = prefix;
1021        }
1022
1023        @Override
1024        public int hashCode() {
1025            int hashCode = 1;
1026            hashCode = 31 * hashCode + sourceUserId;
1027            hashCode = 31 * hashCode + uri.hashCode();
1028            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1029            return hashCode;
1030        }
1031
1032        @Override
1033        public boolean equals(Object o) {
1034            if (o instanceof GrantUri) {
1035                GrantUri other = (GrantUri) o;
1036                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1037                        && prefix == other.prefix;
1038            }
1039            return false;
1040        }
1041
1042        @Override
1043        public String toString() {
1044            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1045            if (prefix) result += " [prefix]";
1046            return result;
1047        }
1048
1049        public String toSafeString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1056            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1057                    ContentProvider.getUriWithoutUserId(uri), false);
1058        }
1059    }
1060
1061    CoreSettingsObserver mCoreSettingsObserver;
1062
1063    FontScaleSettingObserver mFontScaleSettingObserver;
1064
1065    private final class FontScaleSettingObserver extends ContentObserver {
1066        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1067
1068        public FontScaleSettingObserver() {
1069            super(mHandler);
1070            ContentResolver resolver = mContext.getContentResolver();
1071            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1072        }
1073
1074        @Override
1075        public void onChange(boolean selfChange, Uri uri) {
1076            if (mFontScaleUri.equals(uri)) {
1077                updateFontScaleIfNeeded();
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Thread-local storage used to carry caller permissions over through
1084     * indirect content-provider access.
1085     */
1086    private class Identity {
1087        public final IBinder token;
1088        public final int pid;
1089        public final int uid;
1090
1091        Identity(IBinder _token, int _pid, int _uid) {
1092            token = _token;
1093            pid = _pid;
1094            uid = _uid;
1095        }
1096    }
1097
1098    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1099
1100    /**
1101     * All information we have collected about the runtime performance of
1102     * any user id that can impact battery performance.
1103     */
1104    final BatteryStatsService mBatteryStatsService;
1105
1106    /**
1107     * Information about component usage
1108     */
1109    UsageStatsManagerInternal mUsageStatsService;
1110
1111    /**
1112     * Access to DeviceIdleController service.
1113     */
1114    DeviceIdleController.LocalService mLocalDeviceIdleController;
1115
1116    /**
1117     * Information about and control over application operations
1118     */
1119    final AppOpsService mAppOpsService;
1120
1121    /**
1122     * Current configuration information.  HistoryRecord objects are given
1123     * a reference to this object to indicate which configuration they are
1124     * currently running in, so this object must be kept immutable.
1125     */
1126    Configuration mConfiguration = new Configuration();
1127
1128    /**
1129     * Current sequencing integer of the configuration, for skipping old
1130     * configurations.
1131     */
1132    int mConfigurationSeq = 0;
1133
1134    boolean mSuppressResizeConfigChanges = false;
1135
1136    /**
1137     * Hardware-reported OpenGLES version.
1138     */
1139    final int GL_ES_VERSION;
1140
1141    /**
1142     * List of initialization arguments to pass to all processes when binding applications to them.
1143     * For example, references to the commonly used services.
1144     */
1145    HashMap<String, IBinder> mAppBindArgs;
1146
1147    /**
1148     * Temporary to avoid allocations.  Protected by main lock.
1149     */
1150    final StringBuilder mStringBuilder = new StringBuilder(256);
1151
1152    /**
1153     * Used to control how we initialize the service.
1154     */
1155    ComponentName mTopComponent;
1156    String mTopAction = Intent.ACTION_MAIN;
1157    String mTopData;
1158
1159    volatile boolean mProcessesReady = false;
1160    volatile boolean mSystemReady = false;
1161    volatile boolean mOnBattery = false;
1162    volatile int mFactoryTest;
1163
1164    @GuardedBy("this") boolean mBooting = false;
1165    @GuardedBy("this") boolean mCallFinishBooting = false;
1166    @GuardedBy("this") boolean mBootAnimationComplete = false;
1167    @GuardedBy("this") boolean mLaunchWarningShown = false;
1168    @GuardedBy("this") boolean mCheckedForSetup = false;
1169
1170    Context mContext;
1171
1172    /**
1173     * The time at which we will allow normal application switches again,
1174     * after a call to {@link #stopAppSwitches()}.
1175     */
1176    long mAppSwitchesAllowedTime;
1177
1178    /**
1179     * This is set to true after the first switch after mAppSwitchesAllowedTime
1180     * is set; any switches after that will clear the time.
1181     */
1182    boolean mDidAppSwitch;
1183
1184    /**
1185     * Last time (in realtime) at which we checked for power usage.
1186     */
1187    long mLastPowerCheckRealtime;
1188
1189    /**
1190     * Last time (in uptime) at which we checked for power usage.
1191     */
1192    long mLastPowerCheckUptime;
1193
1194    /**
1195     * Set while we are wanting to sleep, to prevent any
1196     * activities from being started/resumed.
1197     */
1198    private boolean mSleeping = false;
1199
1200    /**
1201     * The process state used for processes that are running the top activities.
1202     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1203     */
1204    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1205
1206    /**
1207     * Set while we are running a voice interaction.  This overrides
1208     * sleeping while it is active.
1209     */
1210    private IVoiceInteractionSession mRunningVoice;
1211
1212    /**
1213     * For some direct access we need to power manager.
1214     */
1215    PowerManagerInternal mLocalPowerManager;
1216
1217    /**
1218     * We want to hold a wake lock while running a voice interaction session, since
1219     * this may happen with the screen off and we need to keep the CPU running to
1220     * be able to continue to interact with the user.
1221     */
1222    PowerManager.WakeLock mVoiceWakeLock;
1223
1224    /**
1225     * State of external calls telling us if the device is awake or asleep.
1226     */
1227    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1228
1229    /**
1230     * A list of tokens that cause the top activity to be put to sleep.
1231     * They are used by components that may hide and block interaction with underlying
1232     * activities.
1233     */
1234    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1235
1236    static final int LOCK_SCREEN_HIDDEN = 0;
1237    static final int LOCK_SCREEN_LEAVING = 1;
1238    static final int LOCK_SCREEN_SHOWN = 2;
1239    /**
1240     * State of external call telling us if the lock screen is shown.
1241     */
1242    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1243
1244    /**
1245     * Set if we are shutting down the system, similar to sleeping.
1246     */
1247    boolean mShuttingDown = false;
1248
1249    /**
1250     * Current sequence id for oom_adj computation traversal.
1251     */
1252    int mAdjSeq = 0;
1253
1254    /**
1255     * Current sequence id for process LRU updating.
1256     */
1257    int mLruSeq = 0;
1258
1259    /**
1260     * Keep track of the non-cached/empty process we last found, to help
1261     * determine how to distribute cached/empty processes next time.
1262     */
1263    int mNumNonCachedProcs = 0;
1264
1265    /**
1266     * Keep track of the number of cached hidden procs, to balance oom adj
1267     * distribution between those and empty procs.
1268     */
1269    int mNumCachedHiddenProcs = 0;
1270
1271    /**
1272     * Keep track of the number of service processes we last found, to
1273     * determine on the next iteration which should be B services.
1274     */
1275    int mNumServiceProcs = 0;
1276    int mNewNumAServiceProcs = 0;
1277    int mNewNumServiceProcs = 0;
1278
1279    /**
1280     * Allow the current computed overall memory level of the system to go down?
1281     * This is set to false when we are killing processes for reasons other than
1282     * memory management, so that the now smaller process list will not be taken as
1283     * an indication that memory is tighter.
1284     */
1285    boolean mAllowLowerMemLevel = false;
1286
1287    /**
1288     * The last computed memory level, for holding when we are in a state that
1289     * processes are going away for other reasons.
1290     */
1291    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1292
1293    /**
1294     * The last total number of process we have, to determine if changes actually look
1295     * like a shrinking number of process due to lower RAM.
1296     */
1297    int mLastNumProcesses;
1298
1299    /**
1300     * The uptime of the last time we performed idle maintenance.
1301     */
1302    long mLastIdleTime = SystemClock.uptimeMillis();
1303
1304    /**
1305     * Total time spent with RAM that has been added in the past since the last idle time.
1306     */
1307    long mLowRamTimeSinceLastIdle = 0;
1308
1309    /**
1310     * If RAM is currently low, when that horrible situation started.
1311     */
1312    long mLowRamStartTime = 0;
1313
1314    /**
1315     * For reporting to battery stats the current top application.
1316     */
1317    private String mCurResumedPackage = null;
1318    private int mCurResumedUid = -1;
1319
1320    /**
1321     * For reporting to battery stats the apps currently running foreground
1322     * service.  The ProcessMap is package/uid tuples; each of these contain
1323     * an array of the currently foreground processes.
1324     */
1325    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1326            = new ProcessMap<ArrayList<ProcessRecord>>();
1327
1328    /**
1329     * This is set if we had to do a delayed dexopt of an app before launching
1330     * it, to increase the ANR timeouts in that case.
1331     */
1332    boolean mDidDexOpt;
1333
1334    /**
1335     * Set if the systemServer made a call to enterSafeMode.
1336     */
1337    boolean mSafeMode;
1338
1339    /**
1340     * If true, we are running under a test environment so will sample PSS from processes
1341     * much more rapidly to try to collect better data when the tests are rapidly
1342     * running through apps.
1343     */
1344    boolean mTestPssMode = false;
1345
1346    String mDebugApp = null;
1347    boolean mWaitForDebugger = false;
1348    boolean mDebugTransient = false;
1349    String mOrigDebugApp = null;
1350    boolean mOrigWaitForDebugger = false;
1351    boolean mAlwaysFinishActivities = false;
1352    boolean mLenientBackgroundCheck = false;
1353    boolean mForceResizableActivities;
1354    boolean mSupportsMultiWindow;
1355    boolean mSupportsFreeformWindowManagement;
1356    boolean mSupportsPictureInPicture;
1357    boolean mSupportsLeanbackOnly;
1358    Rect mDefaultPinnedStackBounds;
1359    IActivityController mController = null;
1360    boolean mControllerIsAMonkey = false;
1361    String mProfileApp = null;
1362    ProcessRecord mProfileProc = null;
1363    String mProfileFile;
1364    ParcelFileDescriptor mProfileFd;
1365    int mSamplingInterval = 0;
1366    boolean mAutoStopProfiler = false;
1367    int mProfileType = 0;
1368    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1369    String mMemWatchDumpProcName;
1370    String mMemWatchDumpFile;
1371    int mMemWatchDumpPid;
1372    int mMemWatchDumpUid;
1373    String mTrackAllocationApp = null;
1374    String mNativeDebuggingApp = null;
1375
1376    final long[] mTmpLong = new long[2];
1377
1378    static final class ProcessChangeItem {
1379        static final int CHANGE_ACTIVITIES = 1<<0;
1380        static final int CHANGE_PROCESS_STATE = 1<<1;
1381        int changes;
1382        int uid;
1383        int pid;
1384        int processState;
1385        boolean foregroundActivities;
1386    }
1387
1388    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1389    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1390
1391    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1392    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1393
1394    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1395    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1396
1397    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1398    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1399
1400    /**
1401     * Runtime CPU use collection thread.  This object's lock is used to
1402     * perform synchronization with the thread (notifying it to run).
1403     */
1404    final Thread mProcessCpuThread;
1405
1406    /**
1407     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1408     * Must acquire this object's lock when accessing it.
1409     * NOTE: this lock will be held while doing long operations (trawling
1410     * through all processes in /proc), so it should never be acquired by
1411     * any critical paths such as when holding the main activity manager lock.
1412     */
1413    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1414            MONITOR_THREAD_CPU_USAGE);
1415    final AtomicLong mLastCpuTime = new AtomicLong(0);
1416    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1417
1418    long mLastWriteTime = 0;
1419
1420    /**
1421     * Used to retain an update lock when the foreground activity is in
1422     * immersive mode.
1423     */
1424    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1425
1426    /**
1427     * Set to true after the system has finished booting.
1428     */
1429    boolean mBooted = false;
1430
1431    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1432    int mProcessLimitOverride = -1;
1433
1434    WindowManagerService mWindowManager;
1435    final ActivityThread mSystemThread;
1436
1437    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1438        final ProcessRecord mApp;
1439        final int mPid;
1440        final IApplicationThread mAppThread;
1441
1442        AppDeathRecipient(ProcessRecord app, int pid,
1443                IApplicationThread thread) {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "New death recipient " + this
1446                + " for thread " + thread.asBinder());
1447            mApp = app;
1448            mPid = pid;
1449            mAppThread = thread;
1450        }
1451
1452        @Override
1453        public void binderDied() {
1454            if (DEBUG_ALL) Slog.v(
1455                TAG, "Death received in " + this
1456                + " for thread " + mAppThread.asBinder());
1457            synchronized(ActivityManagerService.this) {
1458                appDiedLocked(mApp, mPid, mAppThread, true);
1459            }
1460        }
1461    }
1462
1463    static final int SHOW_ERROR_UI_MSG = 1;
1464    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1465    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1466    static final int UPDATE_CONFIGURATION_MSG = 4;
1467    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1468    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1469    static final int SERVICE_TIMEOUT_MSG = 12;
1470    static final int UPDATE_TIME_ZONE = 13;
1471    static final int SHOW_UID_ERROR_UI_MSG = 14;
1472    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1473    static final int PROC_START_TIMEOUT_MSG = 20;
1474    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1475    static final int KILL_APPLICATION_MSG = 22;
1476    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1477    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1478    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1479    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1480    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1481    static final int CLEAR_DNS_CACHE_MSG = 28;
1482    static final int UPDATE_HTTP_PROXY_MSG = 29;
1483    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1484    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1485    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1486    static final int REPORT_MEM_USAGE_MSG = 33;
1487    static final int REPORT_USER_SWITCH_MSG = 34;
1488    static final int CONTINUE_USER_SWITCH_MSG = 35;
1489    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1490    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1491    static final int PERSIST_URI_GRANTS_MSG = 38;
1492    static final int REQUEST_ALL_PSS_MSG = 39;
1493    static final int START_PROFILES_MSG = 40;
1494    static final int UPDATE_TIME = 41;
1495    static final int SYSTEM_USER_START_MSG = 42;
1496    static final int SYSTEM_USER_CURRENT_MSG = 43;
1497    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1498    static final int FINISH_BOOTING_MSG = 45;
1499    static final int START_USER_SWITCH_UI_MSG = 46;
1500    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1501    static final int DISMISS_DIALOG_UI_MSG = 48;
1502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1503    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1504    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1505    static final int DELETE_DUMPHEAP_MSG = 52;
1506    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1507    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1508    static final int REPORT_TIME_TRACKER_MSG = 55;
1509    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1510    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1511    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1513    static final int IDLE_UIDS_MSG = 60;
1514    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1515    static final int LOG_STACK_STATE = 62;
1516    static final int VR_MODE_CHANGE_MSG = 63;
1517    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1518    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1519    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1520    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1521    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1522    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1523    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1524
1525    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1526    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1527    static final int FIRST_COMPAT_MODE_MSG = 300;
1528    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1529
1530    static ServiceThread sKillThread = null;
1531    static KillHandler sKillHandler = null;
1532
1533    CompatModeDialog mCompatModeDialog;
1534    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1535    long mLastMemUsageReportTime = 0;
1536
1537    /**
1538     * Flag whether the current user is a "monkey", i.e. whether
1539     * the UI is driven by a UI automation tool.
1540     */
1541    private boolean mUserIsMonkey;
1542
1543    /** Flag whether the device has a Recents UI */
1544    boolean mHasRecents;
1545
1546    /** The dimensions of the thumbnails in the Recents UI. */
1547    int mThumbnailWidth;
1548    int mThumbnailHeight;
1549    float mFullscreenThumbnailScale;
1550
1551    final ServiceThread mHandlerThread;
1552    final MainHandler mHandler;
1553    final UiHandler mUiHandler;
1554
1555    PackageManagerInternal mPackageManagerInt;
1556
1557    // VoiceInteraction session ID that changes for each new request except when
1558    // being called for multiwindow assist in a single session.
1559    private int mViSessionId = 1000;
1560
1561    final class KillHandler extends Handler {
1562        static final int KILL_PROCESS_GROUP_MSG = 4000;
1563
1564        public KillHandler(Looper looper) {
1565            super(looper, null, true);
1566        }
1567
1568        @Override
1569        public void handleMessage(Message msg) {
1570            switch (msg.what) {
1571                case KILL_PROCESS_GROUP_MSG:
1572                {
1573                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1574                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1575                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1576                }
1577                break;
1578
1579                default:
1580                    super.handleMessage(msg);
1581            }
1582        }
1583    }
1584
1585    final class UiHandler extends Handler {
1586        public UiHandler() {
1587            super(com.android.server.UiThread.get().getLooper(), null, true);
1588        }
1589
1590        @Override
1591        public void handleMessage(Message msg) {
1592            switch (msg.what) {
1593            case SHOW_ERROR_UI_MSG: {
1594                mAppErrors.handleShowAppErrorUi(msg);
1595                ensureBootCompleted();
1596            } break;
1597            case SHOW_NOT_RESPONDING_UI_MSG: {
1598                mAppErrors.handleShowAnrUi(msg);
1599                ensureBootCompleted();
1600            } break;
1601            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1602                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1603                synchronized (ActivityManagerService.this) {
1604                    ProcessRecord proc = (ProcessRecord) data.get("app");
1605                    if (proc == null) {
1606                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1607                        break;
1608                    }
1609                    if (proc.crashDialog != null) {
1610                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1611                        return;
1612                    }
1613                    AppErrorResult res = (AppErrorResult) data.get("result");
1614                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1615                        Dialog d = new StrictModeViolationDialog(mContext,
1616                                ActivityManagerService.this, res, proc);
1617                        d.show();
1618                        proc.crashDialog = d;
1619                    } else {
1620                        // The device is asleep, so just pretend that the user
1621                        // saw a crash dialog and hit "force quit".
1622                        res.set(0);
1623                    }
1624                }
1625                ensureBootCompleted();
1626            } break;
1627            case SHOW_FACTORY_ERROR_UI_MSG: {
1628                Dialog d = new FactoryErrorDialog(
1629                    mContext, msg.getData().getCharSequence("msg"));
1630                d.show();
1631                ensureBootCompleted();
1632            } break;
1633            case WAIT_FOR_DEBUGGER_UI_MSG: {
1634                synchronized (ActivityManagerService.this) {
1635                    ProcessRecord app = (ProcessRecord)msg.obj;
1636                    if (msg.arg1 != 0) {
1637                        if (!app.waitedForDebugger) {
1638                            Dialog d = new AppWaitingForDebuggerDialog(
1639                                    ActivityManagerService.this,
1640                                    mContext, app);
1641                            app.waitDialog = d;
1642                            app.waitedForDebugger = true;
1643                            d.show();
1644                        }
1645                    } else {
1646                        if (app.waitDialog != null) {
1647                            app.waitDialog.dismiss();
1648                            app.waitDialog = null;
1649                        }
1650                    }
1651                }
1652            } break;
1653            case SHOW_UID_ERROR_UI_MSG: {
1654                if (mShowDialogs) {
1655                    AlertDialog d = new BaseErrorDialog(mContext);
1656                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                    d.setCancelable(false);
1658                    d.setTitle(mContext.getText(R.string.android_system_label));
1659                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1660                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                    d.show();
1663                }
1664            } break;
1665            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1666                if (mShowDialogs) {
1667                    AlertDialog d = new BaseErrorDialog(mContext);
1668                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1669                    d.setCancelable(false);
1670                    d.setTitle(mContext.getText(R.string.android_system_label));
1671                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1672                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1673                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1674                    d.show();
1675                }
1676            } break;
1677            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1678                synchronized (ActivityManagerService.this) {
1679                    ActivityRecord ar = (ActivityRecord) msg.obj;
1680                    if (mCompatModeDialog != null) {
1681                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1682                                ar.info.applicationInfo.packageName)) {
1683                            return;
1684                        }
1685                        mCompatModeDialog.dismiss();
1686                        mCompatModeDialog = null;
1687                    }
1688                    if (ar != null && false) {
1689                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1690                                ar.packageName)) {
1691                            int mode = mCompatModePackages.computeCompatModeLocked(
1692                                    ar.info.applicationInfo);
1693                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1694                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1695                                mCompatModeDialog = new CompatModeDialog(
1696                                        ActivityManagerService.this, mContext,
1697                                        ar.info.applicationInfo);
1698                                mCompatModeDialog.show();
1699                            }
1700                        }
1701                    }
1702                }
1703                break;
1704            }
1705            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1706                synchronized (ActivityManagerService.this) {
1707                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1708                    if (mUnsupportedDisplaySizeDialog != null) {
1709                        mUnsupportedDisplaySizeDialog.dismiss();
1710                        mUnsupportedDisplaySizeDialog = null;
1711                    }
1712                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1713                            ar.packageName)) {
1714                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1715                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1716                        mUnsupportedDisplaySizeDialog.show();
1717                    }
1718                }
1719                break;
1720            }
1721            case START_USER_SWITCH_UI_MSG: {
1722                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1723                break;
1724            }
1725            case DISMISS_DIALOG_UI_MSG: {
1726                final Dialog d = (Dialog) msg.obj;
1727                d.dismiss();
1728                break;
1729            }
1730            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1731                dispatchProcessesChanged();
1732                break;
1733            }
1734            case DISPATCH_PROCESS_DIED_UI_MSG: {
1735                final int pid = msg.arg1;
1736                final int uid = msg.arg2;
1737                dispatchProcessDied(pid, uid);
1738                break;
1739            }
1740            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1741                dispatchUidsChanged();
1742            } break;
1743            }
1744        }
1745    }
1746
1747    final class MainHandler extends Handler {
1748        public MainHandler(Looper looper) {
1749            super(looper, null, true);
1750        }
1751
1752        @Override
1753        public void handleMessage(Message msg) {
1754            switch (msg.what) {
1755            case UPDATE_CONFIGURATION_MSG: {
1756                final ContentResolver resolver = mContext.getContentResolver();
1757                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1758                        msg.arg1);
1759            } break;
1760            case GC_BACKGROUND_PROCESSES_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    performAppGcsIfAppropriateLocked();
1763                }
1764            } break;
1765            case SERVICE_TIMEOUT_MSG: {
1766                if (mDidDexOpt) {
1767                    mDidDexOpt = false;
1768                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1769                    nmsg.obj = msg.obj;
1770                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1771                    return;
1772                }
1773                mServices.serviceTimeout((ProcessRecord)msg.obj);
1774            } break;
1775            case UPDATE_TIME_ZONE: {
1776                synchronized (ActivityManagerService.this) {
1777                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1778                        ProcessRecord r = mLruProcesses.get(i);
1779                        if (r.thread != null) {
1780                            try {
1781                                r.thread.updateTimeZone();
1782                            } catch (RemoteException ex) {
1783                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1784                            }
1785                        }
1786                    }
1787                }
1788            } break;
1789            case CLEAR_DNS_CACHE_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.clearDnsCache();
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1798                            }
1799                        }
1800                    }
1801                }
1802            } break;
1803            case UPDATE_HTTP_PROXY_MSG: {
1804                ProxyInfo proxy = (ProxyInfo)msg.obj;
1805                String host = "";
1806                String port = "";
1807                String exclList = "";
1808                Uri pacFileUrl = Uri.EMPTY;
1809                if (proxy != null) {
1810                    host = proxy.getHost();
1811                    port = Integer.toString(proxy.getPort());
1812                    exclList = proxy.getExclusionListAsString();
1813                    pacFileUrl = proxy.getPacFileUrl();
1814                }
1815                synchronized (ActivityManagerService.this) {
1816                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1817                        ProcessRecord r = mLruProcesses.get(i);
1818                        if (r.thread != null) {
1819                            try {
1820                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1821                            } catch (RemoteException ex) {
1822                                Slog.w(TAG, "Failed to update http proxy for: " +
1823                                        r.info.processName);
1824                            }
1825                        }
1826                    }
1827                }
1828            } break;
1829            case PROC_START_TIMEOUT_MSG: {
1830                if (mDidDexOpt) {
1831                    mDidDexOpt = false;
1832                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1833                    nmsg.obj = msg.obj;
1834                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1835                    return;
1836                }
1837                ProcessRecord app = (ProcessRecord)msg.obj;
1838                synchronized (ActivityManagerService.this) {
1839                    processStartTimedOutLocked(app);
1840                }
1841            } break;
1842            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1843                ProcessRecord app = (ProcessRecord)msg.obj;
1844                synchronized (ActivityManagerService.this) {
1845                    processContentProviderPublishTimedOutLocked(app);
1846                }
1847            } break;
1848            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1849                synchronized (ActivityManagerService.this) {
1850                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1851                }
1852            } break;
1853            case KILL_APPLICATION_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    final int appId = msg.arg1;
1856                    final int userId = msg.arg2;
1857                    Bundle bundle = (Bundle)msg.obj;
1858                    String pkg = bundle.getString("pkg");
1859                    String reason = bundle.getString("reason");
1860                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1861                            false, userId, reason);
1862                }
1863            } break;
1864            case FINALIZE_PENDING_INTENT_MSG: {
1865                ((PendingIntentRecord)msg.obj).completeFinalize();
1866            } break;
1867            case POST_HEAVY_NOTIFICATION_MSG: {
1868                INotificationManager inm = NotificationManager.getService();
1869                if (inm == null) {
1870                    return;
1871                }
1872
1873                ActivityRecord root = (ActivityRecord)msg.obj;
1874                ProcessRecord process = root.app;
1875                if (process == null) {
1876                    return;
1877                }
1878
1879                try {
1880                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1881                    String text = mContext.getString(R.string.heavy_weight_notification,
1882                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1883                    Notification notification = new Notification.Builder(context)
1884                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1885                            .setWhen(0)
1886                            .setOngoing(true)
1887                            .setTicker(text)
1888                            .setColor(mContext.getColor(
1889                                    com.android.internal.R.color.system_notification_accent_color))
1890                            .setContentTitle(text)
1891                            .setContentText(
1892                                    mContext.getText(R.string.heavy_weight_notification_detail))
1893                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1894                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1895                                    new UserHandle(root.userId)))
1896                            .build();
1897                    try {
1898                        int[] outId = new int[1];
1899                        inm.enqueueNotificationWithTag("android", "android", null,
1900                                R.string.heavy_weight_notification,
1901                                notification, outId, root.userId);
1902                    } catch (RuntimeException e) {
1903                        Slog.w(ActivityManagerService.TAG,
1904                                "Error showing notification for heavy-weight app", e);
1905                    } catch (RemoteException e) {
1906                    }
1907                } catch (NameNotFoundException e) {
1908                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1909                }
1910            } break;
1911            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1912                INotificationManager inm = NotificationManager.getService();
1913                if (inm == null) {
1914                    return;
1915                }
1916                try {
1917                    inm.cancelNotificationWithTag("android", null,
1918                            R.string.heavy_weight_notification,  msg.arg1);
1919                } catch (RuntimeException e) {
1920                    Slog.w(ActivityManagerService.TAG,
1921                            "Error canceling notification for service", e);
1922                } catch (RemoteException e) {
1923                }
1924            } break;
1925            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1926                synchronized (ActivityManagerService.this) {
1927                    checkExcessivePowerUsageLocked(true);
1928                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1929                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1930                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1931                }
1932            } break;
1933            case REPORT_MEM_USAGE_MSG: {
1934                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1935                Thread thread = new Thread() {
1936                    @Override public void run() {
1937                        reportMemUsage(memInfos);
1938                    }
1939                };
1940                thread.start();
1941                break;
1942            }
1943            case REPORT_USER_SWITCH_MSG: {
1944                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1945                break;
1946            }
1947            case CONTINUE_USER_SWITCH_MSG: {
1948                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949                break;
1950            }
1951            case USER_SWITCH_TIMEOUT_MSG: {
1952                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1953                break;
1954            }
1955            case IMMERSIVE_MODE_LOCK_MSG: {
1956                final boolean nextState = (msg.arg1 != 0);
1957                if (mUpdateLock.isHeld() != nextState) {
1958                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1959                            "Applying new update lock state '" + nextState
1960                            + "' for " + (ActivityRecord)msg.obj);
1961                    if (nextState) {
1962                        mUpdateLock.acquire();
1963                    } else {
1964                        mUpdateLock.release();
1965                    }
1966                }
1967                break;
1968            }
1969            case PERSIST_URI_GRANTS_MSG: {
1970                writeGrantedUriPermissions();
1971                break;
1972            }
1973            case REQUEST_ALL_PSS_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1976                }
1977                break;
1978            }
1979            case START_PROFILES_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    mUserController.startProfilesLocked();
1982                }
1983                break;
1984            }
1985            case UPDATE_TIME: {
1986                synchronized (ActivityManagerService.this) {
1987                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988                        ProcessRecord r = mLruProcesses.get(i);
1989                        if (r.thread != null) {
1990                            try {
1991                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1992                            } catch (RemoteException ex) {
1993                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1994                            }
1995                        }
1996                    }
1997                }
1998                break;
1999            }
2000            case SYSTEM_USER_START_MSG: {
2001                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2002                        Integer.toString(msg.arg1), msg.arg1);
2003                mSystemServiceManager.startUser(msg.arg1);
2004                break;
2005            }
2006            case SYSTEM_USER_UNLOCK_MSG: {
2007                final int userId = msg.arg1;
2008                mSystemServiceManager.unlockUser(userId);
2009                synchronized (ActivityManagerService.this) {
2010                    mRecentTasks.loadUserRecentsLocked(userId);
2011                }
2012                if (userId == UserHandle.USER_SYSTEM) {
2013                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2014                }
2015                installEncryptionUnawareProviders(userId);
2016                mUserController.finishUserUnlocked((UserState) msg.obj);
2017                break;
2018            }
2019            case SYSTEM_USER_CURRENT_MSG: {
2020                mBatteryStatsService.noteEvent(
2021                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2022                        Integer.toString(msg.arg2), msg.arg2);
2023                mBatteryStatsService.noteEvent(
2024                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2025                        Integer.toString(msg.arg1), msg.arg1);
2026                mSystemServiceManager.switchUser(msg.arg1);
2027                break;
2028            }
2029            case ENTER_ANIMATION_COMPLETE_MSG: {
2030                synchronized (ActivityManagerService.this) {
2031                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2032                    if (r != null && r.app != null && r.app.thread != null) {
2033                        try {
2034                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2035                        } catch (RemoteException e) {
2036                        }
2037                    }
2038                }
2039                break;
2040            }
2041            case FINISH_BOOTING_MSG: {
2042                if (msg.arg1 != 0) {
2043                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2044                    finishBooting();
2045                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2046                }
2047                if (msg.arg2 != 0) {
2048                    enableScreenAfterBoot();
2049                }
2050                break;
2051            }
2052            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2053                try {
2054                    Locale l = (Locale) msg.obj;
2055                    IBinder service = ServiceManager.getService("mount");
2056                    IMountService mountService = IMountService.Stub.asInterface(service);
2057                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2058                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2059                } catch (RemoteException e) {
2060                    Log.e(TAG, "Error storing locale for decryption UI", e);
2061                }
2062                break;
2063            }
2064            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2107                synchronized (ActivityManagerService.this) {
2108                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                        try {
2110                            // Make a one-way callback to the listener
2111                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2112                        } catch (RemoteException e){
2113                            // Handled by the RemoteCallbackList
2114                        }
2115                    }
2116                    mTaskStackListeners.finishBroadcast();
2117                }
2118                break;
2119            }
2120            case NOTIFY_FORCED_RESIZABLE_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2123                        try {
2124                            // Make a one-way callback to the listener
2125                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2126                                    (String) msg.obj, msg.arg1);
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2136                    synchronized (ActivityManagerService.this) {
2137                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                            try {
2139                                // Make a one-way callback to the listener
2140                                mTaskStackListeners.getBroadcastItem(i)
2141                                        .onActivityDismissingDockedStack();
2142                            } catch (RemoteException e){
2143                                // Handled by the RemoteCallbackList
2144                            }
2145                        }
2146                        mTaskStackListeners.finishBroadcast();
2147                    }
2148                    break;
2149                }
2150            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2151                final int uid = msg.arg1;
2152                final byte[] firstPacket = (byte[]) msg.obj;
2153
2154                synchronized (mPidsSelfLocked) {
2155                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2156                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2157                        if (p.uid == uid) {
2158                            try {
2159                                p.thread.notifyCleartextNetwork(firstPacket);
2160                            } catch (RemoteException ignored) {
2161                            }
2162                        }
2163                    }
2164                }
2165                break;
2166            }
2167            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2168                final String procName;
2169                final int uid;
2170                final long memLimit;
2171                final String reportPackage;
2172                synchronized (ActivityManagerService.this) {
2173                    procName = mMemWatchDumpProcName;
2174                    uid = mMemWatchDumpUid;
2175                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2176                    if (val == null) {
2177                        val = mMemWatchProcesses.get(procName, 0);
2178                    }
2179                    if (val != null) {
2180                        memLimit = val.first;
2181                        reportPackage = val.second;
2182                    } else {
2183                        memLimit = 0;
2184                        reportPackage = null;
2185                    }
2186                }
2187                if (procName == null) {
2188                    return;
2189                }
2190
2191                if (DEBUG_PSS) Slog.d(TAG_PSS,
2192                        "Showing dump heap notification from " + procName + "/" + uid);
2193
2194                INotificationManager inm = NotificationManager.getService();
2195                if (inm == null) {
2196                    return;
2197                }
2198
2199                String text = mContext.getString(R.string.dump_heap_notification, procName);
2200
2201
2202                Intent deleteIntent = new Intent();
2203                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2204                Intent intent = new Intent();
2205                intent.setClassName("android", DumpHeapActivity.class.getName());
2206                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2207                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2208                if (reportPackage != null) {
2209                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2210                }
2211                int userId = UserHandle.getUserId(uid);
2212                Notification notification = new Notification.Builder(mContext)
2213                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2214                        .setWhen(0)
2215                        .setOngoing(true)
2216                        .setAutoCancel(true)
2217                        .setTicker(text)
2218                        .setColor(mContext.getColor(
2219                                com.android.internal.R.color.system_notification_accent_color))
2220                        .setContentTitle(text)
2221                        .setContentText(
2222                                mContext.getText(R.string.dump_heap_notification_detail))
2223                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2224                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2225                                new UserHandle(userId)))
2226                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2227                                deleteIntent, 0, UserHandle.SYSTEM))
2228                        .build();
2229
2230                try {
2231                    int[] outId = new int[1];
2232                    inm.enqueueNotificationWithTag("android", "android", null,
2233                            R.string.dump_heap_notification,
2234                            notification, outId, userId);
2235                } catch (RuntimeException e) {
2236                    Slog.w(ActivityManagerService.TAG,
2237                            "Error showing notification for dump heap", e);
2238                } catch (RemoteException e) {
2239                }
2240            } break;
2241            case DELETE_DUMPHEAP_MSG: {
2242                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2243                        DumpHeapActivity.JAVA_URI,
2244                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2245                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2246                        UserHandle.myUserId());
2247                synchronized (ActivityManagerService.this) {
2248                    mMemWatchDumpFile = null;
2249                    mMemWatchDumpProcName = null;
2250                    mMemWatchDumpPid = -1;
2251                    mMemWatchDumpUid = -1;
2252                }
2253            } break;
2254            case FOREGROUND_PROFILE_CHANGED_MSG: {
2255                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2256            } break;
2257            case REPORT_TIME_TRACKER_MSG: {
2258                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2259                tracker.deliverResult(mContext);
2260            } break;
2261            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2262                mUserController.dispatchUserSwitchComplete(msg.arg1);
2263            } break;
2264            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2265                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2266                try {
2267                    connection.shutdown();
2268                } catch (RemoteException e) {
2269                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2270                }
2271                // Only a UiAutomation can set this flag and now that
2272                // it is finished we make sure it is reset to its default.
2273                mUserIsMonkey = false;
2274            } break;
2275            case APP_BOOST_DEACTIVATE_MSG: {
2276                synchronized(ActivityManagerService.this) {
2277                    if (mIsBoosted) {
2278                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2279                            nativeMigrateFromBoost();
2280                            mIsBoosted = false;
2281                            mBoostStartTime = 0;
2282                        } else {
2283                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2284                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2285                        }
2286                    }
2287                }
2288            } break;
2289            case IDLE_UIDS_MSG: {
2290                idleUids();
2291            } break;
2292            case LOG_STACK_STATE: {
2293                synchronized (ActivityManagerService.this) {
2294                    mStackSupervisor.logStackState();
2295                }
2296            } break;
2297            case VR_MODE_CHANGE_MSG: {
2298                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2299                final ActivityRecord r = (ActivityRecord) msg.obj;
2300                boolean vrMode;
2301                ComponentName requestedPackage;
2302                ComponentName callingPackage;
2303                int userId;
2304                synchronized (ActivityManagerService.this) {
2305                    vrMode = r.requestedVrComponent != null;
2306                    requestedPackage = r.requestedVrComponent;
2307                    userId = r.userId;
2308                    callingPackage = r.info.getComponentName();
2309                    if (mInVrMode != vrMode) {
2310                        mInVrMode = vrMode;
2311                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2312                    }
2313                }
2314                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2315            } break;
2316            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2317                final ActivityRecord r = (ActivityRecord) msg.obj;
2318                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2319                if (needsVrMode) {
2320                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2321                            r.info.getComponentName(), false);
2322                }
2323            } break;
2324            }
2325        }
2326    };
2327
2328    static final int COLLECT_PSS_BG_MSG = 1;
2329
2330    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2331        @Override
2332        public void handleMessage(Message msg) {
2333            switch (msg.what) {
2334            case COLLECT_PSS_BG_MSG: {
2335                long start = SystemClock.uptimeMillis();
2336                MemInfoReader memInfo = null;
2337                synchronized (ActivityManagerService.this) {
2338                    if (mFullPssPending) {
2339                        mFullPssPending = false;
2340                        memInfo = new MemInfoReader();
2341                    }
2342                }
2343                if (memInfo != null) {
2344                    updateCpuStatsNow();
2345                    long nativeTotalPss = 0;
2346                    synchronized (mProcessCpuTracker) {
2347                        final int N = mProcessCpuTracker.countStats();
2348                        for (int j=0; j<N; j++) {
2349                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2350                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2351                                // This is definitely an application process; skip it.
2352                                continue;
2353                            }
2354                            synchronized (mPidsSelfLocked) {
2355                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2356                                    // This is one of our own processes; skip it.
2357                                    continue;
2358                                }
2359                            }
2360                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2361                        }
2362                    }
2363                    memInfo.readMemInfo();
2364                    synchronized (ActivityManagerService.this) {
2365                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2366                                + (SystemClock.uptimeMillis()-start) + "ms");
2367                        final long cachedKb = memInfo.getCachedSizeKb();
2368                        final long freeKb = memInfo.getFreeSizeKb();
2369                        final long zramKb = memInfo.getZramTotalSizeKb();
2370                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2371                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2372                                kernelKb*1024, nativeTotalPss*1024);
2373                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2374                                nativeTotalPss);
2375                    }
2376                }
2377
2378                int num = 0;
2379                long[] tmp = new long[2];
2380                do {
2381                    ProcessRecord proc;
2382                    int procState;
2383                    int pid;
2384                    long lastPssTime;
2385                    synchronized (ActivityManagerService.this) {
2386                        if (mPendingPssProcesses.size() <= 0) {
2387                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2388                                    "Collected PSS of " + num + " processes in "
2389                                    + (SystemClock.uptimeMillis() - start) + "ms");
2390                            mPendingPssProcesses.clear();
2391                            return;
2392                        }
2393                        proc = mPendingPssProcesses.remove(0);
2394                        procState = proc.pssProcState;
2395                        lastPssTime = proc.lastPssTime;
2396                        if (proc.thread != null && procState == proc.setProcState
2397                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2398                                        < SystemClock.uptimeMillis()) {
2399                            pid = proc.pid;
2400                        } else {
2401                            proc = null;
2402                            pid = 0;
2403                        }
2404                    }
2405                    if (proc != null) {
2406                        long pss = Debug.getPss(pid, tmp, null);
2407                        synchronized (ActivityManagerService.this) {
2408                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2409                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2410                                num++;
2411                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2412                                        SystemClock.uptimeMillis());
2413                            }
2414                        }
2415                    }
2416                } while (true);
2417            }
2418            }
2419        }
2420    };
2421
2422    public void setSystemProcess() {
2423        try {
2424            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2425            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2426            ServiceManager.addService("meminfo", new MemBinder(this));
2427            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2428            ServiceManager.addService("dbinfo", new DbBinder(this));
2429            if (MONITOR_CPU_USAGE) {
2430                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2431            }
2432            ServiceManager.addService("permission", new PermissionController(this));
2433            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2434
2435            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2436                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2437            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2438
2439            synchronized (this) {
2440                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2441                app.persistent = true;
2442                app.pid = MY_PID;
2443                app.maxAdj = ProcessList.SYSTEM_ADJ;
2444                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2445                synchronized (mPidsSelfLocked) {
2446                    mPidsSelfLocked.put(app.pid, app);
2447                }
2448                updateLruProcessLocked(app, false, null);
2449                updateOomAdjLocked();
2450            }
2451        } catch (PackageManager.NameNotFoundException e) {
2452            throw new RuntimeException(
2453                    "Unable to find android system package", e);
2454        }
2455    }
2456
2457    public void setWindowManager(WindowManagerService wm) {
2458        mWindowManager = wm;
2459        mStackSupervisor.setWindowManager(wm);
2460        mActivityStarter.setWindowManager(wm);
2461    }
2462
2463    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2464        mUsageStatsService = usageStatsManager;
2465    }
2466
2467    public void startObservingNativeCrashes() {
2468        final NativeCrashListener ncl = new NativeCrashListener(this);
2469        ncl.start();
2470    }
2471
2472    public IAppOpsService getAppOpsService() {
2473        return mAppOpsService;
2474    }
2475
2476    static class MemBinder extends Binder {
2477        ActivityManagerService mActivityManagerService;
2478        MemBinder(ActivityManagerService activityManagerService) {
2479            mActivityManagerService = activityManagerService;
2480        }
2481
2482        @Override
2483        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2484            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2485                    != PackageManager.PERMISSION_GRANTED) {
2486                pw.println("Permission Denial: can't dump meminfo from from pid="
2487                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2488                        + " without permission " + android.Manifest.permission.DUMP);
2489                return;
2490            }
2491
2492            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2493        }
2494    }
2495
2496    static class GraphicsBinder extends Binder {
2497        ActivityManagerService mActivityManagerService;
2498        GraphicsBinder(ActivityManagerService activityManagerService) {
2499            mActivityManagerService = activityManagerService;
2500        }
2501
2502        @Override
2503        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2504            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2505                    != PackageManager.PERMISSION_GRANTED) {
2506                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2507                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2508                        + " without permission " + android.Manifest.permission.DUMP);
2509                return;
2510            }
2511
2512            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2513        }
2514    }
2515
2516    static class DbBinder extends Binder {
2517        ActivityManagerService mActivityManagerService;
2518        DbBinder(ActivityManagerService activityManagerService) {
2519            mActivityManagerService = activityManagerService;
2520        }
2521
2522        @Override
2523        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2524            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2525                    != PackageManager.PERMISSION_GRANTED) {
2526                pw.println("Permission Denial: can't dump dbinfo from from pid="
2527                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2528                        + " without permission " + android.Manifest.permission.DUMP);
2529                return;
2530            }
2531
2532            mActivityManagerService.dumpDbInfo(fd, pw, args);
2533        }
2534    }
2535
2536    static class CpuBinder extends Binder {
2537        ActivityManagerService mActivityManagerService;
2538        CpuBinder(ActivityManagerService activityManagerService) {
2539            mActivityManagerService = activityManagerService;
2540        }
2541
2542        @Override
2543        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2544            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2545                    != PackageManager.PERMISSION_GRANTED) {
2546                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2547                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2548                        + " without permission " + android.Manifest.permission.DUMP);
2549                return;
2550            }
2551
2552            synchronized (mActivityManagerService.mProcessCpuTracker) {
2553                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2554                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2555                        SystemClock.uptimeMillis()));
2556            }
2557        }
2558    }
2559
2560    public static final class Lifecycle extends SystemService {
2561        private final ActivityManagerService mService;
2562
2563        public Lifecycle(Context context) {
2564            super(context);
2565            mService = new ActivityManagerService(context);
2566        }
2567
2568        @Override
2569        public void onStart() {
2570            mService.start();
2571        }
2572
2573        public ActivityManagerService getService() {
2574            return mService;
2575        }
2576    }
2577
2578    // Note: This method is invoked on the main thread but may need to attach various
2579    // handlers to other threads.  So take care to be explicit about the looper.
2580    public ActivityManagerService(Context systemContext) {
2581        mContext = systemContext;
2582        mFactoryTest = FactoryTest.getMode();
2583        mSystemThread = ActivityThread.currentActivityThread();
2584
2585        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2586
2587        mHandlerThread = new ServiceThread(TAG,
2588                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2589        mHandlerThread.start();
2590        mHandler = new MainHandler(mHandlerThread.getLooper());
2591        mUiHandler = new UiHandler();
2592
2593        /* static; one-time init here */
2594        if (sKillHandler == null) {
2595            sKillThread = new ServiceThread(TAG + ":kill",
2596                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2597            sKillThread.start();
2598            sKillHandler = new KillHandler(sKillThread.getLooper());
2599        }
2600
2601        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2602                "foreground", BROADCAST_FG_TIMEOUT, false);
2603        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                "background", BROADCAST_BG_TIMEOUT, true);
2605        mBroadcastQueues[0] = mFgBroadcastQueue;
2606        mBroadcastQueues[1] = mBgBroadcastQueue;
2607
2608        mServices = new ActiveServices(this);
2609        mProviderMap = new ProviderMap(this);
2610        mAppErrors = new AppErrors(mContext, this);
2611
2612        // TODO: Move creation of battery stats service outside of activity manager service.
2613        File dataDir = Environment.getDataDirectory();
2614        File systemDir = new File(dataDir, "system");
2615        systemDir.mkdirs();
2616        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2617        mBatteryStatsService.getActiveStatistics().readLocked();
2618        mBatteryStatsService.scheduleWriteToDisk();
2619        mOnBattery = DEBUG_POWER ? true
2620                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2621        mBatteryStatsService.getActiveStatistics().setCallback(this);
2622
2623        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2624
2625        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2626        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2627                new IAppOpsCallback.Stub() {
2628                    @Override public void opChanged(int op, int uid, String packageName) {
2629                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2630                            if (mAppOpsService.checkOperation(op, uid, packageName)
2631                                    != AppOpsManager.MODE_ALLOWED) {
2632                                runInBackgroundDisabled(uid);
2633                            }
2634                        }
2635                    }
2636                });
2637
2638        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2639
2640        mUserController = new UserController(this);
2641
2642        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2643            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2644
2645        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2646
2647        mConfiguration.setToDefaults();
2648        mConfiguration.setLocales(LocaleList.getDefault());
2649
2650        mConfigurationSeq = mConfiguration.seq = 1;
2651        mProcessCpuTracker.init();
2652
2653        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2654        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2655        mStackSupervisor = new ActivityStackSupervisor(this);
2656        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2657        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2658
2659        mProcessCpuThread = new Thread("CpuTracker") {
2660            @Override
2661            public void run() {
2662                while (true) {
2663                    try {
2664                        try {
2665                            synchronized(this) {
2666                                final long now = SystemClock.uptimeMillis();
2667                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2668                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2669                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2670                                //        + ", write delay=" + nextWriteDelay);
2671                                if (nextWriteDelay < nextCpuDelay) {
2672                                    nextCpuDelay = nextWriteDelay;
2673                                }
2674                                if (nextCpuDelay > 0) {
2675                                    mProcessCpuMutexFree.set(true);
2676                                    this.wait(nextCpuDelay);
2677                                }
2678                            }
2679                        } catch (InterruptedException e) {
2680                        }
2681                        updateCpuStatsNow();
2682                    } catch (Exception e) {
2683                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2684                    }
2685                }
2686            }
2687        };
2688
2689        Watchdog.getInstance().addMonitor(this);
2690        Watchdog.getInstance().addThread(mHandler);
2691    }
2692
2693    public void setSystemServiceManager(SystemServiceManager mgr) {
2694        mSystemServiceManager = mgr;
2695    }
2696
2697    public void setInstaller(Installer installer) {
2698        mInstaller = installer;
2699    }
2700
2701    private void start() {
2702        Process.removeAllProcessGroups();
2703        mProcessCpuThread.start();
2704
2705        mBatteryStatsService.publish(mContext);
2706        mAppOpsService.publish(mContext);
2707        Slog.d("AppOps", "AppOpsService published");
2708        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2709    }
2710
2711    void onUserStoppedLocked(int userId) {
2712        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2713    }
2714
2715    public void initPowerManagement() {
2716        mStackSupervisor.initPowerManagement();
2717        mBatteryStatsService.initPowerManagement();
2718        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2719        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2720        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2721        mVoiceWakeLock.setReferenceCounted(false);
2722    }
2723
2724    @Override
2725    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2726            throws RemoteException {
2727        if (code == SYSPROPS_TRANSACTION) {
2728            // We need to tell all apps about the system property change.
2729            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2730            synchronized(this) {
2731                final int NP = mProcessNames.getMap().size();
2732                for (int ip=0; ip<NP; ip++) {
2733                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2734                    final int NA = apps.size();
2735                    for (int ia=0; ia<NA; ia++) {
2736                        ProcessRecord app = apps.valueAt(ia);
2737                        if (app.thread != null) {
2738                            procs.add(app.thread.asBinder());
2739                        }
2740                    }
2741                }
2742            }
2743
2744            int N = procs.size();
2745            for (int i=0; i<N; i++) {
2746                Parcel data2 = Parcel.obtain();
2747                try {
2748                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2749                } catch (RemoteException e) {
2750                }
2751                data2.recycle();
2752            }
2753        }
2754        try {
2755            return super.onTransact(code, data, reply, flags);
2756        } catch (RuntimeException e) {
2757            // The activity manager only throws security exceptions, so let's
2758            // log all others.
2759            if (!(e instanceof SecurityException)) {
2760                Slog.wtf(TAG, "Activity Manager Crash", e);
2761            }
2762            throw e;
2763        }
2764    }
2765
2766    void updateCpuStats() {
2767        final long now = SystemClock.uptimeMillis();
2768        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2769            return;
2770        }
2771        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2772            synchronized (mProcessCpuThread) {
2773                mProcessCpuThread.notify();
2774            }
2775        }
2776    }
2777
2778    void updateCpuStatsNow() {
2779        synchronized (mProcessCpuTracker) {
2780            mProcessCpuMutexFree.set(false);
2781            final long now = SystemClock.uptimeMillis();
2782            boolean haveNewCpuStats = false;
2783
2784            if (MONITOR_CPU_USAGE &&
2785                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2786                mLastCpuTime.set(now);
2787                mProcessCpuTracker.update();
2788                if (mProcessCpuTracker.hasGoodLastStats()) {
2789                    haveNewCpuStats = true;
2790                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2791                    //Slog.i(TAG, "Total CPU usage: "
2792                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2793
2794                    // Slog the cpu usage if the property is set.
2795                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2796                        int user = mProcessCpuTracker.getLastUserTime();
2797                        int system = mProcessCpuTracker.getLastSystemTime();
2798                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2799                        int irq = mProcessCpuTracker.getLastIrqTime();
2800                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2801                        int idle = mProcessCpuTracker.getLastIdleTime();
2802
2803                        int total = user + system + iowait + irq + softIrq + idle;
2804                        if (total == 0) total = 1;
2805
2806                        EventLog.writeEvent(EventLogTags.CPU,
2807                                ((user+system+iowait+irq+softIrq) * 100) / total,
2808                                (user * 100) / total,
2809                                (system * 100) / total,
2810                                (iowait * 100) / total,
2811                                (irq * 100) / total,
2812                                (softIrq * 100) / total);
2813                    }
2814                }
2815            }
2816
2817            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2818            synchronized(bstats) {
2819                synchronized(mPidsSelfLocked) {
2820                    if (haveNewCpuStats) {
2821                        if (bstats.startAddingCpuLocked()) {
2822                            int totalUTime = 0;
2823                            int totalSTime = 0;
2824                            final int N = mProcessCpuTracker.countStats();
2825                            for (int i=0; i<N; i++) {
2826                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2827                                if (!st.working) {
2828                                    continue;
2829                                }
2830                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2831                                totalUTime += st.rel_utime;
2832                                totalSTime += st.rel_stime;
2833                                if (pr != null) {
2834                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2835                                    if (ps == null || !ps.isActive()) {
2836                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2837                                                pr.info.uid, pr.processName);
2838                                    }
2839                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2840                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2841                                } else {
2842                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2843                                    if (ps == null || !ps.isActive()) {
2844                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2845                                                bstats.mapUid(st.uid), st.name);
2846                                    }
2847                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2848                                }
2849                            }
2850                            final int userTime = mProcessCpuTracker.getLastUserTime();
2851                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2852                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2853                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2854                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2855                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2856                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2857                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2858                        }
2859                    }
2860                }
2861
2862                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2863                    mLastWriteTime = now;
2864                    mBatteryStatsService.scheduleWriteToDisk();
2865                }
2866            }
2867        }
2868    }
2869
2870    @Override
2871    public void batteryNeedsCpuUpdate() {
2872        updateCpuStatsNow();
2873    }
2874
2875    @Override
2876    public void batteryPowerChanged(boolean onBattery) {
2877        // When plugging in, update the CPU stats first before changing
2878        // the plug state.
2879        updateCpuStatsNow();
2880        synchronized (this) {
2881            synchronized(mPidsSelfLocked) {
2882                mOnBattery = DEBUG_POWER ? true : onBattery;
2883            }
2884        }
2885    }
2886
2887    @Override
2888    public void batterySendBroadcast(Intent intent) {
2889        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2890                AppOpsManager.OP_NONE, null, false, false,
2891                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2892    }
2893
2894    /**
2895     * Initialize the application bind args. These are passed to each
2896     * process when the bindApplication() IPC is sent to the process. They're
2897     * lazily setup to make sure the services are running when they're asked for.
2898     */
2899    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2900        if (mAppBindArgs == null) {
2901            mAppBindArgs = new HashMap<>();
2902
2903            // Isolated processes won't get this optimization, so that we don't
2904            // violate the rules about which services they have access to.
2905            if (!isolated) {
2906                // Setup the application init args
2907                mAppBindArgs.put("package", ServiceManager.getService("package"));
2908                mAppBindArgs.put("window", ServiceManager.getService("window"));
2909                mAppBindArgs.put(Context.ALARM_SERVICE,
2910                        ServiceManager.getService(Context.ALARM_SERVICE));
2911            }
2912        }
2913        return mAppBindArgs;
2914    }
2915
2916    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2917        if (r == null || mFocusedActivity == r) {
2918            return false;
2919        }
2920
2921        if (!r.isFocusable()) {
2922            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2923            return false;
2924        }
2925
2926        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2927
2928        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2929        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2930                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2931        mDoingSetFocusedActivity = true;
2932
2933        final ActivityRecord last = mFocusedActivity;
2934        mFocusedActivity = r;
2935        if (r.task.isApplicationTask()) {
2936            if (mCurAppTimeTracker != r.appTimeTracker) {
2937                // We are switching app tracking.  Complete the current one.
2938                if (mCurAppTimeTracker != null) {
2939                    mCurAppTimeTracker.stop();
2940                    mHandler.obtainMessage(
2941                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2942                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2943                    mCurAppTimeTracker = null;
2944                }
2945                if (r.appTimeTracker != null) {
2946                    mCurAppTimeTracker = r.appTimeTracker;
2947                    startTimeTrackingFocusedActivityLocked();
2948                }
2949            } else {
2950                startTimeTrackingFocusedActivityLocked();
2951            }
2952        } else {
2953            r.appTimeTracker = null;
2954        }
2955        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2956        // TODO: Probably not, because we don't want to resume voice on switching
2957        // back to this activity
2958        if (r.task.voiceInteractor != null) {
2959            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2960        } else {
2961            finishRunningVoiceLocked();
2962            IVoiceInteractionSession session;
2963            if (last != null && ((session = last.task.voiceSession) != null
2964                    || (session = last.voiceSession) != null)) {
2965                // We had been in a voice interaction session, but now focused has
2966                // move to something different.  Just finish the session, we can't
2967                // return to it and retain the proper state and synchronization with
2968                // the voice interaction service.
2969                finishVoiceTask(session);
2970            }
2971        }
2972        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2973            mWindowManager.setFocusedApp(r.appToken, true);
2974        }
2975        applyUpdateLockStateLocked(r);
2976        applyUpdateVrModeLocked(r);
2977        if (mFocusedActivity.userId != mLastFocusedUserId) {
2978            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2979            mHandler.obtainMessage(
2980                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2981            mLastFocusedUserId = mFocusedActivity.userId;
2982        }
2983
2984        // Log a warning if the focused app is changed during the process. This could
2985        // indicate a problem of the focus setting logic!
2986        if (mFocusedActivity != r) Slog.w(TAG,
2987                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2988        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2989
2990        EventLogTags.writeAmFocusedActivity(
2991                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2992                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2993                reason);
2994        return true;
2995    }
2996
2997    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2998        if (mFocusedActivity != goingAway) {
2999            return;
3000        }
3001
3002        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3003        if (focusedStack != null) {
3004            final ActivityRecord top = focusedStack.topActivity();
3005            if (top != null && top.userId != mLastFocusedUserId) {
3006                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3007                mHandler.sendMessage(
3008                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3009                mLastFocusedUserId = top.userId;
3010            }
3011        }
3012
3013        // Try to move focus to another activity if possible.
3014        if (setFocusedActivityLocked(
3015                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3016            return;
3017        }
3018
3019        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3020                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3021        mFocusedActivity = null;
3022        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3023    }
3024
3025    @Override
3026    public void setFocusedStack(int stackId) {
3027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3028        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3029        final long callingId = Binder.clearCallingIdentity();
3030        try {
3031            synchronized (this) {
3032                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3033                if (stack == null) {
3034                    return;
3035                }
3036                final ActivityRecord r = stack.topRunningActivityLocked();
3037                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3038                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3039                }
3040            }
3041        } finally {
3042            Binder.restoreCallingIdentity(callingId);
3043        }
3044    }
3045
3046    @Override
3047    public void setFocusedTask(int taskId) {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3049        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3050        final long callingId = Binder.clearCallingIdentity();
3051        try {
3052            synchronized (this) {
3053                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3054                if (task == null) {
3055                    return;
3056                }
3057                final ActivityRecord r = task.topRunningActivityLocked();
3058                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3059                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3060                }
3061            }
3062        } finally {
3063            Binder.restoreCallingIdentity(callingId);
3064        }
3065    }
3066
3067    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3068    @Override
3069    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3071        synchronized (this) {
3072            if (listener != null) {
3073                mTaskStackListeners.register(listener);
3074            }
3075        }
3076    }
3077
3078    @Override
3079    public void notifyActivityDrawn(IBinder token) {
3080        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3081        synchronized (this) {
3082            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3083            if (r != null) {
3084                r.task.stack.notifyActivityDrawnLocked(r);
3085            }
3086        }
3087    }
3088
3089    final void applyUpdateLockStateLocked(ActivityRecord r) {
3090        // Modifications to the UpdateLock state are done on our handler, outside
3091        // the activity manager's locks.  The new state is determined based on the
3092        // state *now* of the relevant activity record.  The object is passed to
3093        // the handler solely for logging detail, not to be consulted/modified.
3094        final boolean nextState = r != null && r.immersive;
3095        mHandler.sendMessage(
3096                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3097    }
3098
3099    final void applyUpdateVrModeLocked(ActivityRecord r) {
3100        mHandler.sendMessage(
3101                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3102    }
3103
3104    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3105        mHandler.sendMessage(
3106                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3107    }
3108
3109    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3110            ComponentName callingPackage, boolean immediate) {
3111        VrManagerInternal vrService =
3112                LocalServices.getService(VrManagerInternal.class);
3113        if (immediate) {
3114            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3115        } else {
3116            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3117        }
3118    }
3119
3120    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3121        Message msg = Message.obtain();
3122        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3123        msg.obj = r.task.askedCompatMode ? null : r;
3124        mUiHandler.sendMessage(msg);
3125    }
3126
3127    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3128        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3129                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3130            final Message msg = Message.obtain();
3131            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3132            msg.obj = r;
3133            mUiHandler.sendMessage(msg);
3134        }
3135    }
3136
3137    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3138            String what, Object obj, ProcessRecord srcApp) {
3139        app.lastActivityTime = now;
3140
3141        if (app.activities.size() > 0) {
3142            // Don't want to touch dependent processes that are hosting activities.
3143            return index;
3144        }
3145
3146        int lrui = mLruProcesses.lastIndexOf(app);
3147        if (lrui < 0) {
3148            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3149                    + what + " " + obj + " from " + srcApp);
3150            return index;
3151        }
3152
3153        if (lrui >= index) {
3154            // Don't want to cause this to move dependent processes *back* in the
3155            // list as if they were less frequently used.
3156            return index;
3157        }
3158
3159        if (lrui >= mLruProcessActivityStart) {
3160            // Don't want to touch dependent processes that are hosting activities.
3161            return index;
3162        }
3163
3164        mLruProcesses.remove(lrui);
3165        if (index > 0) {
3166            index--;
3167        }
3168        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3169                + " in LRU list: " + app);
3170        mLruProcesses.add(index, app);
3171        return index;
3172    }
3173
3174    static void killProcessGroup(int uid, int pid) {
3175        if (sKillHandler != null) {
3176            sKillHandler.sendMessage(
3177                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3178        } else {
3179            Slog.w(TAG, "Asked to kill process group before system bringup!");
3180            Process.killProcessGroup(uid, pid);
3181        }
3182    }
3183
3184    final void removeLruProcessLocked(ProcessRecord app) {
3185        int lrui = mLruProcesses.lastIndexOf(app);
3186        if (lrui >= 0) {
3187            if (!app.killed) {
3188                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3189                Process.killProcessQuiet(app.pid);
3190                killProcessGroup(app.uid, app.pid);
3191            }
3192            if (lrui <= mLruProcessActivityStart) {
3193                mLruProcessActivityStart--;
3194            }
3195            if (lrui <= mLruProcessServiceStart) {
3196                mLruProcessServiceStart--;
3197            }
3198            mLruProcesses.remove(lrui);
3199        }
3200    }
3201
3202    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3203            ProcessRecord client) {
3204        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3205                || app.treatLikeActivity;
3206        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3207        if (!activityChange && hasActivity) {
3208            // The process has activities, so we are only allowing activity-based adjustments
3209            // to move it.  It should be kept in the front of the list with other
3210            // processes that have activities, and we don't want those to change their
3211            // order except due to activity operations.
3212            return;
3213        }
3214
3215        mLruSeq++;
3216        final long now = SystemClock.uptimeMillis();
3217        app.lastActivityTime = now;
3218
3219        // First a quick reject: if the app is already at the position we will
3220        // put it, then there is nothing to do.
3221        if (hasActivity) {
3222            final int N = mLruProcesses.size();
3223            if (N > 0 && mLruProcesses.get(N-1) == app) {
3224                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3225                return;
3226            }
3227        } else {
3228            if (mLruProcessServiceStart > 0
3229                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3230                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3231                return;
3232            }
3233        }
3234
3235        int lrui = mLruProcesses.lastIndexOf(app);
3236
3237        if (app.persistent && lrui >= 0) {
3238            // We don't care about the position of persistent processes, as long as
3239            // they are in the list.
3240            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3241            return;
3242        }
3243
3244        /* In progress: compute new position first, so we can avoid doing work
3245           if the process is not actually going to move.  Not yet working.
3246        int addIndex;
3247        int nextIndex;
3248        boolean inActivity = false, inService = false;
3249        if (hasActivity) {
3250            // Process has activities, put it at the very tipsy-top.
3251            addIndex = mLruProcesses.size();
3252            nextIndex = mLruProcessServiceStart;
3253            inActivity = true;
3254        } else if (hasService) {
3255            // Process has services, put it at the top of the service list.
3256            addIndex = mLruProcessActivityStart;
3257            nextIndex = mLruProcessServiceStart;
3258            inActivity = true;
3259            inService = true;
3260        } else  {
3261            // Process not otherwise of interest, it goes to the top of the non-service area.
3262            addIndex = mLruProcessServiceStart;
3263            if (client != null) {
3264                int clientIndex = mLruProcesses.lastIndexOf(client);
3265                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3266                        + app);
3267                if (clientIndex >= 0 && addIndex > clientIndex) {
3268                    addIndex = clientIndex;
3269                }
3270            }
3271            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3272        }
3273
3274        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3275                + mLruProcessActivityStart + "): " + app);
3276        */
3277
3278        if (lrui >= 0) {
3279            if (lrui < mLruProcessActivityStart) {
3280                mLruProcessActivityStart--;
3281            }
3282            if (lrui < mLruProcessServiceStart) {
3283                mLruProcessServiceStart--;
3284            }
3285            /*
3286            if (addIndex > lrui) {
3287                addIndex--;
3288            }
3289            if (nextIndex > lrui) {
3290                nextIndex--;
3291            }
3292            */
3293            mLruProcesses.remove(lrui);
3294        }
3295
3296        /*
3297        mLruProcesses.add(addIndex, app);
3298        if (inActivity) {
3299            mLruProcessActivityStart++;
3300        }
3301        if (inService) {
3302            mLruProcessActivityStart++;
3303        }
3304        */
3305
3306        int nextIndex;
3307        if (hasActivity) {
3308            final int N = mLruProcesses.size();
3309            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3310                // Process doesn't have activities, but has clients with
3311                // activities...  move it up, but one below the top (the top
3312                // should always have a real activity).
3313                if (DEBUG_LRU) Slog.d(TAG_LRU,
3314                        "Adding to second-top of LRU activity list: " + app);
3315                mLruProcesses.add(N - 1, app);
3316                // To keep it from spamming the LRU list (by making a bunch of clients),
3317                // we will push down any other entries owned by the app.
3318                final int uid = app.info.uid;
3319                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3320                    ProcessRecord subProc = mLruProcesses.get(i);
3321                    if (subProc.info.uid == uid) {
3322                        // We want to push this one down the list.  If the process after
3323                        // it is for the same uid, however, don't do so, because we don't
3324                        // want them internally to be re-ordered.
3325                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3326                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3327                                    "Pushing uid " + uid + " swapping at " + i + ": "
3328                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3329                            ProcessRecord tmp = mLruProcesses.get(i);
3330                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3331                            mLruProcesses.set(i - 1, tmp);
3332                            i--;
3333                        }
3334                    } else {
3335                        // A gap, we can stop here.
3336                        break;
3337                    }
3338                }
3339            } else {
3340                // Process has activities, put it at the very tipsy-top.
3341                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3342                mLruProcesses.add(app);
3343            }
3344            nextIndex = mLruProcessServiceStart;
3345        } else if (hasService) {
3346            // Process has services, put it at the top of the service list.
3347            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3348            mLruProcesses.add(mLruProcessActivityStart, app);
3349            nextIndex = mLruProcessServiceStart;
3350            mLruProcessActivityStart++;
3351        } else  {
3352            // Process not otherwise of interest, it goes to the top of the non-service area.
3353            int index = mLruProcessServiceStart;
3354            if (client != null) {
3355                // If there is a client, don't allow the process to be moved up higher
3356                // in the list than that client.
3357                int clientIndex = mLruProcesses.lastIndexOf(client);
3358                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3359                        + " when updating " + app);
3360                if (clientIndex <= lrui) {
3361                    // Don't allow the client index restriction to push it down farther in the
3362                    // list than it already is.
3363                    clientIndex = lrui;
3364                }
3365                if (clientIndex >= 0 && index > clientIndex) {
3366                    index = clientIndex;
3367                }
3368            }
3369            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3370            mLruProcesses.add(index, app);
3371            nextIndex = index-1;
3372            mLruProcessActivityStart++;
3373            mLruProcessServiceStart++;
3374        }
3375
3376        // If the app is currently using a content provider or service,
3377        // bump those processes as well.
3378        for (int j=app.connections.size()-1; j>=0; j--) {
3379            ConnectionRecord cr = app.connections.valueAt(j);
3380            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3381                    && cr.binding.service.app != null
3382                    && cr.binding.service.app.lruSeq != mLruSeq
3383                    && !cr.binding.service.app.persistent) {
3384                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3385                        "service connection", cr, app);
3386            }
3387        }
3388        for (int j=app.conProviders.size()-1; j>=0; j--) {
3389            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3390            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3391                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3392                        "provider reference", cpr, app);
3393            }
3394        }
3395    }
3396
3397    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3398        if (uid == Process.SYSTEM_UID) {
3399            // The system gets to run in any process.  If there are multiple
3400            // processes with the same uid, just pick the first (this
3401            // should never happen).
3402            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3403            if (procs == null) return null;
3404            final int procCount = procs.size();
3405            for (int i = 0; i < procCount; i++) {
3406                final int procUid = procs.keyAt(i);
3407                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3408                    // Don't use an app process or different user process for system component.
3409                    continue;
3410                }
3411                return procs.valueAt(i);
3412            }
3413        }
3414        ProcessRecord proc = mProcessNames.get(processName, uid);
3415        if (false && proc != null && !keepIfLarge
3416                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3417                && proc.lastCachedPss >= 4000) {
3418            // Turn this condition on to cause killing to happen regularly, for testing.
3419            if (proc.baseProcessTracker != null) {
3420                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3421            }
3422            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3423        } else if (proc != null && !keepIfLarge
3424                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3425                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3426            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3427            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3428                if (proc.baseProcessTracker != null) {
3429                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3430                }
3431                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3432            }
3433        }
3434        return proc;
3435    }
3436
3437    void notifyPackageUse(String packageName, int reason) {
3438        IPackageManager pm = AppGlobals.getPackageManager();
3439        try {
3440            pm.notifyPackageUse(packageName, reason);
3441        } catch (RemoteException e) {
3442        }
3443    }
3444
3445    boolean isNextTransitionForward() {
3446        int transit = mWindowManager.getPendingAppTransition();
3447        return transit == TRANSIT_ACTIVITY_OPEN
3448                || transit == TRANSIT_TASK_OPEN
3449                || transit == TRANSIT_TASK_TO_FRONT;
3450    }
3451
3452    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3453            String processName, String abiOverride, int uid, Runnable crashHandler) {
3454        synchronized(this) {
3455            ApplicationInfo info = new ApplicationInfo();
3456            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3457            // For isolated processes, the former contains the parent's uid and the latter the
3458            // actual uid of the isolated process.
3459            // In the special case introduced by this method (which is, starting an isolated
3460            // process directly from the SystemServer without an actual parent app process) the
3461            // closest thing to a parent's uid is SYSTEM_UID.
3462            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3463            // the |isolated| logic in the ProcessRecord constructor.
3464            info.uid = Process.SYSTEM_UID;
3465            info.processName = processName;
3466            info.className = entryPoint;
3467            info.packageName = "android";
3468            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3469                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3470                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3471                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3472                    crashHandler);
3473            return proc != null ? proc.pid : 0;
3474        }
3475    }
3476
3477    final ProcessRecord startProcessLocked(String processName,
3478            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3479            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3480            boolean isolated, boolean keepIfLarge) {
3481        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3482                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3483                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3484                null /* crashHandler */);
3485    }
3486
3487    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3488            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3489            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3490            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3491        long startTime = SystemClock.elapsedRealtime();
3492        ProcessRecord app;
3493        if (!isolated) {
3494            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3495            checkTime(startTime, "startProcess: after getProcessRecord");
3496
3497            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3498                // If we are in the background, then check to see if this process
3499                // is bad.  If so, we will just silently fail.
3500                if (mAppErrors.isBadProcessLocked(info)) {
3501                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3502                            + "/" + info.processName);
3503                    return null;
3504                }
3505            } else {
3506                // When the user is explicitly starting a process, then clear its
3507                // crash count so that we won't make it bad until they see at
3508                // least one crash dialog again, and make the process good again
3509                // if it had been bad.
3510                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3511                        + "/" + info.processName);
3512                mAppErrors.resetProcessCrashTimeLocked(info);
3513                if (mAppErrors.isBadProcessLocked(info)) {
3514                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3515                            UserHandle.getUserId(info.uid), info.uid,
3516                            info.processName);
3517                    mAppErrors.clearBadProcessLocked(info);
3518                    if (app != null) {
3519                        app.bad = false;
3520                    }
3521                }
3522            }
3523        } else {
3524            // If this is an isolated process, it can't re-use an existing process.
3525            app = null;
3526        }
3527
3528        // app launch boost for big.little configurations
3529        // use cpusets to migrate freshly launched tasks to big cores
3530        nativeMigrateToBoost();
3531        mIsBoosted = true;
3532        mBoostStartTime = SystemClock.uptimeMillis();
3533        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3534        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3535
3536        // We don't have to do anything more if:
3537        // (1) There is an existing application record; and
3538        // (2) The caller doesn't think it is dead, OR there is no thread
3539        //     object attached to it so we know it couldn't have crashed; and
3540        // (3) There is a pid assigned to it, so it is either starting or
3541        //     already running.
3542        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3543                + " app=" + app + " knownToBeDead=" + knownToBeDead
3544                + " thread=" + (app != null ? app.thread : null)
3545                + " pid=" + (app != null ? app.pid : -1));
3546        if (app != null && app.pid > 0) {
3547            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3548                // We already have the app running, or are waiting for it to
3549                // come up (we have a pid but not yet its thread), so keep it.
3550                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3551                // If this is a new package in the process, add the package to the list
3552                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3553                checkTime(startTime, "startProcess: done, added package to proc");
3554                return app;
3555            }
3556
3557            // An application record is attached to a previous process,
3558            // clean it up now.
3559            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3560            checkTime(startTime, "startProcess: bad proc running, killing");
3561            killProcessGroup(app.uid, app.pid);
3562            handleAppDiedLocked(app, true, true);
3563            checkTime(startTime, "startProcess: done killing old proc");
3564        }
3565
3566        String hostingNameStr = hostingName != null
3567                ? hostingName.flattenToShortString() : null;
3568
3569        if (app == null) {
3570            checkTime(startTime, "startProcess: creating new process record");
3571            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3572            if (app == null) {
3573                Slog.w(TAG, "Failed making new process record for "
3574                        + processName + "/" + info.uid + " isolated=" + isolated);
3575                return null;
3576            }
3577            app.crashHandler = crashHandler;
3578            checkTime(startTime, "startProcess: done creating new process record");
3579        } else {
3580            // If this is a new package in the process, add the package to the list
3581            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3582            checkTime(startTime, "startProcess: added package to existing proc");
3583        }
3584
3585        // If the system is not ready yet, then hold off on starting this
3586        // process until it is.
3587        if (!mProcessesReady
3588                && !isAllowedWhileBooting(info)
3589                && !allowWhileBooting) {
3590            if (!mProcessesOnHold.contains(app)) {
3591                mProcessesOnHold.add(app);
3592            }
3593            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3594                    "System not ready, putting on hold: " + app);
3595            checkTime(startTime, "startProcess: returning with proc on hold");
3596            return app;
3597        }
3598
3599        checkTime(startTime, "startProcess: stepping in to startProcess");
3600        startProcessLocked(
3601                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3602        checkTime(startTime, "startProcess: done starting proc!");
3603        return (app.pid != 0) ? app : null;
3604    }
3605
3606    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3607        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3608    }
3609
3610    private final void startProcessLocked(ProcessRecord app,
3611            String hostingType, String hostingNameStr) {
3612        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3613                null /* entryPoint */, null /* entryPointArgs */);
3614    }
3615
3616    private final void startProcessLocked(ProcessRecord app, String hostingType,
3617            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3618        long startTime = SystemClock.elapsedRealtime();
3619        if (app.pid > 0 && app.pid != MY_PID) {
3620            checkTime(startTime, "startProcess: removing from pids map");
3621            synchronized (mPidsSelfLocked) {
3622                mPidsSelfLocked.remove(app.pid);
3623                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3624            }
3625            checkTime(startTime, "startProcess: done removing from pids map");
3626            app.setPid(0);
3627        }
3628
3629        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3630                "startProcessLocked removing on hold: " + app);
3631        mProcessesOnHold.remove(app);
3632
3633        checkTime(startTime, "startProcess: starting to update cpu stats");
3634        updateCpuStats();
3635        checkTime(startTime, "startProcess: done updating cpu stats");
3636
3637        try {
3638            try {
3639                final int userId = UserHandle.getUserId(app.uid);
3640                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3641            } catch (RemoteException e) {
3642                throw e.rethrowAsRuntimeException();
3643            }
3644
3645            int uid = app.uid;
3646            int[] gids = null;
3647            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3648            if (!app.isolated) {
3649                int[] permGids = null;
3650                try {
3651                    checkTime(startTime, "startProcess: getting gids from package manager");
3652                    final IPackageManager pm = AppGlobals.getPackageManager();
3653                    permGids = pm.getPackageGids(app.info.packageName,
3654                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3655                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3656                            MountServiceInternal.class);
3657                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3658                            app.info.packageName);
3659                } catch (RemoteException e) {
3660                    throw e.rethrowAsRuntimeException();
3661                }
3662
3663                /*
3664                 * Add shared application and profile GIDs so applications can share some
3665                 * resources like shared libraries and access user-wide resources
3666                 */
3667                if (ArrayUtils.isEmpty(permGids)) {
3668                    gids = new int[2];
3669                } else {
3670                    gids = new int[permGids.length + 2];
3671                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3672                }
3673                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3674                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3675            }
3676            checkTime(startTime, "startProcess: building args");
3677            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3678                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3679                        && mTopComponent != null
3680                        && app.processName.equals(mTopComponent.getPackageName())) {
3681                    uid = 0;
3682                }
3683                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3684                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3685                    uid = 0;
3686                }
3687            }
3688            int debugFlags = 0;
3689            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3690                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3691                // Also turn on CheckJNI for debuggable apps. It's quite
3692                // awkward to turn on otherwise.
3693                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3694            }
3695            // Run the app in safe mode if its manifest requests so or the
3696            // system is booted in safe mode.
3697            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3698                mSafeMode == true) {
3699                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3700            }
3701            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3702                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3703            }
3704            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3705            if ("true".equals(genDebugInfoProperty)) {
3706                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3707            }
3708            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3709                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3710            }
3711            if ("1".equals(SystemProperties.get("debug.assert"))) {
3712                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3713            }
3714            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3715                // Enable all debug flags required by the native debugger.
3716                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3717                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3718                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3719                mNativeDebuggingApp = null;
3720            }
3721
3722            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3723            if (requiredAbi == null) {
3724                requiredAbi = Build.SUPPORTED_ABIS[0];
3725            }
3726
3727            String instructionSet = null;
3728            if (app.info.primaryCpuAbi != null) {
3729                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3730            }
3731
3732            app.gids = gids;
3733            app.requiredAbi = requiredAbi;
3734            app.instructionSet = instructionSet;
3735
3736            // Start the process.  It will either succeed and return a result containing
3737            // the PID of the new process, or else throw a RuntimeException.
3738            boolean isActivityProcess = (entryPoint == null);
3739            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3740            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3741                    app.processName);
3742            checkTime(startTime, "startProcess: asking zygote to start proc");
3743            Process.ProcessStartResult startResult = Process.start(entryPoint,
3744                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3745                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3746                    app.info.dataDir, entryPointArgs);
3747            checkTime(startTime, "startProcess: returned from zygote!");
3748            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3749
3750            if (app.isolated) {
3751                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3752            }
3753            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3754            checkTime(startTime, "startProcess: done updating battery stats");
3755
3756            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3757                    UserHandle.getUserId(uid), startResult.pid, uid,
3758                    app.processName, hostingType,
3759                    hostingNameStr != null ? hostingNameStr : "");
3760
3761            try {
3762                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3763                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3764            } catch (RemoteException ex) {
3765                // Ignore
3766            }
3767
3768            if (app.persistent) {
3769                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3770            }
3771
3772            checkTime(startTime, "startProcess: building log message");
3773            StringBuilder buf = mStringBuilder;
3774            buf.setLength(0);
3775            buf.append("Start proc ");
3776            buf.append(startResult.pid);
3777            buf.append(':');
3778            buf.append(app.processName);
3779            buf.append('/');
3780            UserHandle.formatUid(buf, uid);
3781            if (!isActivityProcess) {
3782                buf.append(" [");
3783                buf.append(entryPoint);
3784                buf.append("]");
3785            }
3786            buf.append(" for ");
3787            buf.append(hostingType);
3788            if (hostingNameStr != null) {
3789                buf.append(" ");
3790                buf.append(hostingNameStr);
3791            }
3792            Slog.i(TAG, buf.toString());
3793            app.setPid(startResult.pid);
3794            app.usingWrapper = startResult.usingWrapper;
3795            app.removed = false;
3796            app.killed = false;
3797            app.killedByAm = false;
3798            checkTime(startTime, "startProcess: starting to update pids map");
3799            synchronized (mPidsSelfLocked) {
3800                this.mPidsSelfLocked.put(startResult.pid, app);
3801                if (isActivityProcess) {
3802                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3803                    msg.obj = app;
3804                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3805                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3806                }
3807            }
3808            checkTime(startTime, "startProcess: done updating pids map");
3809        } catch (RuntimeException e) {
3810            Slog.e(TAG, "Failure starting process " + app.processName, e);
3811
3812            // Something went very wrong while trying to start this process; one
3813            // common case is when the package is frozen due to an active
3814            // upgrade. To recover, clean up any active bookkeeping related to
3815            // starting this process. (We already invoked this method once when
3816            // the package was initially frozen through KILL_APPLICATION_MSG, so
3817            // it doesn't hurt to use it again.)
3818            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3819                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3820        }
3821    }
3822
3823    void updateUsageStats(ActivityRecord component, boolean resumed) {
3824        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3825                "updateUsageStats: comp=" + component + "res=" + resumed);
3826        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3827        if (resumed) {
3828            if (mUsageStatsService != null) {
3829                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3830                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3831            }
3832            synchronized (stats) {
3833                stats.noteActivityResumedLocked(component.app.uid);
3834            }
3835        } else {
3836            if (mUsageStatsService != null) {
3837                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3838                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3839            }
3840            synchronized (stats) {
3841                stats.noteActivityPausedLocked(component.app.uid);
3842            }
3843        }
3844    }
3845
3846    Intent getHomeIntent() {
3847        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3848        intent.setComponent(mTopComponent);
3849        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3851            intent.addCategory(Intent.CATEGORY_HOME);
3852        }
3853        return intent;
3854    }
3855
3856    boolean startHomeActivityLocked(int userId, String reason) {
3857        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3858                && mTopAction == null) {
3859            // We are running in factory test mode, but unable to find
3860            // the factory test app, so just sit around displaying the
3861            // error message and don't try to start anything.
3862            return false;
3863        }
3864        Intent intent = getHomeIntent();
3865        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3866        if (aInfo != null) {
3867            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3868            // Don't do this if the home app is currently being
3869            // instrumented.
3870            aInfo = new ActivityInfo(aInfo);
3871            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3872            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3873                    aInfo.applicationInfo.uid, true);
3874            if (app == null || app.instrumentationClass == null) {
3875                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3876                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3877            }
3878        } else {
3879            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3880        }
3881
3882        return true;
3883    }
3884
3885    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3886        ActivityInfo ai = null;
3887        ComponentName comp = intent.getComponent();
3888        try {
3889            if (comp != null) {
3890                // Factory test.
3891                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3892            } else {
3893                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3894                        intent,
3895                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3896                        flags, userId);
3897
3898                if (info != null) {
3899                    ai = info.activityInfo;
3900                }
3901            }
3902        } catch (RemoteException e) {
3903            // ignore
3904        }
3905
3906        return ai;
3907    }
3908
3909    /**
3910     * Starts the "new version setup screen" if appropriate.
3911     */
3912    void startSetupActivityLocked() {
3913        // Only do this once per boot.
3914        if (mCheckedForSetup) {
3915            return;
3916        }
3917
3918        // We will show this screen if the current one is a different
3919        // version than the last one shown, and we are not running in
3920        // low-level factory test mode.
3921        final ContentResolver resolver = mContext.getContentResolver();
3922        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3923                Settings.Global.getInt(resolver,
3924                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3925            mCheckedForSetup = true;
3926
3927            // See if we should be showing the platform update setup UI.
3928            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3929            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3930                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3931            if (!ris.isEmpty()) {
3932                final ResolveInfo ri = ris.get(0);
3933                String vers = ri.activityInfo.metaData != null
3934                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3935                        : null;
3936                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3937                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3938                            Intent.METADATA_SETUP_VERSION);
3939                }
3940                String lastVers = Settings.Secure.getString(
3941                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3942                if (vers != null && !vers.equals(lastVers)) {
3943                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3944                    intent.setComponent(new ComponentName(
3945                            ri.activityInfo.packageName, ri.activityInfo.name));
3946                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3947                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3948                            null, 0, 0, 0, null, false, false, null, null, null);
3949                }
3950            }
3951        }
3952    }
3953
3954    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3955        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3956    }
3957
3958    void enforceNotIsolatedCaller(String caller) {
3959        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3960            throw new SecurityException("Isolated process not allowed to call " + caller);
3961        }
3962    }
3963
3964    void enforceShellRestriction(String restriction, int userHandle) {
3965        if (Binder.getCallingUid() == Process.SHELL_UID) {
3966            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3967                throw new SecurityException("Shell does not have permission to access user "
3968                        + userHandle);
3969            }
3970        }
3971    }
3972
3973    @Override
3974    public int getFrontActivityScreenCompatMode() {
3975        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3976        synchronized (this) {
3977            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3978        }
3979    }
3980
3981    @Override
3982    public void setFrontActivityScreenCompatMode(int mode) {
3983        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3984                "setFrontActivityScreenCompatMode");
3985        synchronized (this) {
3986            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3987        }
3988    }
3989
3990    @Override
3991    public int getPackageScreenCompatMode(String packageName) {
3992        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3993        synchronized (this) {
3994            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3995        }
3996    }
3997
3998    @Override
3999    public void setPackageScreenCompatMode(String packageName, int mode) {
4000        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4001                "setPackageScreenCompatMode");
4002        synchronized (this) {
4003            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4004        }
4005    }
4006
4007    @Override
4008    public boolean getPackageAskScreenCompat(String packageName) {
4009        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4010        synchronized (this) {
4011            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4012        }
4013    }
4014
4015    @Override
4016    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4017        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4018                "setPackageAskScreenCompat");
4019        synchronized (this) {
4020            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4021        }
4022    }
4023
4024    private boolean hasUsageStatsPermission(String callingPackage) {
4025        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4026                Binder.getCallingUid(), callingPackage);
4027        if (mode == AppOpsManager.MODE_DEFAULT) {
4028            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4029                    == PackageManager.PERMISSION_GRANTED;
4030        }
4031        return mode == AppOpsManager.MODE_ALLOWED;
4032    }
4033
4034    @Override
4035    public int getPackageProcessState(String packageName, String callingPackage) {
4036        if (!hasUsageStatsPermission(callingPackage)) {
4037            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4038                    "getPackageProcessState");
4039        }
4040
4041        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4042        synchronized (this) {
4043            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4044                final ProcessRecord proc = mLruProcesses.get(i);
4045                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4046                        || procState > proc.setProcState) {
4047                    boolean found = false;
4048                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4049                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4050                            procState = proc.setProcState;
4051                            found = true;
4052                        }
4053                    }
4054                    if (proc.pkgDeps != null && !found) {
4055                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4056                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4057                                procState = proc.setProcState;
4058                                break;
4059                            }
4060                        }
4061                    }
4062                }
4063            }
4064        }
4065        return procState;
4066    }
4067
4068    @Override
4069    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4070        synchronized (this) {
4071            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4072            if (app == null) {
4073                return false;
4074            }
4075            if (app.trimMemoryLevel < level && app.thread != null &&
4076                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4077                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4078                try {
4079                    app.thread.scheduleTrimMemory(level);
4080                    app.trimMemoryLevel = level;
4081                    return true;
4082                } catch (RemoteException e) {
4083                    // Fallthrough to failure case.
4084                }
4085            }
4086        }
4087        return false;
4088    }
4089
4090    private void dispatchProcessesChanged() {
4091        int N;
4092        synchronized (this) {
4093            N = mPendingProcessChanges.size();
4094            if (mActiveProcessChanges.length < N) {
4095                mActiveProcessChanges = new ProcessChangeItem[N];
4096            }
4097            mPendingProcessChanges.toArray(mActiveProcessChanges);
4098            mPendingProcessChanges.clear();
4099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4100                    "*** Delivering " + N + " process changes");
4101        }
4102
4103        int i = mProcessObservers.beginBroadcast();
4104        while (i > 0) {
4105            i--;
4106            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4107            if (observer != null) {
4108                try {
4109                    for (int j=0; j<N; j++) {
4110                        ProcessChangeItem item = mActiveProcessChanges[j];
4111                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4112                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4114                                    + item.uid + ": " + item.foregroundActivities);
4115                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4116                                    item.foregroundActivities);
4117                        }
4118                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4119                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4120                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4121                                    + ": " + item.processState);
4122                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4123                        }
4124                    }
4125                } catch (RemoteException e) {
4126                }
4127            }
4128        }
4129        mProcessObservers.finishBroadcast();
4130
4131        synchronized (this) {
4132            for (int j=0; j<N; j++) {
4133                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4134            }
4135        }
4136    }
4137
4138    private void dispatchProcessDied(int pid, int uid) {
4139        int i = mProcessObservers.beginBroadcast();
4140        while (i > 0) {
4141            i--;
4142            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4143            if (observer != null) {
4144                try {
4145                    observer.onProcessDied(pid, uid);
4146                } catch (RemoteException e) {
4147                }
4148            }
4149        }
4150        mProcessObservers.finishBroadcast();
4151    }
4152
4153    private void dispatchUidsChanged() {
4154        int N;
4155        synchronized (this) {
4156            N = mPendingUidChanges.size();
4157            if (mActiveUidChanges.length < N) {
4158                mActiveUidChanges = new UidRecord.ChangeItem[N];
4159            }
4160            for (int i=0; i<N; i++) {
4161                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4162                mActiveUidChanges[i] = change;
4163                if (change.uidRecord != null) {
4164                    change.uidRecord.pendingChange = null;
4165                    change.uidRecord = null;
4166                }
4167            }
4168            mPendingUidChanges.clear();
4169            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                    "*** Delivering " + N + " uid changes");
4171        }
4172
4173        if (mLocalPowerManager != null) {
4174            for (int j=0; j<N; j++) {
4175                UidRecord.ChangeItem item = mActiveUidChanges[j];
4176                if (item.change == UidRecord.CHANGE_GONE
4177                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4178                    mLocalPowerManager.uidGone(item.uid);
4179                } else {
4180                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4181                }
4182            }
4183        }
4184
4185        int i = mUidObservers.beginBroadcast();
4186        while (i > 0) {
4187            i--;
4188            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4189            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4190            if (observer != null) {
4191                try {
4192                    for (int j=0; j<N; j++) {
4193                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4194                        final int change = item.change;
4195                        UidRecord validateUid = null;
4196                        if (VALIDATE_UID_STATES && i == 0) {
4197                            validateUid = mValidateUids.get(item.uid);
4198                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4199                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4200                                validateUid = new UidRecord(item.uid);
4201                                mValidateUids.put(item.uid, validateUid);
4202                            }
4203                        }
4204                        if (change == UidRecord.CHANGE_IDLE
4205                                || change == UidRecord.CHANGE_GONE_IDLE) {
4206                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID idle uid=" + item.uid);
4209                                observer.onUidIdle(item.uid);
4210                            }
4211                            if (VALIDATE_UID_STATES && i == 0) {
4212                                if (validateUid != null) {
4213                                    validateUid.idle = true;
4214                                }
4215                            }
4216                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4217                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4218                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4219                                        "UID active uid=" + item.uid);
4220                                observer.onUidActive(item.uid);
4221                            }
4222                            if (VALIDATE_UID_STATES && i == 0) {
4223                                validateUid.idle = false;
4224                            }
4225                        }
4226                        if (change == UidRecord.CHANGE_GONE
4227                                || change == UidRecord.CHANGE_GONE_IDLE) {
4228                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4229                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4230                                        "UID gone uid=" + item.uid);
4231                                observer.onUidGone(item.uid);
4232                            }
4233                            if (VALIDATE_UID_STATES && i == 0) {
4234                                if (validateUid != null) {
4235                                    mValidateUids.remove(item.uid);
4236                                }
4237                            }
4238                        } else {
4239                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4240                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4241                                        "UID CHANGED uid=" + item.uid
4242                                                + ": " + item.processState);
4243                                observer.onUidStateChanged(item.uid, item.processState);
4244                            }
4245                            if (VALIDATE_UID_STATES && i == 0) {
4246                                validateUid.curProcState = validateUid.setProcState
4247                                        = item.processState;
4248                            }
4249                        }
4250                    }
4251                } catch (RemoteException e) {
4252                }
4253            }
4254        }
4255        mUidObservers.finishBroadcast();
4256
4257        synchronized (this) {
4258            for (int j=0; j<N; j++) {
4259                mAvailUidChanges.add(mActiveUidChanges[j]);
4260            }
4261        }
4262    }
4263
4264    @Override
4265    public final int startActivity(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4268        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4269                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4270                UserHandle.getCallingUserId());
4271    }
4272
4273    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4274        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4275        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4276                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4277                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4278
4279        // TODO: Switch to user app stacks here.
4280        String mimeType = intent.getType();
4281        final Uri data = intent.getData();
4282        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4283            mimeType = getProviderMimeType(data, userId);
4284        }
4285        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4286
4287        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4288        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4289                null, 0, 0, null, null, null, null, false, userId, container, null);
4290    }
4291
4292    @Override
4293    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4294            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4295            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4296        enforceNotIsolatedCaller("startActivity");
4297        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4298                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4299        // TODO: Switch to user app stacks here.
4300        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4301                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4302                profilerInfo, null, null, bOptions, false, userId, null, null);
4303    }
4304
4305    @Override
4306    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4309            int userId) {
4310
4311        // This is very dangerous -- it allows you to perform a start activity (including
4312        // permission grants) as any app that may launch one of your own activities.  So
4313        // we will only allow this to be done from activities that are part of the core framework,
4314        // and then only when they are running as the system.
4315        final ActivityRecord sourceRecord;
4316        final int targetUid;
4317        final String targetPackage;
4318        synchronized (this) {
4319            if (resultTo == null) {
4320                throw new SecurityException("Must be called from an activity");
4321            }
4322            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4323            if (sourceRecord == null) {
4324                throw new SecurityException("Called with bad activity token: " + resultTo);
4325            }
4326            if (!sourceRecord.info.packageName.equals("android")) {
4327                throw new SecurityException(
4328                        "Must be called from an activity that is declared in the android package");
4329            }
4330            if (sourceRecord.app == null) {
4331                throw new SecurityException("Called without a process attached to activity");
4332            }
4333            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4334                // This is still okay, as long as this activity is running under the
4335                // uid of the original calling activity.
4336                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4337                    throw new SecurityException(
4338                            "Calling activity in uid " + sourceRecord.app.uid
4339                                    + " must be system uid or original calling uid "
4340                                    + sourceRecord.launchedFromUid);
4341                }
4342            }
4343            if (ignoreTargetSecurity) {
4344                if (intent.getComponent() == null) {
4345                    throw new SecurityException(
4346                            "Component must be specified with ignoreTargetSecurity");
4347                }
4348                if (intent.getSelector() != null) {
4349                    throw new SecurityException(
4350                            "Selector not allowed with ignoreTargetSecurity");
4351                }
4352            }
4353            targetUid = sourceRecord.launchedFromUid;
4354            targetPackage = sourceRecord.launchedFromPackage;
4355        }
4356
4357        if (userId == UserHandle.USER_NULL) {
4358            userId = UserHandle.getUserId(sourceRecord.app.uid);
4359        }
4360
4361        // TODO: Switch to user app stacks here.
4362        try {
4363            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4364                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4365                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4366            return ret;
4367        } catch (SecurityException e) {
4368            // XXX need to figure out how to propagate to original app.
4369            // A SecurityException here is generally actually a fault of the original
4370            // calling activity (such as a fairly granting permissions), so propagate it
4371            // back to them.
4372            /*
4373            StringBuilder msg = new StringBuilder();
4374            msg.append("While launching");
4375            msg.append(intent.toString());
4376            msg.append(": ");
4377            msg.append(e.getMessage());
4378            */
4379            throw e;
4380        }
4381    }
4382
4383    @Override
4384    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4385            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4386            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4387        enforceNotIsolatedCaller("startActivityAndWait");
4388        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4389                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4390        WaitResult res = new WaitResult();
4391        // TODO: Switch to user app stacks here.
4392        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4393                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4394                bOptions, false, userId, null, null);
4395        return res;
4396    }
4397
4398    @Override
4399    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4400            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4401            int startFlags, Configuration config, Bundle bOptions, int userId) {
4402        enforceNotIsolatedCaller("startActivityWithConfig");
4403        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4404                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4405        // TODO: Switch to user app stacks here.
4406        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4408                null, null, config, bOptions, false, userId, null, null);
4409        return ret;
4410    }
4411
4412    @Override
4413    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4414            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4415            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4416            throws TransactionTooLargeException {
4417        enforceNotIsolatedCaller("startActivityIntentSender");
4418        // Refuse possible leaked file descriptors
4419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4420            throw new IllegalArgumentException("File descriptors passed in Intent");
4421        }
4422
4423        IIntentSender sender = intent.getTarget();
4424        if (!(sender instanceof PendingIntentRecord)) {
4425            throw new IllegalArgumentException("Bad PendingIntent object");
4426        }
4427
4428        PendingIntentRecord pir = (PendingIntentRecord)sender;
4429
4430        synchronized (this) {
4431            // If this is coming from the currently resumed activity, it is
4432            // effectively saying that app switches are allowed at this point.
4433            final ActivityStack stack = getFocusedStack();
4434            if (stack.mResumedActivity != null &&
4435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4436                mAppSwitchesAllowedTime = 0;
4437            }
4438        }
4439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4440                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4441        return ret;
4442    }
4443
4444    @Override
4445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4446            Intent intent, String resolvedType, IVoiceInteractionSession session,
4447            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4448            Bundle bOptions, int userId) {
4449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4450                != PackageManager.PERMISSION_GRANTED) {
4451            String msg = "Permission Denial: startVoiceActivity() from pid="
4452                    + Binder.getCallingPid()
4453                    + ", uid=" + Binder.getCallingUid()
4454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4455            Slog.w(TAG, msg);
4456            throw new SecurityException(msg);
4457        }
4458        if (session == null || interactor == null) {
4459            throw new NullPointerException("null session or interactor");
4460        }
4461        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4462                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4463        // TODO: Switch to user app stacks here.
4464        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4465                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4466                null, bOptions, false, userId, null, null);
4467    }
4468
4469    @Override
4470    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4471            throws RemoteException {
4472        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4473        synchronized (this) {
4474            ActivityRecord activity = getFocusedStack().topActivity();
4475            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4476                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4477            }
4478            if (mRunningVoice != null || activity.task.voiceSession != null
4479                    || activity.voiceSession != null) {
4480                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4481                return;
4482            }
4483            if (activity.pendingVoiceInteractionStart) {
4484                Slog.w(TAG, "Pending start of voice interaction already.");
4485                return;
4486            }
4487            activity.pendingVoiceInteractionStart = true;
4488        }
4489        LocalServices.getService(VoiceInteractionManagerInternal.class)
4490                .startLocalVoiceInteraction(callingActivity, options);
4491    }
4492
4493    @Override
4494    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4495        LocalServices.getService(VoiceInteractionManagerInternal.class)
4496                .stopLocalVoiceInteraction(callingActivity);
4497    }
4498
4499    @Override
4500    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4501        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4502                .supportsLocalVoiceInteraction();
4503    }
4504
4505    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4506            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4507        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4508        if (activityToCallback == null) return;
4509        activityToCallback.setVoiceSessionLocked(voiceSession);
4510
4511        // Inform the activity
4512        try {
4513            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4514                    voiceInteractor);
4515            long token = Binder.clearCallingIdentity();
4516            try {
4517                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4518            } finally {
4519                Binder.restoreCallingIdentity(token);
4520            }
4521            // TODO: VI Should we cache the activity so that it's easier to find later
4522            // rather than scan through all the stacks and activities?
4523        } catch (RemoteException re) {
4524            activityToCallback.clearVoiceSessionLocked();
4525            // TODO: VI Should this terminate the voice session?
4526        }
4527    }
4528
4529    @Override
4530    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4531        synchronized (this) {
4532            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4533                if (keepAwake) {
4534                    mVoiceWakeLock.acquire();
4535                } else {
4536                    mVoiceWakeLock.release();
4537                }
4538            }
4539        }
4540    }
4541
4542    @Override
4543    public boolean startNextMatchingActivity(IBinder callingActivity,
4544            Intent intent, Bundle bOptions) {
4545        // Refuse possible leaked file descriptors
4546        if (intent != null && intent.hasFileDescriptors() == true) {
4547            throw new IllegalArgumentException("File descriptors passed in Intent");
4548        }
4549        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4550
4551        synchronized (this) {
4552            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4553            if (r == null) {
4554                ActivityOptions.abort(options);
4555                return false;
4556            }
4557            if (r.app == null || r.app.thread == null) {
4558                // The caller is not running...  d'oh!
4559                ActivityOptions.abort(options);
4560                return false;
4561            }
4562            intent = new Intent(intent);
4563            // The caller is not allowed to change the data.
4564            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4565            // And we are resetting to find the next component...
4566            intent.setComponent(null);
4567
4568            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4569
4570            ActivityInfo aInfo = null;
4571            try {
4572                List<ResolveInfo> resolves =
4573                    AppGlobals.getPackageManager().queryIntentActivities(
4574                            intent, r.resolvedType,
4575                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4576                            UserHandle.getCallingUserId()).getList();
4577
4578                // Look for the original activity in the list...
4579                final int N = resolves != null ? resolves.size() : 0;
4580                for (int i=0; i<N; i++) {
4581                    ResolveInfo rInfo = resolves.get(i);
4582                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4583                            && rInfo.activityInfo.name.equals(r.info.name)) {
4584                        // We found the current one...  the next matching is
4585                        // after it.
4586                        i++;
4587                        if (i<N) {
4588                            aInfo = resolves.get(i).activityInfo;
4589                        }
4590                        if (debug) {
4591                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4592                                    + "/" + r.info.name);
4593                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4594                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4595                        }
4596                        break;
4597                    }
4598                }
4599            } catch (RemoteException e) {
4600            }
4601
4602            if (aInfo == null) {
4603                // Nobody who is next!
4604                ActivityOptions.abort(options);
4605                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4606                return false;
4607            }
4608
4609            intent.setComponent(new ComponentName(
4610                    aInfo.applicationInfo.packageName, aInfo.name));
4611            intent.setFlags(intent.getFlags()&~(
4612                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4613                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4614                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4615                    Intent.FLAG_ACTIVITY_NEW_TASK));
4616
4617            // Okay now we need to start the new activity, replacing the
4618            // currently running activity.  This is a little tricky because
4619            // we want to start the new one as if the current one is finished,
4620            // but not finish the current one first so that there is no flicker.
4621            // And thus...
4622            final boolean wasFinishing = r.finishing;
4623            r.finishing = true;
4624
4625            // Propagate reply information over to the new activity.
4626            final ActivityRecord resultTo = r.resultTo;
4627            final String resultWho = r.resultWho;
4628            final int requestCode = r.requestCode;
4629            r.resultTo = null;
4630            if (resultTo != null) {
4631                resultTo.removeResultsLocked(r, resultWho, requestCode);
4632            }
4633
4634            final long origId = Binder.clearCallingIdentity();
4635            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4636                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4637                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4638                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4639                    false, false, null, null, null);
4640            Binder.restoreCallingIdentity(origId);
4641
4642            r.finishing = wasFinishing;
4643            if (res != ActivityManager.START_SUCCESS) {
4644                return false;
4645            }
4646            return true;
4647        }
4648    }
4649
4650    @Override
4651    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4652        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4653            String msg = "Permission Denial: startActivityFromRecents called without " +
4654                    START_TASKS_FROM_RECENTS;
4655            Slog.w(TAG, msg);
4656            throw new SecurityException(msg);
4657        }
4658        final long origId = Binder.clearCallingIdentity();
4659        try {
4660            synchronized (this) {
4661                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4662            }
4663        } finally {
4664            Binder.restoreCallingIdentity(origId);
4665        }
4666    }
4667
4668    final int startActivityInPackage(int uid, String callingPackage,
4669            Intent intent, String resolvedType, IBinder resultTo,
4670            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4671            IActivityContainer container, TaskRecord inTask) {
4672
4673        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4674                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4675
4676        // TODO: Switch to user app stacks here.
4677        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4678                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4679                null, null, null, bOptions, false, userId, container, inTask);
4680        return ret;
4681    }
4682
4683    @Override
4684    public final int startActivities(IApplicationThread caller, String callingPackage,
4685            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4686            int userId) {
4687        enforceNotIsolatedCaller("startActivities");
4688        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4689                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4690        // TODO: Switch to user app stacks here.
4691        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4692                resolvedTypes, resultTo, bOptions, userId);
4693        return ret;
4694    }
4695
4696    final int startActivitiesInPackage(int uid, String callingPackage,
4697            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4698            Bundle bOptions, int userId) {
4699
4700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4701                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4702        // TODO: Switch to user app stacks here.
4703        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4704                resultTo, bOptions, userId);
4705        return ret;
4706    }
4707
4708    @Override
4709    public void reportActivityFullyDrawn(IBinder token) {
4710        synchronized (this) {
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r == null) {
4713                return;
4714            }
4715            r.reportFullyDrawnLocked();
4716        }
4717    }
4718
4719    @Override
4720    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4721        synchronized (this) {
4722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4723            if (r == null) {
4724                return;
4725            }
4726            TaskRecord task = r.task;
4727            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4728                // Fixed screen orientation isn't supported when activities aren't in full screen
4729                // mode.
4730                return;
4731            }
4732            final long origId = Binder.clearCallingIdentity();
4733            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4734            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4735                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4736            if (config != null) {
4737                r.frozenBeforeDestroy = true;
4738                if (!updateConfigurationLocked(config, r, false)) {
4739                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4740                }
4741            }
4742            Binder.restoreCallingIdentity(origId);
4743        }
4744    }
4745
4746    @Override
4747    public int getRequestedOrientation(IBinder token) {
4748        synchronized (this) {
4749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4750            if (r == null) {
4751                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4752            }
4753            return mWindowManager.getAppOrientation(r.appToken);
4754        }
4755    }
4756
4757    /**
4758     * This is the internal entry point for handling Activity.finish().
4759     *
4760     * @param token The Binder token referencing the Activity we want to finish.
4761     * @param resultCode Result code, if any, from this Activity.
4762     * @param resultData Result data (Intent), if any, from this Activity.
4763     * @param finishTask Whether to finish the task associated with this Activity.
4764     *
4765     * @return Returns true if the activity successfully finished, or false if it is still running.
4766     */
4767    @Override
4768    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4769            int finishTask) {
4770        // Refuse possible leaked file descriptors
4771        if (resultData != null && resultData.hasFileDescriptors() == true) {
4772            throw new IllegalArgumentException("File descriptors passed in Intent");
4773        }
4774
4775        synchronized(this) {
4776            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4777            if (r == null) {
4778                return true;
4779            }
4780            // Keep track of the root activity of the task before we finish it
4781            TaskRecord tr = r.task;
4782            ActivityRecord rootR = tr.getRootActivity();
4783            if (rootR == null) {
4784                Slog.w(TAG, "Finishing task with all activities already finished");
4785            }
4786            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4787            // finish.
4788            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4789                    mStackSupervisor.isLastLockedTask(tr)) {
4790                Slog.i(TAG, "Not finishing task in lock task mode");
4791                mStackSupervisor.showLockTaskToast();
4792                return false;
4793            }
4794            if (mController != null) {
4795                // Find the first activity that is not finishing.
4796                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4797                if (next != null) {
4798                    // ask watcher if this is allowed
4799                    boolean resumeOK = true;
4800                    try {
4801                        resumeOK = mController.activityResuming(next.packageName);
4802                    } catch (RemoteException e) {
4803                        mController = null;
4804                        Watchdog.getInstance().setActivityController(null);
4805                    }
4806
4807                    if (!resumeOK) {
4808                        Slog.i(TAG, "Not finishing activity because controller resumed");
4809                        return false;
4810                    }
4811                }
4812            }
4813            final long origId = Binder.clearCallingIdentity();
4814            try {
4815                boolean res;
4816                final boolean finishWithRootActivity =
4817                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4818                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4819                        || (finishWithRootActivity && r == rootR)) {
4820                    // If requested, remove the task that is associated to this activity only if it
4821                    // was the root activity in the task. The result code and data is ignored
4822                    // because we don't support returning them across task boundaries. Also, to
4823                    // keep backwards compatibility we remove the task from recents when finishing
4824                    // task with root activity.
4825                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4826                    if (!res) {
4827                        Slog.i(TAG, "Removing task failed to finish activity");
4828                    }
4829                } else {
4830                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4831                            resultData, "app-request", true);
4832                    if (!res) {
4833                        Slog.i(TAG, "Failed to finish by app-request");
4834                    }
4835                }
4836                return res;
4837            } finally {
4838                Binder.restoreCallingIdentity(origId);
4839            }
4840        }
4841    }
4842
4843    @Override
4844    public final void finishHeavyWeightApp() {
4845        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4846                != PackageManager.PERMISSION_GRANTED) {
4847            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4848                    + Binder.getCallingPid()
4849                    + ", uid=" + Binder.getCallingUid()
4850                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4851            Slog.w(TAG, msg);
4852            throw new SecurityException(msg);
4853        }
4854
4855        synchronized(this) {
4856            if (mHeavyWeightProcess == null) {
4857                return;
4858            }
4859
4860            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4861            for (int i = 0; i < activities.size(); i++) {
4862                ActivityRecord r = activities.get(i);
4863                if (!r.finishing && r.isInStackLocked()) {
4864                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4865                            null, "finish-heavy", true);
4866                }
4867            }
4868
4869            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4870                    mHeavyWeightProcess.userId, 0));
4871            mHeavyWeightProcess = null;
4872        }
4873    }
4874
4875    @Override
4876    public void crashApplication(int uid, int initialPid, String packageName,
4877            String message) {
4878        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4879                != PackageManager.PERMISSION_GRANTED) {
4880            String msg = "Permission Denial: crashApplication() from pid="
4881                    + Binder.getCallingPid()
4882                    + ", uid=" + Binder.getCallingUid()
4883                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4884            Slog.w(TAG, msg);
4885            throw new SecurityException(msg);
4886        }
4887
4888        synchronized(this) {
4889            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4890        }
4891    }
4892
4893    @Override
4894    public final void finishSubActivity(IBinder token, String resultWho,
4895            int requestCode) {
4896        synchronized(this) {
4897            final long origId = Binder.clearCallingIdentity();
4898            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4899            if (r != null) {
4900                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4901            }
4902            Binder.restoreCallingIdentity(origId);
4903        }
4904    }
4905
4906    @Override
4907    public boolean finishActivityAffinity(IBinder token) {
4908        synchronized(this) {
4909            final long origId = Binder.clearCallingIdentity();
4910            try {
4911                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4912                if (r == null) {
4913                    return false;
4914                }
4915
4916                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4917                // can finish.
4918                final TaskRecord task = r.task;
4919                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4920                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4921                    mStackSupervisor.showLockTaskToast();
4922                    return false;
4923                }
4924                return task.stack.finishActivityAffinityLocked(r);
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public void finishVoiceTask(IVoiceInteractionSession session) {
4933        synchronized (this) {
4934            final long origId = Binder.clearCallingIdentity();
4935            try {
4936                // TODO: VI Consider treating local voice interactions and voice tasks
4937                // differently here
4938                mStackSupervisor.finishVoiceTask(session);
4939            } finally {
4940                Binder.restoreCallingIdentity(origId);
4941            }
4942        }
4943
4944    }
4945
4946    @Override
4947    public boolean releaseActivityInstance(IBinder token) {
4948        synchronized(this) {
4949            final long origId = Binder.clearCallingIdentity();
4950            try {
4951                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4952                if (r == null) {
4953                    return false;
4954                }
4955                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4956            } finally {
4957                Binder.restoreCallingIdentity(origId);
4958            }
4959        }
4960    }
4961
4962    @Override
4963    public void releaseSomeActivities(IApplicationThread appInt) {
4964        synchronized(this) {
4965            final long origId = Binder.clearCallingIdentity();
4966            try {
4967                ProcessRecord app = getRecordForAppLocked(appInt);
4968                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4969            } finally {
4970                Binder.restoreCallingIdentity(origId);
4971            }
4972        }
4973    }
4974
4975    @Override
4976    public boolean willActivityBeVisible(IBinder token) {
4977        synchronized(this) {
4978            ActivityStack stack = ActivityRecord.getStackLocked(token);
4979            if (stack != null) {
4980                return stack.willActivityBeVisibleLocked(token);
4981            }
4982            return false;
4983        }
4984    }
4985
4986    @Override
4987    public void overridePendingTransition(IBinder token, String packageName,
4988            int enterAnim, int exitAnim) {
4989        synchronized(this) {
4990            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4991            if (self == null) {
4992                return;
4993            }
4994
4995            final long origId = Binder.clearCallingIdentity();
4996
4997            if (self.state == ActivityState.RESUMED
4998                    || self.state == ActivityState.PAUSING) {
4999                mWindowManager.overridePendingAppTransition(packageName,
5000                        enterAnim, exitAnim, null);
5001            }
5002
5003            Binder.restoreCallingIdentity(origId);
5004        }
5005    }
5006
5007    /**
5008     * Main function for removing an existing process from the activity manager
5009     * as a result of that process going away.  Clears out all connections
5010     * to the process.
5011     */
5012    private final void handleAppDiedLocked(ProcessRecord app,
5013            boolean restarting, boolean allowRestart) {
5014        int pid = app.pid;
5015        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5016        if (!kept && !restarting) {
5017            removeLruProcessLocked(app);
5018            if (pid > 0) {
5019                ProcessList.remove(pid);
5020            }
5021        }
5022
5023        if (mProfileProc == app) {
5024            clearProfilerLocked();
5025        }
5026
5027        // Remove this application's activities from active lists.
5028        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5029
5030        app.activities.clear();
5031
5032        if (app.instrumentationClass != null) {
5033            Slog.w(TAG, "Crash of app " + app.processName
5034                  + " running instrumentation " + app.instrumentationClass);
5035            Bundle info = new Bundle();
5036            info.putString("shortMsg", "Process crashed.");
5037            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5038        }
5039
5040        if (!restarting && hasVisibleActivities
5041                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5042            // If there was nothing to resume, and we are not already restarting this process, but
5043            // there is a visible activity that is hosted by the process...  then make sure all
5044            // visible activities are running, taking care of restarting this process.
5045            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5046        }
5047    }
5048
5049    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5050        IBinder threadBinder = thread.asBinder();
5051        // Find the application record.
5052        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5053            ProcessRecord rec = mLruProcesses.get(i);
5054            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5055                return i;
5056            }
5057        }
5058        return -1;
5059    }
5060
5061    final ProcessRecord getRecordForAppLocked(
5062            IApplicationThread thread) {
5063        if (thread == null) {
5064            return null;
5065        }
5066
5067        int appIndex = getLRURecordIndexForAppLocked(thread);
5068        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5069    }
5070
5071    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5072        // If there are no longer any background processes running,
5073        // and the app that died was not running instrumentation,
5074        // then tell everyone we are now low on memory.
5075        boolean haveBg = false;
5076        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5077            ProcessRecord rec = mLruProcesses.get(i);
5078            if (rec.thread != null
5079                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5080                haveBg = true;
5081                break;
5082            }
5083        }
5084
5085        if (!haveBg) {
5086            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5087            if (doReport) {
5088                long now = SystemClock.uptimeMillis();
5089                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5090                    doReport = false;
5091                } else {
5092                    mLastMemUsageReportTime = now;
5093                }
5094            }
5095            final ArrayList<ProcessMemInfo> memInfos
5096                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5097            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5098            long now = SystemClock.uptimeMillis();
5099            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5100                ProcessRecord rec = mLruProcesses.get(i);
5101                if (rec == dyingProc || rec.thread == null) {
5102                    continue;
5103                }
5104                if (doReport) {
5105                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5106                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5107                }
5108                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5109                    // The low memory report is overriding any current
5110                    // state for a GC request.  Make sure to do
5111                    // heavy/important/visible/foreground processes first.
5112                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5113                        rec.lastRequestedGc = 0;
5114                    } else {
5115                        rec.lastRequestedGc = rec.lastLowMemory;
5116                    }
5117                    rec.reportLowMemory = true;
5118                    rec.lastLowMemory = now;
5119                    mProcessesToGc.remove(rec);
5120                    addProcessToGcListLocked(rec);
5121                }
5122            }
5123            if (doReport) {
5124                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5125                mHandler.sendMessage(msg);
5126            }
5127            scheduleAppGcsLocked();
5128        }
5129    }
5130
5131    final void appDiedLocked(ProcessRecord app) {
5132       appDiedLocked(app, app.pid, app.thread, false);
5133    }
5134
5135    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5136            boolean fromBinderDied) {
5137        // First check if this ProcessRecord is actually active for the pid.
5138        synchronized (mPidsSelfLocked) {
5139            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5140            if (curProc != app) {
5141                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5142                return;
5143            }
5144        }
5145
5146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5147        synchronized (stats) {
5148            stats.noteProcessDiedLocked(app.info.uid, pid);
5149        }
5150
5151        if (!app.killed) {
5152            if (!fromBinderDied) {
5153                Process.killProcessQuiet(pid);
5154            }
5155            killProcessGroup(app.uid, pid);
5156            app.killed = true;
5157        }
5158
5159        // Clean up already done if the process has been re-started.
5160        if (app.pid == pid && app.thread != null &&
5161                app.thread.asBinder() == thread.asBinder()) {
5162            boolean doLowMem = app.instrumentationClass == null;
5163            boolean doOomAdj = doLowMem;
5164            if (!app.killedByAm) {
5165                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5166                        + ") has died");
5167                mAllowLowerMemLevel = true;
5168            } else {
5169                // Note that we always want to do oom adj to update our state with the
5170                // new number of procs.
5171                mAllowLowerMemLevel = false;
5172                doLowMem = false;
5173            }
5174            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5175            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5176                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5177            handleAppDiedLocked(app, false, true);
5178
5179            if (doOomAdj) {
5180                updateOomAdjLocked();
5181            }
5182            if (doLowMem) {
5183                doLowMemReportIfNeededLocked(app);
5184            }
5185        } else if (app.pid != pid) {
5186            // A new process has already been started.
5187            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5188                    + ") has died and restarted (pid " + app.pid + ").");
5189            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5190        } else if (DEBUG_PROCESSES) {
5191            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5192                    + thread.asBinder());
5193        }
5194    }
5195
5196    /**
5197     * If a stack trace dump file is configured, dump process stack traces.
5198     * @param clearTraces causes the dump file to be erased prior to the new
5199     *    traces being written, if true; when false, the new traces will be
5200     *    appended to any existing file content.
5201     * @param firstPids of dalvik VM processes to dump stack traces for first
5202     * @param lastPids of dalvik VM processes to dump stack traces for last
5203     * @param nativeProcs optional list of native process names to dump stack crawls
5204     * @return file containing stack traces, or null if no dump file is configured
5205     */
5206    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5207            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5208        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5209        if (tracesPath == null || tracesPath.length() == 0) {
5210            return null;
5211        }
5212
5213        File tracesFile = new File(tracesPath);
5214        try {
5215            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5216            tracesFile.createNewFile();
5217            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5218        } catch (IOException e) {
5219            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5220            return null;
5221        }
5222
5223        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5224        return tracesFile;
5225    }
5226
5227    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5228            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5229        // Use a FileObserver to detect when traces finish writing.
5230        // The order of traces is considered important to maintain for legibility.
5231        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5232            @Override
5233            public synchronized void onEvent(int event, String path) { notify(); }
5234        };
5235
5236        try {
5237            observer.startWatching();
5238
5239            // First collect all of the stacks of the most important pids.
5240            if (firstPids != null) {
5241                try {
5242                    int num = firstPids.size();
5243                    for (int i = 0; i < num; i++) {
5244                        synchronized (observer) {
5245                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5246                                    + firstPids.get(i));
5247                            final long sime = SystemClock.elapsedRealtime();
5248                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5249                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5250                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5251                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5252                        }
5253                    }
5254                } catch (InterruptedException e) {
5255                    Slog.wtf(TAG, e);
5256                }
5257            }
5258
5259            // Next collect the stacks of the native pids
5260            if (nativeProcs != null) {
5261                int[] pids = Process.getPidsForCommands(nativeProcs);
5262                if (pids != null) {
5263                    for (int pid : pids) {
5264                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5265                        final long sime = SystemClock.elapsedRealtime();
5266                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5267                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5268                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5269                    }
5270                }
5271            }
5272
5273            // Lastly, measure CPU usage.
5274            if (processCpuTracker != null) {
5275                processCpuTracker.init();
5276                System.gc();
5277                processCpuTracker.update();
5278                try {
5279                    synchronized (processCpuTracker) {
5280                        processCpuTracker.wait(500); // measure over 1/2 second.
5281                    }
5282                } catch (InterruptedException e) {
5283                }
5284                processCpuTracker.update();
5285
5286                // We'll take the stack crawls of just the top apps using CPU.
5287                final int N = processCpuTracker.countWorkingStats();
5288                int numProcs = 0;
5289                for (int i=0; i<N && numProcs<5; i++) {
5290                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5291                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5292                        numProcs++;
5293                        try {
5294                            synchronized (observer) {
5295                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5296                                        + stats.pid);
5297                                final long stime = SystemClock.elapsedRealtime();
5298                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5299                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5300                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5301                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5302                            }
5303                        } catch (InterruptedException e) {
5304                            Slog.wtf(TAG, e);
5305                        }
5306                    } else if (DEBUG_ANR) {
5307                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5308                                + stats.pid);
5309                    }
5310                }
5311            }
5312        } finally {
5313            observer.stopWatching();
5314        }
5315    }
5316
5317    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5318        if (true || IS_USER_BUILD) {
5319            return;
5320        }
5321        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5322        if (tracesPath == null || tracesPath.length() == 0) {
5323            return;
5324        }
5325
5326        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5327        StrictMode.allowThreadDiskWrites();
5328        try {
5329            final File tracesFile = new File(tracesPath);
5330            final File tracesDir = tracesFile.getParentFile();
5331            final File tracesTmp = new File(tracesDir, "__tmp__");
5332            try {
5333                if (tracesFile.exists()) {
5334                    tracesTmp.delete();
5335                    tracesFile.renameTo(tracesTmp);
5336                }
5337                StringBuilder sb = new StringBuilder();
5338                Time tobj = new Time();
5339                tobj.set(System.currentTimeMillis());
5340                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5341                sb.append(": ");
5342                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5343                sb.append(" since ");
5344                sb.append(msg);
5345                FileOutputStream fos = new FileOutputStream(tracesFile);
5346                fos.write(sb.toString().getBytes());
5347                if (app == null) {
5348                    fos.write("\n*** No application process!".getBytes());
5349                }
5350                fos.close();
5351                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5352            } catch (IOException e) {
5353                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5354                return;
5355            }
5356
5357            if (app != null) {
5358                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5359                firstPids.add(app.pid);
5360                dumpStackTraces(tracesPath, firstPids, null, null, null);
5361            }
5362
5363            File lastTracesFile = null;
5364            File curTracesFile = null;
5365            for (int i=9; i>=0; i--) {
5366                String name = String.format(Locale.US, "slow%02d.txt", i);
5367                curTracesFile = new File(tracesDir, name);
5368                if (curTracesFile.exists()) {
5369                    if (lastTracesFile != null) {
5370                        curTracesFile.renameTo(lastTracesFile);
5371                    } else {
5372                        curTracesFile.delete();
5373                    }
5374                }
5375                lastTracesFile = curTracesFile;
5376            }
5377            tracesFile.renameTo(curTracesFile);
5378            if (tracesTmp.exists()) {
5379                tracesTmp.renameTo(tracesFile);
5380            }
5381        } finally {
5382            StrictMode.setThreadPolicy(oldPolicy);
5383        }
5384    }
5385
5386    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5387        if (!mLaunchWarningShown) {
5388            mLaunchWarningShown = true;
5389            mUiHandler.post(new Runnable() {
5390                @Override
5391                public void run() {
5392                    synchronized (ActivityManagerService.this) {
5393                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5394                        d.show();
5395                        mUiHandler.postDelayed(new Runnable() {
5396                            @Override
5397                            public void run() {
5398                                synchronized (ActivityManagerService.this) {
5399                                    d.dismiss();
5400                                    mLaunchWarningShown = false;
5401                                }
5402                            }
5403                        }, 4000);
5404                    }
5405                }
5406            });
5407        }
5408    }
5409
5410    @Override
5411    public boolean clearApplicationUserData(final String packageName,
5412            final IPackageDataObserver observer, int userId) {
5413        enforceNotIsolatedCaller("clearApplicationUserData");
5414        int uid = Binder.getCallingUid();
5415        int pid = Binder.getCallingPid();
5416        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5417                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5418
5419
5420        long callingId = Binder.clearCallingIdentity();
5421        try {
5422            IPackageManager pm = AppGlobals.getPackageManager();
5423            int pkgUid = -1;
5424            synchronized(this) {
5425                if (getPackageManagerInternalLocked().canPackageBeWiped(
5426                        userId, packageName)) {
5427                    throw new SecurityException(
5428                            "Cannot clear data for a device owner or a profile owner");
5429                }
5430
5431                try {
5432                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5433                } catch (RemoteException e) {
5434                }
5435                if (pkgUid == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    if (observer != null) {
5438                        try {
5439                            observer.onRemoveCompleted(packageName, false);
5440                        } catch (RemoteException e) {
5441                            Slog.i(TAG, "Observer no longer exists.");
5442                        }
5443                    }
5444                    return false;
5445                }
5446                if (uid == pkgUid || checkComponentPermission(
5447                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5448                        pid, uid, -1, true)
5449                        == PackageManager.PERMISSION_GRANTED) {
5450                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5451                } else {
5452                    throw new SecurityException("PID " + pid + " does not have permission "
5453                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5454                                    + " of package " + packageName);
5455                }
5456
5457                // Remove all tasks match the cleared application package and user
5458                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5459                    final TaskRecord tr = mRecentTasks.get(i);
5460                    final String taskPackageName =
5461                            tr.getBaseIntent().getComponent().getPackageName();
5462                    if (tr.userId != userId) continue;
5463                    if (!taskPackageName.equals(packageName)) continue;
5464                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5465                }
5466            }
5467
5468            final int pkgUidF = pkgUid;
5469            final int userIdF = userId;
5470            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5471                @Override
5472                public void onRemoveCompleted(String packageName, boolean succeeded)
5473                        throws RemoteException {
5474                    synchronized (ActivityManagerService.this) {
5475                        finishForceStopPackageLocked(packageName, pkgUidF);
5476                    }
5477
5478                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5479                            Uri.fromParts("package", packageName, null));
5480                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5481                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5482                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5483                            null, null, 0, null, null, null, null, false, false, userIdF);
5484
5485                    if (observer != null) {
5486                        observer.onRemoveCompleted(packageName, succeeded);
5487                    }
5488                }
5489            };
5490
5491            try {
5492                // Clear application user data
5493                pm.clearApplicationUserData(packageName, localObserver, userId);
5494
5495                synchronized(this) {
5496                    // Remove all permissions granted from/to this package
5497                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5498                }
5499
5500                // Remove all zen rules created by this package; revoke it's zen access.
5501                INotificationManager inm = NotificationManager.getService();
5502                inm.removeAutomaticZenRules(packageName);
5503                inm.setNotificationPolicyAccessGranted(packageName, false);
5504
5505            } catch (RemoteException e) {
5506            }
5507        } finally {
5508            Binder.restoreCallingIdentity(callingId);
5509        }
5510        return true;
5511    }
5512
5513    @Override
5514    public void killBackgroundProcesses(final String packageName, int userId) {
5515        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5516                != PackageManager.PERMISSION_GRANTED &&
5517                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5518                        != PackageManager.PERMISSION_GRANTED) {
5519            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5520                    + Binder.getCallingPid()
5521                    + ", uid=" + Binder.getCallingUid()
5522                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5523            Slog.w(TAG, msg);
5524            throw new SecurityException(msg);
5525        }
5526
5527        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5528                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5529        long callingId = Binder.clearCallingIdentity();
5530        try {
5531            IPackageManager pm = AppGlobals.getPackageManager();
5532            synchronized(this) {
5533                int appId = -1;
5534                try {
5535                    appId = UserHandle.getAppId(
5536                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5537                } catch (RemoteException e) {
5538                }
5539                if (appId == -1) {
5540                    Slog.w(TAG, "Invalid packageName: " + packageName);
5541                    return;
5542                }
5543                killPackageProcessesLocked(packageName, appId, userId,
5544                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5545            }
5546        } finally {
5547            Binder.restoreCallingIdentity(callingId);
5548        }
5549    }
5550
5551    @Override
5552    public void killAllBackgroundProcesses() {
5553        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5554                != PackageManager.PERMISSION_GRANTED) {
5555            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5556                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5558            Slog.w(TAG, msg);
5559            throw new SecurityException(msg);
5560        }
5561
5562        final long callingId = Binder.clearCallingIdentity();
5563        try {
5564            synchronized (this) {
5565                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5566                final int NP = mProcessNames.getMap().size();
5567                for (int ip = 0; ip < NP; ip++) {
5568                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5569                    final int NA = apps.size();
5570                    for (int ia = 0; ia < NA; ia++) {
5571                        final ProcessRecord app = apps.valueAt(ia);
5572                        if (app.persistent) {
5573                            // We don't kill persistent processes.
5574                            continue;
5575                        }
5576                        if (app.removed) {
5577                            procs.add(app);
5578                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5579                            app.removed = true;
5580                            procs.add(app);
5581                        }
5582                    }
5583                }
5584
5585                final int N = procs.size();
5586                for (int i = 0; i < N; i++) {
5587                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5588                }
5589
5590                mAllowLowerMemLevel = true;
5591
5592                updateOomAdjLocked();
5593                doLowMemReportIfNeededLocked(null);
5594            }
5595        } finally {
5596            Binder.restoreCallingIdentity(callingId);
5597        }
5598    }
5599
5600    /**
5601     * Kills all background processes, except those matching any of the
5602     * specified properties.
5603     *
5604     * @param minTargetSdk the target SDK version at or above which to preserve
5605     *                     processes, or {@code -1} to ignore the target SDK
5606     * @param maxProcState the process state at or below which to preserve
5607     *                     processes, or {@code -1} to ignore the process state
5608     */
5609    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5610        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5611                != PackageManager.PERMISSION_GRANTED) {
5612            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5613                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5614                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5615            Slog.w(TAG, msg);
5616            throw new SecurityException(msg);
5617        }
5618
5619        final long callingId = Binder.clearCallingIdentity();
5620        try {
5621            synchronized (this) {
5622                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5623                final int NP = mProcessNames.getMap().size();
5624                for (int ip = 0; ip < NP; ip++) {
5625                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5626                    final int NA = apps.size();
5627                    for (int ia = 0; ia < NA; ia++) {
5628                        final ProcessRecord app = apps.valueAt(ia);
5629                        if (app.removed) {
5630                            procs.add(app);
5631                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5632                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5633                            app.removed = true;
5634                            procs.add(app);
5635                        }
5636                    }
5637                }
5638
5639                final int N = procs.size();
5640                for (int i = 0; i < N; i++) {
5641                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5642                }
5643            }
5644        } finally {
5645            Binder.restoreCallingIdentity(callingId);
5646        }
5647    }
5648
5649    @Override
5650    public void forceStopPackage(final String packageName, int userId) {
5651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5652                != PackageManager.PERMISSION_GRANTED) {
5653            String msg = "Permission Denial: forceStopPackage() from pid="
5654                    + Binder.getCallingPid()
5655                    + ", uid=" + Binder.getCallingUid()
5656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5657            Slog.w(TAG, msg);
5658            throw new SecurityException(msg);
5659        }
5660        final int callingPid = Binder.getCallingPid();
5661        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5662                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5663        long callingId = Binder.clearCallingIdentity();
5664        try {
5665            IPackageManager pm = AppGlobals.getPackageManager();
5666            synchronized(this) {
5667                int[] users = userId == UserHandle.USER_ALL
5668                        ? mUserController.getUsers() : new int[] { userId };
5669                for (int user : users) {
5670                    int pkgUid = -1;
5671                    try {
5672                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5673                                user);
5674                    } catch (RemoteException e) {
5675                    }
5676                    if (pkgUid == -1) {
5677                        Slog.w(TAG, "Invalid packageName: " + packageName);
5678                        continue;
5679                    }
5680                    try {
5681                        pm.setPackageStoppedState(packageName, true, user);
5682                    } catch (RemoteException e) {
5683                    } catch (IllegalArgumentException e) {
5684                        Slog.w(TAG, "Failed trying to unstop package "
5685                                + packageName + ": " + e);
5686                    }
5687                    if (mUserController.isUserRunningLocked(user, 0)) {
5688                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5689                        finishForceStopPackageLocked(packageName, pkgUid);
5690                    }
5691                }
5692            }
5693        } finally {
5694            Binder.restoreCallingIdentity(callingId);
5695        }
5696    }
5697
5698    @Override
5699    public void addPackageDependency(String packageName) {
5700        synchronized (this) {
5701            int callingPid = Binder.getCallingPid();
5702            if (callingPid == Process.myPid()) {
5703                //  Yeah, um, no.
5704                return;
5705            }
5706            ProcessRecord proc;
5707            synchronized (mPidsSelfLocked) {
5708                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5709            }
5710            if (proc != null) {
5711                if (proc.pkgDeps == null) {
5712                    proc.pkgDeps = new ArraySet<String>(1);
5713                }
5714                proc.pkgDeps.add(packageName);
5715            }
5716        }
5717    }
5718
5719    /*
5720     * The pkg name and app id have to be specified.
5721     */
5722    @Override
5723    public void killApplication(String pkg, int appId, int userId, String reason) {
5724        if (pkg == null) {
5725            return;
5726        }
5727        // Make sure the uid is valid.
5728        if (appId < 0) {
5729            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5730            return;
5731        }
5732        int callerUid = Binder.getCallingUid();
5733        // Only the system server can kill an application
5734        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5735            // Post an aysnc message to kill the application
5736            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5737            msg.arg1 = appId;
5738            msg.arg2 = userId;
5739            Bundle bundle = new Bundle();
5740            bundle.putString("pkg", pkg);
5741            bundle.putString("reason", reason);
5742            msg.obj = bundle;
5743            mHandler.sendMessage(msg);
5744        } else {
5745            throw new SecurityException(callerUid + " cannot kill pkg: " +
5746                    pkg);
5747        }
5748    }
5749
5750    @Override
5751    public void closeSystemDialogs(String reason) {
5752        enforceNotIsolatedCaller("closeSystemDialogs");
5753
5754        final int pid = Binder.getCallingPid();
5755        final int uid = Binder.getCallingUid();
5756        final long origId = Binder.clearCallingIdentity();
5757        try {
5758            synchronized (this) {
5759                // Only allow this from foreground processes, so that background
5760                // applications can't abuse it to prevent system UI from being shown.
5761                if (uid >= Process.FIRST_APPLICATION_UID) {
5762                    ProcessRecord proc;
5763                    synchronized (mPidsSelfLocked) {
5764                        proc = mPidsSelfLocked.get(pid);
5765                    }
5766                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5767                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5768                                + " from background process " + proc);
5769                        return;
5770                    }
5771                }
5772                closeSystemDialogsLocked(reason);
5773            }
5774        } finally {
5775            Binder.restoreCallingIdentity(origId);
5776        }
5777    }
5778
5779    void closeSystemDialogsLocked(String reason) {
5780        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5781        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5782                | Intent.FLAG_RECEIVER_FOREGROUND);
5783        if (reason != null) {
5784            intent.putExtra("reason", reason);
5785        }
5786        mWindowManager.closeSystemDialogs(reason);
5787
5788        mStackSupervisor.closeSystemDialogsLocked();
5789
5790        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5791                AppOpsManager.OP_NONE, null, false, false,
5792                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5793    }
5794
5795    @Override
5796    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5797        enforceNotIsolatedCaller("getProcessMemoryInfo");
5798        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5799        for (int i=pids.length-1; i>=0; i--) {
5800            ProcessRecord proc;
5801            int oomAdj;
5802            synchronized (this) {
5803                synchronized (mPidsSelfLocked) {
5804                    proc = mPidsSelfLocked.get(pids[i]);
5805                    oomAdj = proc != null ? proc.setAdj : 0;
5806                }
5807            }
5808            infos[i] = new Debug.MemoryInfo();
5809            Debug.getMemoryInfo(pids[i], infos[i]);
5810            if (proc != null) {
5811                synchronized (this) {
5812                    if (proc.thread != null && proc.setAdj == oomAdj) {
5813                        // Record this for posterity if the process has been stable.
5814                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5815                                infos[i].getTotalUss(), false, proc.pkgList);
5816                    }
5817                }
5818            }
5819        }
5820        return infos;
5821    }
5822
5823    @Override
5824    public long[] getProcessPss(int[] pids) {
5825        enforceNotIsolatedCaller("getProcessPss");
5826        long[] pss = new long[pids.length];
5827        for (int i=pids.length-1; i>=0; i--) {
5828            ProcessRecord proc;
5829            int oomAdj;
5830            synchronized (this) {
5831                synchronized (mPidsSelfLocked) {
5832                    proc = mPidsSelfLocked.get(pids[i]);
5833                    oomAdj = proc != null ? proc.setAdj : 0;
5834                }
5835            }
5836            long[] tmpUss = new long[1];
5837            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5838            if (proc != null) {
5839                synchronized (this) {
5840                    if (proc.thread != null && proc.setAdj == oomAdj) {
5841                        // Record this for posterity if the process has been stable.
5842                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5843                    }
5844                }
5845            }
5846        }
5847        return pss;
5848    }
5849
5850    @Override
5851    public void killApplicationProcess(String processName, int uid) {
5852        if (processName == null) {
5853            return;
5854        }
5855
5856        int callerUid = Binder.getCallingUid();
5857        // Only the system server can kill an application
5858        if (callerUid == Process.SYSTEM_UID) {
5859            synchronized (this) {
5860                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5861                if (app != null && app.thread != null) {
5862                    try {
5863                        app.thread.scheduleSuicide();
5864                    } catch (RemoteException e) {
5865                        // If the other end already died, then our work here is done.
5866                    }
5867                } else {
5868                    Slog.w(TAG, "Process/uid not found attempting kill of "
5869                            + processName + " / " + uid);
5870                }
5871            }
5872        } else {
5873            throw new SecurityException(callerUid + " cannot kill app process: " +
5874                    processName);
5875        }
5876    }
5877
5878    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5879        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5880                false, true, false, false, UserHandle.getUserId(uid), reason);
5881    }
5882
5883    private void finishForceStopPackageLocked(final String packageName, int uid) {
5884        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5885                Uri.fromParts("package", packageName, null));
5886        if (!mProcessesReady) {
5887            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5888                    | Intent.FLAG_RECEIVER_FOREGROUND);
5889        }
5890        intent.putExtra(Intent.EXTRA_UID, uid);
5891        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5892        broadcastIntentLocked(null, null, intent,
5893                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5894                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5895    }
5896
5897
5898    private final boolean killPackageProcessesLocked(String packageName, int appId,
5899            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5900            boolean doit, boolean evenPersistent, String reason) {
5901        ArrayList<ProcessRecord> procs = new ArrayList<>();
5902
5903        // Remove all processes this package may have touched: all with the
5904        // same UID (except for the system or root user), and all whose name
5905        // matches the package name.
5906        final int NP = mProcessNames.getMap().size();
5907        for (int ip=0; ip<NP; ip++) {
5908            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5909            final int NA = apps.size();
5910            for (int ia=0; ia<NA; ia++) {
5911                ProcessRecord app = apps.valueAt(ia);
5912                if (app.persistent && !evenPersistent) {
5913                    // we don't kill persistent processes
5914                    continue;
5915                }
5916                if (app.removed) {
5917                    if (doit) {
5918                        procs.add(app);
5919                    }
5920                    continue;
5921                }
5922
5923                // Skip process if it doesn't meet our oom adj requirement.
5924                if (app.setAdj < minOomAdj) {
5925                    continue;
5926                }
5927
5928                // If no package is specified, we call all processes under the
5929                // give user id.
5930                if (packageName == null) {
5931                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5932                        continue;
5933                    }
5934                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5935                        continue;
5936                    }
5937                // Package has been specified, we want to hit all processes
5938                // that match it.  We need to qualify this by the processes
5939                // that are running under the specified app and user ID.
5940                } else {
5941                    final boolean isDep = app.pkgDeps != null
5942                            && app.pkgDeps.contains(packageName);
5943                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5944                        continue;
5945                    }
5946                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5947                        continue;
5948                    }
5949                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5950                        continue;
5951                    }
5952                }
5953
5954                // Process has passed all conditions, kill it!
5955                if (!doit) {
5956                    return true;
5957                }
5958                app.removed = true;
5959                procs.add(app);
5960            }
5961        }
5962
5963        int N = procs.size();
5964        for (int i=0; i<N; i++) {
5965            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5966        }
5967        updateOomAdjLocked();
5968        return N > 0;
5969    }
5970
5971    private void cleanupDisabledPackageComponentsLocked(
5972            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5973
5974        Set<String> disabledClasses = null;
5975        boolean packageDisabled = false;
5976        IPackageManager pm = AppGlobals.getPackageManager();
5977
5978        if (changedClasses == null) {
5979            // Nothing changed...
5980            return;
5981        }
5982
5983        // Determine enable/disable state of the package and its components.
5984        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5985        for (int i = changedClasses.length - 1; i >= 0; i--) {
5986            final String changedClass = changedClasses[i];
5987
5988            if (changedClass.equals(packageName)) {
5989                try {
5990                    // Entire package setting changed
5991                    enabled = pm.getApplicationEnabledSetting(packageName,
5992                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5993                } catch (Exception e) {
5994                    // No such package/component; probably racing with uninstall.  In any
5995                    // event it means we have nothing further to do here.
5996                    return;
5997                }
5998                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5999                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6000                if (packageDisabled) {
6001                    // Entire package is disabled.
6002                    // No need to continue to check component states.
6003                    disabledClasses = null;
6004                    break;
6005                }
6006            } else {
6007                try {
6008                    enabled = pm.getComponentEnabledSetting(
6009                            new ComponentName(packageName, changedClass),
6010                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6011                } catch (Exception e) {
6012                    // As above, probably racing with uninstall.
6013                    return;
6014                }
6015                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6016                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6017                    if (disabledClasses == null) {
6018                        disabledClasses = new ArraySet<>(changedClasses.length);
6019                    }
6020                    disabledClasses.add(changedClass);
6021                }
6022            }
6023        }
6024
6025        if (!packageDisabled && disabledClasses == null) {
6026            // Nothing to do here...
6027            return;
6028        }
6029
6030        // Clean-up disabled activities.
6031        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6032                packageName, disabledClasses, true, false, userId) && mBooted) {
6033            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6034            mStackSupervisor.scheduleIdleLocked();
6035        }
6036
6037        // Clean-up disabled tasks
6038        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6039
6040        // Clean-up disabled services.
6041        mServices.bringDownDisabledPackageServicesLocked(
6042                packageName, disabledClasses, userId, false, killProcess, true);
6043
6044        // Clean-up disabled providers.
6045        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6046        mProviderMap.collectPackageProvidersLocked(
6047                packageName, disabledClasses, true, false, userId, providers);
6048        for (int i = providers.size() - 1; i >= 0; i--) {
6049            removeDyingProviderLocked(null, providers.get(i), true);
6050        }
6051
6052        // Clean-up disabled broadcast receivers.
6053        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6054            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6055                    packageName, disabledClasses, userId, true);
6056        }
6057
6058    }
6059
6060    final boolean clearBroadcastQueueForUserLocked(int userId) {
6061        boolean didSomething = false;
6062        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6063            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6064                    null, null, userId, true);
6065        }
6066        return didSomething;
6067    }
6068
6069    final boolean forceStopPackageLocked(String packageName, int appId,
6070            boolean callerWillRestart, boolean purgeCache, boolean doit,
6071            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6072        int i;
6073
6074        if (userId == UserHandle.USER_ALL && packageName == null) {
6075            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6076        }
6077
6078        if (appId < 0 && packageName != null) {
6079            try {
6080                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6081                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6082            } catch (RemoteException e) {
6083            }
6084        }
6085
6086        if (doit) {
6087            if (packageName != null) {
6088                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6089                        + " user=" + userId + ": " + reason);
6090            } else {
6091                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6092            }
6093
6094            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6095        }
6096
6097        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6098                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6099                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6100
6101        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6102                packageName, null, doit, evenPersistent, userId)) {
6103            if (!doit) {
6104                return true;
6105            }
6106            didSomething = true;
6107        }
6108
6109        if (mServices.bringDownDisabledPackageServicesLocked(
6110                packageName, null, userId, evenPersistent, true, doit)) {
6111            if (!doit) {
6112                return true;
6113            }
6114            didSomething = true;
6115        }
6116
6117        if (packageName == null) {
6118            // Remove all sticky broadcasts from this user.
6119            mStickyBroadcasts.remove(userId);
6120        }
6121
6122        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6123        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6124                userId, providers)) {
6125            if (!doit) {
6126                return true;
6127            }
6128            didSomething = true;
6129        }
6130        for (i = providers.size() - 1; i >= 0; i--) {
6131            removeDyingProviderLocked(null, providers.get(i), true);
6132        }
6133
6134        // Remove transient permissions granted from/to this package/user
6135        removeUriPermissionsForPackageLocked(packageName, userId, false);
6136
6137        if (doit) {
6138            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6139                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6140                        packageName, null, userId, doit);
6141            }
6142        }
6143
6144        if (packageName == null || uninstalling) {
6145            // Remove pending intents.  For now we only do this when force
6146            // stopping users, because we have some problems when doing this
6147            // for packages -- app widgets are not currently cleaned up for
6148            // such packages, so they can be left with bad pending intents.
6149            if (mIntentSenderRecords.size() > 0) {
6150                Iterator<WeakReference<PendingIntentRecord>> it
6151                        = mIntentSenderRecords.values().iterator();
6152                while (it.hasNext()) {
6153                    WeakReference<PendingIntentRecord> wpir = it.next();
6154                    if (wpir == null) {
6155                        it.remove();
6156                        continue;
6157                    }
6158                    PendingIntentRecord pir = wpir.get();
6159                    if (pir == null) {
6160                        it.remove();
6161                        continue;
6162                    }
6163                    if (packageName == null) {
6164                        // Stopping user, remove all objects for the user.
6165                        if (pir.key.userId != userId) {
6166                            // Not the same user, skip it.
6167                            continue;
6168                        }
6169                    } else {
6170                        if (UserHandle.getAppId(pir.uid) != appId) {
6171                            // Different app id, skip it.
6172                            continue;
6173                        }
6174                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6175                            // Different user, skip it.
6176                            continue;
6177                        }
6178                        if (!pir.key.packageName.equals(packageName)) {
6179                            // Different package, skip it.
6180                            continue;
6181                        }
6182                    }
6183                    if (!doit) {
6184                        return true;
6185                    }
6186                    didSomething = true;
6187                    it.remove();
6188                    pir.canceled = true;
6189                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6190                        pir.key.activity.pendingResults.remove(pir.ref);
6191                    }
6192                }
6193            }
6194        }
6195
6196        if (doit) {
6197            if (purgeCache && packageName != null) {
6198                AttributeCache ac = AttributeCache.instance();
6199                if (ac != null) {
6200                    ac.removePackage(packageName);
6201                }
6202            }
6203            if (mBooted) {
6204                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6205                mStackSupervisor.scheduleIdleLocked();
6206            }
6207        }
6208
6209        return didSomething;
6210    }
6211
6212    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6213        ProcessRecord old = mProcessNames.remove(name, uid);
6214        if (old != null) {
6215            old.uidRecord.numProcs--;
6216            if (old.uidRecord.numProcs == 0) {
6217                // No more processes using this uid, tell clients it is gone.
6218                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6219                        "No more processes in " + old.uidRecord);
6220                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6221                mActiveUids.remove(uid);
6222                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6223            }
6224            old.uidRecord = null;
6225        }
6226        mIsolatedProcesses.remove(uid);
6227        return old;
6228    }
6229
6230    private final void addProcessNameLocked(ProcessRecord proc) {
6231        // We shouldn't already have a process under this name, but just in case we
6232        // need to clean up whatever may be there now.
6233        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6234        if (old == proc && proc.persistent) {
6235            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6236            Slog.w(TAG, "Re-adding persistent process " + proc);
6237        } else if (old != null) {
6238            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6239        }
6240        UidRecord uidRec = mActiveUids.get(proc.uid);
6241        if (uidRec == null) {
6242            uidRec = new UidRecord(proc.uid);
6243            // This is the first appearance of the uid, report it now!
6244            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6245                    "Creating new process uid: " + uidRec);
6246            mActiveUids.put(proc.uid, uidRec);
6247            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6248            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6249        }
6250        proc.uidRecord = uidRec;
6251        uidRec.numProcs++;
6252        mProcessNames.put(proc.processName, proc.uid, proc);
6253        if (proc.isolated) {
6254            mIsolatedProcesses.put(proc.uid, proc);
6255        }
6256    }
6257
6258    boolean removeProcessLocked(ProcessRecord app,
6259            boolean callerWillRestart, boolean allowRestart, String reason) {
6260        final String name = app.processName;
6261        final int uid = app.uid;
6262        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6263            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6264
6265        ProcessRecord old = mProcessNames.get(name, uid);
6266        if (old != app) {
6267            // This process is no longer active, so nothing to do.
6268            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6269            return false;
6270        }
6271        removeProcessNameLocked(name, uid);
6272        if (mHeavyWeightProcess == app) {
6273            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6274                    mHeavyWeightProcess.userId, 0));
6275            mHeavyWeightProcess = null;
6276        }
6277        boolean needRestart = false;
6278        if (app.pid > 0 && app.pid != MY_PID) {
6279            int pid = app.pid;
6280            synchronized (mPidsSelfLocked) {
6281                mPidsSelfLocked.remove(pid);
6282                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6283            }
6284            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6285            if (app.isolated) {
6286                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6287            }
6288            boolean willRestart = false;
6289            if (app.persistent && !app.isolated) {
6290                if (!callerWillRestart) {
6291                    willRestart = true;
6292                } else {
6293                    needRestart = true;
6294                }
6295            }
6296            app.kill(reason, true);
6297            handleAppDiedLocked(app, willRestart, allowRestart);
6298            if (willRestart) {
6299                removeLruProcessLocked(app);
6300                addAppLocked(app.info, false, null /* ABI override */);
6301            }
6302        } else {
6303            mRemovedProcesses.add(app);
6304        }
6305
6306        return needRestart;
6307    }
6308
6309    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6310        cleanupAppInLaunchingProvidersLocked(app, true);
6311        removeProcessLocked(app, false, true, "timeout publishing content providers");
6312    }
6313
6314    private final void processStartTimedOutLocked(ProcessRecord app) {
6315        final int pid = app.pid;
6316        boolean gone = false;
6317        synchronized (mPidsSelfLocked) {
6318            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6319            if (knownApp != null && knownApp.thread == null) {
6320                mPidsSelfLocked.remove(pid);
6321                gone = true;
6322            }
6323        }
6324
6325        if (gone) {
6326            Slog.w(TAG, "Process " + app + " failed to attach");
6327            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6328                    pid, app.uid, app.processName);
6329            removeProcessNameLocked(app.processName, app.uid);
6330            if (mHeavyWeightProcess == app) {
6331                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6332                        mHeavyWeightProcess.userId, 0));
6333                mHeavyWeightProcess = null;
6334            }
6335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6336            if (app.isolated) {
6337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6338            }
6339            // Take care of any launching providers waiting for this process.
6340            cleanupAppInLaunchingProvidersLocked(app, true);
6341            // Take care of any services that are waiting for the process.
6342            mServices.processStartTimedOutLocked(app);
6343            app.kill("start timeout", true);
6344            removeLruProcessLocked(app);
6345            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6346                Slog.w(TAG, "Unattached app died before backup, skipping");
6347                try {
6348                    IBackupManager bm = IBackupManager.Stub.asInterface(
6349                            ServiceManager.getService(Context.BACKUP_SERVICE));
6350                    bm.agentDisconnected(app.info.packageName);
6351                } catch (RemoteException e) {
6352                    // Can't happen; the backup manager is local
6353                }
6354            }
6355            if (isPendingBroadcastProcessLocked(pid)) {
6356                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6357                skipPendingBroadcastLocked(pid);
6358            }
6359        } else {
6360            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6361        }
6362    }
6363
6364    private final boolean attachApplicationLocked(IApplicationThread thread,
6365            int pid) {
6366
6367        // Find the application record that is being attached...  either via
6368        // the pid if we are running in multiple processes, or just pull the
6369        // next app record if we are emulating process with anonymous threads.
6370        ProcessRecord app;
6371        if (pid != MY_PID && pid >= 0) {
6372            synchronized (mPidsSelfLocked) {
6373                app = mPidsSelfLocked.get(pid);
6374            }
6375        } else {
6376            app = null;
6377        }
6378
6379        if (app == null) {
6380            Slog.w(TAG, "No pending application record for pid " + pid
6381                    + " (IApplicationThread " + thread + "); dropping process");
6382            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6383            if (pid > 0 && pid != MY_PID) {
6384                Process.killProcessQuiet(pid);
6385                //TODO: killProcessGroup(app.info.uid, pid);
6386            } else {
6387                try {
6388                    thread.scheduleExit();
6389                } catch (Exception e) {
6390                    // Ignore exceptions.
6391                }
6392            }
6393            return false;
6394        }
6395
6396        // If this application record is still attached to a previous
6397        // process, clean it up now.
6398        if (app.thread != null) {
6399            handleAppDiedLocked(app, true, true);
6400        }
6401
6402        // Tell the process all about itself.
6403
6404        if (DEBUG_ALL) Slog.v(
6405                TAG, "Binding process pid " + pid + " to record " + app);
6406
6407        final String processName = app.processName;
6408        try {
6409            AppDeathRecipient adr = new AppDeathRecipient(
6410                    app, pid, thread);
6411            thread.asBinder().linkToDeath(adr, 0);
6412            app.deathRecipient = adr;
6413        } catch (RemoteException e) {
6414            app.resetPackageList(mProcessStats);
6415            startProcessLocked(app, "link fail", processName);
6416            return false;
6417        }
6418
6419        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6420
6421        app.makeActive(thread, mProcessStats);
6422        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6423        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6424        app.forcingToForeground = null;
6425        updateProcessForegroundLocked(app, false, false);
6426        app.hasShownUi = false;
6427        app.debugging = false;
6428        app.cached = false;
6429        app.killedByAm = false;
6430        app.killed = false;
6431
6432
6433        // We carefully use the same state that PackageManager uses for
6434        // filtering, since we use this flag to decide if we need to install
6435        // providers when user is unlocked later
6436        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6437
6438        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6439
6440        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6441        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6442
6443        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6444            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6445            msg.obj = app;
6446            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6447        }
6448
6449        if (!normalMode) {
6450            Slog.i(TAG, "Launching preboot mode app: " + app);
6451        }
6452
6453        if (DEBUG_ALL) Slog.v(
6454            TAG, "New app record " + app
6455            + " thread=" + thread.asBinder() + " pid=" + pid);
6456        try {
6457            int testMode = IApplicationThread.DEBUG_OFF;
6458            if (mDebugApp != null && mDebugApp.equals(processName)) {
6459                testMode = mWaitForDebugger
6460                    ? IApplicationThread.DEBUG_WAIT
6461                    : IApplicationThread.DEBUG_ON;
6462                app.debugging = true;
6463                if (mDebugTransient) {
6464                    mDebugApp = mOrigDebugApp;
6465                    mWaitForDebugger = mOrigWaitForDebugger;
6466                }
6467            }
6468            String profileFile = app.instrumentationProfileFile;
6469            ParcelFileDescriptor profileFd = null;
6470            int samplingInterval = 0;
6471            boolean profileAutoStop = false;
6472            if (mProfileApp != null && mProfileApp.equals(processName)) {
6473                mProfileProc = app;
6474                profileFile = mProfileFile;
6475                profileFd = mProfileFd;
6476                samplingInterval = mSamplingInterval;
6477                profileAutoStop = mAutoStopProfiler;
6478            }
6479            boolean enableTrackAllocation = false;
6480            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6481                enableTrackAllocation = true;
6482                mTrackAllocationApp = null;
6483            }
6484
6485            // If the app is being launched for restore or full backup, set it up specially
6486            boolean isRestrictedBackupMode = false;
6487            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6488                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6489                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6490                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6491                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6492            }
6493
6494            if (app.instrumentationClass != null) {
6495                notifyPackageUse(app.instrumentationClass.getPackageName(),
6496                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6497            }
6498            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6499                    + processName + " with config " + mConfiguration);
6500            ApplicationInfo appInfo = app.instrumentationInfo != null
6501                    ? app.instrumentationInfo : app.info;
6502            app.compat = compatibilityInfoForPackageLocked(appInfo);
6503            if (profileFd != null) {
6504                profileFd = profileFd.dup();
6505            }
6506            ProfilerInfo profilerInfo = profileFile == null ? null
6507                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6508            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6509                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6510                    app.instrumentationUiAutomationConnection, testMode,
6511                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6512                    isRestrictedBackupMode || !normalMode, app.persistent,
6513                    new Configuration(mConfiguration), app.compat,
6514                    getCommonServicesLocked(app.isolated),
6515                    mCoreSettingsObserver.getCoreSettingsLocked());
6516            updateLruProcessLocked(app, false, null);
6517            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6518        } catch (Exception e) {
6519            // todo: Yikes!  What should we do?  For now we will try to
6520            // start another process, but that could easily get us in
6521            // an infinite loop of restarting processes...
6522            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6523
6524            app.resetPackageList(mProcessStats);
6525            app.unlinkDeathRecipient();
6526            startProcessLocked(app, "bind fail", processName);
6527            return false;
6528        }
6529
6530        // Remove this record from the list of starting applications.
6531        mPersistentStartingProcesses.remove(app);
6532        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6533                "Attach application locked removing on hold: " + app);
6534        mProcessesOnHold.remove(app);
6535
6536        boolean badApp = false;
6537        boolean didSomething = false;
6538
6539        // See if the top visible activity is waiting to run in this process...
6540        if (normalMode) {
6541            try {
6542                if (mStackSupervisor.attachApplicationLocked(app)) {
6543                    didSomething = true;
6544                }
6545            } catch (Exception e) {
6546                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6547                badApp = true;
6548            }
6549        }
6550
6551        // Find any services that should be running in this process...
6552        if (!badApp) {
6553            try {
6554                didSomething |= mServices.attachApplicationLocked(app, processName);
6555            } catch (Exception e) {
6556                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6557                badApp = true;
6558            }
6559        }
6560
6561        // Check if a next-broadcast receiver is in this process...
6562        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6563            try {
6564                didSomething |= sendPendingBroadcastsLocked(app);
6565            } catch (Exception e) {
6566                // If the app died trying to launch the receiver we declare it 'bad'
6567                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6568                badApp = true;
6569            }
6570        }
6571
6572        // Check whether the next backup agent is in this process...
6573        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6574            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6575                    "New app is backup target, launching agent for " + app);
6576            notifyPackageUse(mBackupTarget.appInfo.packageName,
6577                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6578            try {
6579                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6580                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6581                        mBackupTarget.backupMode);
6582            } catch (Exception e) {
6583                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6584                badApp = true;
6585            }
6586        }
6587
6588        if (badApp) {
6589            app.kill("error during init", true);
6590            handleAppDiedLocked(app, false, true);
6591            return false;
6592        }
6593
6594        if (!didSomething) {
6595            updateOomAdjLocked();
6596        }
6597
6598        return true;
6599    }
6600
6601    @Override
6602    public final void attachApplication(IApplicationThread thread) {
6603        synchronized (this) {
6604            int callingPid = Binder.getCallingPid();
6605            final long origId = Binder.clearCallingIdentity();
6606            attachApplicationLocked(thread, callingPid);
6607            Binder.restoreCallingIdentity(origId);
6608        }
6609    }
6610
6611    @Override
6612    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6613        final long origId = Binder.clearCallingIdentity();
6614        synchronized (this) {
6615            ActivityStack stack = ActivityRecord.getStackLocked(token);
6616            if (stack != null) {
6617                ActivityRecord r =
6618                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6619                if (stopProfiling) {
6620                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6621                        try {
6622                            mProfileFd.close();
6623                        } catch (IOException e) {
6624                        }
6625                        clearProfilerLocked();
6626                    }
6627                }
6628            }
6629        }
6630        Binder.restoreCallingIdentity(origId);
6631    }
6632
6633    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6634        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6635                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6636    }
6637
6638    void enableScreenAfterBoot() {
6639        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6640                SystemClock.uptimeMillis());
6641        mWindowManager.enableScreenAfterBoot();
6642
6643        synchronized (this) {
6644            updateEventDispatchingLocked();
6645        }
6646    }
6647
6648    @Override
6649    public void showBootMessage(final CharSequence msg, final boolean always) {
6650        if (Binder.getCallingUid() != Process.myUid()) {
6651            // These days only the core system can call this, so apps can't get in
6652            // the way of what we show about running them.
6653        }
6654        mWindowManager.showBootMessage(msg, always);
6655    }
6656
6657    @Override
6658    public void keyguardWaitingForActivityDrawn() {
6659        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6660        final long token = Binder.clearCallingIdentity();
6661        try {
6662            synchronized (this) {
6663                if (DEBUG_LOCKSCREEN) logLockScreen("");
6664                mWindowManager.keyguardWaitingForActivityDrawn();
6665                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6666                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6667                    updateSleepIfNeededLocked();
6668                }
6669            }
6670        } finally {
6671            Binder.restoreCallingIdentity(token);
6672        }
6673    }
6674
6675    @Override
6676    public void keyguardGoingAway(int flags) {
6677        enforceNotIsolatedCaller("keyguardGoingAway");
6678        final long token = Binder.clearCallingIdentity();
6679        try {
6680            synchronized (this) {
6681                if (DEBUG_LOCKSCREEN) logLockScreen("");
6682                mWindowManager.keyguardGoingAway(flags);
6683                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6684                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6685                    updateSleepIfNeededLocked();
6686
6687                    // Some stack visibility might change (e.g. docked stack)
6688                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6689                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6690                }
6691            }
6692        } finally {
6693            Binder.restoreCallingIdentity(token);
6694        }
6695    }
6696
6697    final void finishBooting() {
6698        synchronized (this) {
6699            if (!mBootAnimationComplete) {
6700                mCallFinishBooting = true;
6701                return;
6702            }
6703            mCallFinishBooting = false;
6704        }
6705
6706        ArraySet<String> completedIsas = new ArraySet<String>();
6707        for (String abi : Build.SUPPORTED_ABIS) {
6708            Process.establishZygoteConnectionForAbi(abi);
6709            final String instructionSet = VMRuntime.getInstructionSet(abi);
6710            if (!completedIsas.contains(instructionSet)) {
6711                try {
6712                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6713                } catch (InstallerException e) {
6714                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6715                            e.getMessage() +")");
6716                }
6717                completedIsas.add(instructionSet);
6718            }
6719        }
6720
6721        IntentFilter pkgFilter = new IntentFilter();
6722        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6723        pkgFilter.addDataScheme("package");
6724        mContext.registerReceiver(new BroadcastReceiver() {
6725            @Override
6726            public void onReceive(Context context, Intent intent) {
6727                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6728                if (pkgs != null) {
6729                    for (String pkg : pkgs) {
6730                        synchronized (ActivityManagerService.this) {
6731                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6732                                    0, "query restart")) {
6733                                setResultCode(Activity.RESULT_OK);
6734                                return;
6735                            }
6736                        }
6737                    }
6738                }
6739            }
6740        }, pkgFilter);
6741
6742        IntentFilter dumpheapFilter = new IntentFilter();
6743        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6744        mContext.registerReceiver(new BroadcastReceiver() {
6745            @Override
6746            public void onReceive(Context context, Intent intent) {
6747                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6748                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6749                } else {
6750                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6751                }
6752            }
6753        }, dumpheapFilter);
6754
6755        // Let system services know.
6756        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6757
6758        synchronized (this) {
6759            // Ensure that any processes we had put on hold are now started
6760            // up.
6761            final int NP = mProcessesOnHold.size();
6762            if (NP > 0) {
6763                ArrayList<ProcessRecord> procs =
6764                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6765                for (int ip=0; ip<NP; ip++) {
6766                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6767                            + procs.get(ip));
6768                    startProcessLocked(procs.get(ip), "on-hold", null);
6769                }
6770            }
6771
6772            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6773                // Start looking for apps that are abusing wake locks.
6774                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6775                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6776                // Tell anyone interested that we are done booting!
6777                SystemProperties.set("sys.boot_completed", "1");
6778
6779                // And trigger dev.bootcomplete if we are not showing encryption progress
6780                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6781                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6782                    SystemProperties.set("dev.bootcomplete", "1");
6783                }
6784                mUserController.sendBootCompletedLocked(
6785                        new IIntentReceiver.Stub() {
6786                            @Override
6787                            public void performReceive(Intent intent, int resultCode,
6788                                    String data, Bundle extras, boolean ordered,
6789                                    boolean sticky, int sendingUser) {
6790                                synchronized (ActivityManagerService.this) {
6791                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6792                                            true, false);
6793                                }
6794                            }
6795                        });
6796                scheduleStartProfilesLocked();
6797            }
6798        }
6799    }
6800
6801    @Override
6802    public void bootAnimationComplete() {
6803        final boolean callFinishBooting;
6804        synchronized (this) {
6805            callFinishBooting = mCallFinishBooting;
6806            mBootAnimationComplete = true;
6807        }
6808        if (callFinishBooting) {
6809            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6810            finishBooting();
6811            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6812        }
6813    }
6814
6815    final void ensureBootCompleted() {
6816        boolean booting;
6817        boolean enableScreen;
6818        synchronized (this) {
6819            booting = mBooting;
6820            mBooting = false;
6821            enableScreen = !mBooted;
6822            mBooted = true;
6823        }
6824
6825        if (booting) {
6826            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6827            finishBooting();
6828            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6829        }
6830
6831        if (enableScreen) {
6832            enableScreenAfterBoot();
6833        }
6834    }
6835
6836    @Override
6837    public final void activityResumed(IBinder token) {
6838        final long origId = Binder.clearCallingIdentity();
6839        synchronized(this) {
6840            ActivityStack stack = ActivityRecord.getStackLocked(token);
6841            if (stack != null) {
6842                stack.activityResumedLocked(token);
6843            }
6844        }
6845        Binder.restoreCallingIdentity(origId);
6846    }
6847
6848    @Override
6849    public final void activityPaused(IBinder token) {
6850        final long origId = Binder.clearCallingIdentity();
6851        synchronized(this) {
6852            ActivityStack stack = ActivityRecord.getStackLocked(token);
6853            if (stack != null) {
6854                stack.activityPausedLocked(token, false);
6855            }
6856        }
6857        Binder.restoreCallingIdentity(origId);
6858    }
6859
6860    @Override
6861    public final void activityStopped(IBinder token, Bundle icicle,
6862            PersistableBundle persistentState, CharSequence description) {
6863        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6864
6865        // Refuse possible leaked file descriptors
6866        if (icicle != null && icicle.hasFileDescriptors()) {
6867            throw new IllegalArgumentException("File descriptors passed in Bundle");
6868        }
6869
6870        final long origId = Binder.clearCallingIdentity();
6871
6872        synchronized (this) {
6873            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6874            if (r != null) {
6875                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6876            }
6877        }
6878
6879        trimApplications();
6880
6881        Binder.restoreCallingIdentity(origId);
6882    }
6883
6884    @Override
6885    public final void activityDestroyed(IBinder token) {
6886        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6887        synchronized (this) {
6888            ActivityStack stack = ActivityRecord.getStackLocked(token);
6889            if (stack != null) {
6890                stack.activityDestroyedLocked(token, "activityDestroyed");
6891            }
6892        }
6893    }
6894
6895    @Override
6896    public final void activityRelaunched(IBinder token) {
6897        final long origId = Binder.clearCallingIdentity();
6898        synchronized (this) {
6899            mStackSupervisor.activityRelaunchedLocked(token);
6900        }
6901        Binder.restoreCallingIdentity(origId);
6902    }
6903
6904    @Override
6905    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6906            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6907        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6908                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6909        synchronized (this) {
6910            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6911            if (record == null) {
6912                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6913                        + "found for: " + token);
6914            }
6915            record.setSizeConfigurations(horizontalSizeConfiguration,
6916                    verticalSizeConfigurations, smallestSizeConfigurations);
6917        }
6918    }
6919
6920    @Override
6921    public final void backgroundResourcesReleased(IBinder token) {
6922        final long origId = Binder.clearCallingIdentity();
6923        try {
6924            synchronized (this) {
6925                ActivityStack stack = ActivityRecord.getStackLocked(token);
6926                if (stack != null) {
6927                    stack.backgroundResourcesReleased();
6928                }
6929            }
6930        } finally {
6931            Binder.restoreCallingIdentity(origId);
6932        }
6933    }
6934
6935    @Override
6936    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6937        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6938    }
6939
6940    @Override
6941    public final void notifyEnterAnimationComplete(IBinder token) {
6942        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6943    }
6944
6945    @Override
6946    public String getCallingPackage(IBinder token) {
6947        synchronized (this) {
6948            ActivityRecord r = getCallingRecordLocked(token);
6949            return r != null ? r.info.packageName : null;
6950        }
6951    }
6952
6953    @Override
6954    public ComponentName getCallingActivity(IBinder token) {
6955        synchronized (this) {
6956            ActivityRecord r = getCallingRecordLocked(token);
6957            return r != null ? r.intent.getComponent() : null;
6958        }
6959    }
6960
6961    private ActivityRecord getCallingRecordLocked(IBinder token) {
6962        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6963        if (r == null) {
6964            return null;
6965        }
6966        return r.resultTo;
6967    }
6968
6969    @Override
6970    public ComponentName getActivityClassForToken(IBinder token) {
6971        synchronized(this) {
6972            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6973            if (r == null) {
6974                return null;
6975            }
6976            return r.intent.getComponent();
6977        }
6978    }
6979
6980    @Override
6981    public String getPackageForToken(IBinder token) {
6982        synchronized(this) {
6983            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6984            if (r == null) {
6985                return null;
6986            }
6987            return r.packageName;
6988        }
6989    }
6990
6991    @Override
6992    public boolean isRootVoiceInteraction(IBinder token) {
6993        synchronized(this) {
6994            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6995            if (r == null) {
6996                return false;
6997            }
6998            return r.rootVoiceInteraction;
6999        }
7000    }
7001
7002    @Override
7003    public IIntentSender getIntentSender(int type,
7004            String packageName, IBinder token, String resultWho,
7005            int requestCode, Intent[] intents, String[] resolvedTypes,
7006            int flags, Bundle bOptions, int userId) {
7007        enforceNotIsolatedCaller("getIntentSender");
7008        // Refuse possible leaked file descriptors
7009        if (intents != null) {
7010            if (intents.length < 1) {
7011                throw new IllegalArgumentException("Intents array length must be >= 1");
7012            }
7013            for (int i=0; i<intents.length; i++) {
7014                Intent intent = intents[i];
7015                if (intent != null) {
7016                    if (intent.hasFileDescriptors()) {
7017                        throw new IllegalArgumentException("File descriptors passed in Intent");
7018                    }
7019                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7020                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7021                        throw new IllegalArgumentException(
7022                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7023                    }
7024                    intents[i] = new Intent(intent);
7025                }
7026            }
7027            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7028                throw new IllegalArgumentException(
7029                        "Intent array length does not match resolvedTypes length");
7030            }
7031        }
7032        if (bOptions != null) {
7033            if (bOptions.hasFileDescriptors()) {
7034                throw new IllegalArgumentException("File descriptors passed in options");
7035            }
7036        }
7037
7038        synchronized(this) {
7039            int callingUid = Binder.getCallingUid();
7040            int origUserId = userId;
7041            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7042                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7043                    ALLOW_NON_FULL, "getIntentSender", null);
7044            if (origUserId == UserHandle.USER_CURRENT) {
7045                // We don't want to evaluate this until the pending intent is
7046                // actually executed.  However, we do want to always do the
7047                // security checking for it above.
7048                userId = UserHandle.USER_CURRENT;
7049            }
7050            try {
7051                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7052                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7053                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7054                    if (!UserHandle.isSameApp(callingUid, uid)) {
7055                        String msg = "Permission Denial: getIntentSender() from pid="
7056                            + Binder.getCallingPid()
7057                            + ", uid=" + Binder.getCallingUid()
7058                            + ", (need uid=" + uid + ")"
7059                            + " is not allowed to send as package " + packageName;
7060                        Slog.w(TAG, msg);
7061                        throw new SecurityException(msg);
7062                    }
7063                }
7064
7065                return getIntentSenderLocked(type, packageName, callingUid, userId,
7066                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7067
7068            } catch (RemoteException e) {
7069                throw new SecurityException(e);
7070            }
7071        }
7072    }
7073
7074    IIntentSender getIntentSenderLocked(int type, String packageName,
7075            int callingUid, int userId, IBinder token, String resultWho,
7076            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7077            Bundle bOptions) {
7078        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7079        ActivityRecord activity = null;
7080        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7081            activity = ActivityRecord.isInStackLocked(token);
7082            if (activity == null) {
7083                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7084                return null;
7085            }
7086            if (activity.finishing) {
7087                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7088                return null;
7089            }
7090        }
7091
7092        // We're going to be splicing together extras before sending, so we're
7093        // okay poking into any contained extras.
7094        if (intents != null) {
7095            for (int i = 0; i < intents.length; i++) {
7096                intents[i].setDefusable(true);
7097            }
7098        }
7099        Bundle.setDefusable(bOptions, true);
7100
7101        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7102        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7103        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7104        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7105                |PendingIntent.FLAG_UPDATE_CURRENT);
7106
7107        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7108                type, packageName, activity, resultWho,
7109                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7110        WeakReference<PendingIntentRecord> ref;
7111        ref = mIntentSenderRecords.get(key);
7112        PendingIntentRecord rec = ref != null ? ref.get() : null;
7113        if (rec != null) {
7114            if (!cancelCurrent) {
7115                if (updateCurrent) {
7116                    if (rec.key.requestIntent != null) {
7117                        rec.key.requestIntent.replaceExtras(intents != null ?
7118                                intents[intents.length - 1] : null);
7119                    }
7120                    if (intents != null) {
7121                        intents[intents.length-1] = rec.key.requestIntent;
7122                        rec.key.allIntents = intents;
7123                        rec.key.allResolvedTypes = resolvedTypes;
7124                    } else {
7125                        rec.key.allIntents = null;
7126                        rec.key.allResolvedTypes = null;
7127                    }
7128                }
7129                return rec;
7130            }
7131            rec.canceled = true;
7132            mIntentSenderRecords.remove(key);
7133        }
7134        if (noCreate) {
7135            return rec;
7136        }
7137        rec = new PendingIntentRecord(this, key, callingUid);
7138        mIntentSenderRecords.put(key, rec.ref);
7139        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7140            if (activity.pendingResults == null) {
7141                activity.pendingResults
7142                        = new HashSet<WeakReference<PendingIntentRecord>>();
7143            }
7144            activity.pendingResults.add(rec.ref);
7145        }
7146        return rec;
7147    }
7148
7149    @Override
7150    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7151            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7152        if (target instanceof PendingIntentRecord) {
7153            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7154                    finishedReceiver, requiredPermission, options);
7155        } else {
7156            if (intent == null) {
7157                // Weird case: someone has given us their own custom IIntentSender, and now
7158                // they have someone else trying to send to it but of course this isn't
7159                // really a PendingIntent, so there is no base Intent, and the caller isn't
7160                // supplying an Intent... but we never want to dispatch a null Intent to
7161                // a receiver, so um...  let's make something up.
7162                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7163                intent = new Intent(Intent.ACTION_MAIN);
7164            }
7165            try {
7166                target.send(code, intent, resolvedType, null, requiredPermission, options);
7167            } catch (RemoteException e) {
7168            }
7169            // Platform code can rely on getting a result back when the send is done, but if
7170            // this intent sender is from outside of the system we can't rely on it doing that.
7171            // So instead we don't give it the result receiver, and instead just directly
7172            // report the finish immediately.
7173            if (finishedReceiver != null) {
7174                try {
7175                    finishedReceiver.performReceive(intent, 0,
7176                            null, null, false, false, UserHandle.getCallingUserId());
7177                } catch (RemoteException e) {
7178                }
7179            }
7180            return 0;
7181        }
7182    }
7183
7184    /**
7185     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7186     *
7187     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7188     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7189     */
7190    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7191        if (DEBUG_WHITELISTS) {
7192            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7193                    + targetUid + ", " + duration + ")");
7194        }
7195        synchronized (mPidsSelfLocked) {
7196            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7197            if (pr == null) {
7198                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7199                return;
7200            }
7201            if (!pr.whitelistManager) {
7202                if (DEBUG_WHITELISTS) {
7203                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7204                            + callerPid + " is not allowed");
7205                }
7206                return;
7207            }
7208        }
7209
7210        final long token = Binder.clearCallingIdentity();
7211        try {
7212            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7213                    true, "pe from uid:" + callerUid);
7214        } finally {
7215            Binder.restoreCallingIdentity(token);
7216        }
7217    }
7218
7219    @Override
7220    public void cancelIntentSender(IIntentSender sender) {
7221        if (!(sender instanceof PendingIntentRecord)) {
7222            return;
7223        }
7224        synchronized(this) {
7225            PendingIntentRecord rec = (PendingIntentRecord)sender;
7226            try {
7227                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7228                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7229                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7230                    String msg = "Permission Denial: cancelIntentSender() from pid="
7231                        + Binder.getCallingPid()
7232                        + ", uid=" + Binder.getCallingUid()
7233                        + " is not allowed to cancel packges "
7234                        + rec.key.packageName;
7235                    Slog.w(TAG, msg);
7236                    throw new SecurityException(msg);
7237                }
7238            } catch (RemoteException e) {
7239                throw new SecurityException(e);
7240            }
7241            cancelIntentSenderLocked(rec, true);
7242        }
7243    }
7244
7245    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7246        rec.canceled = true;
7247        mIntentSenderRecords.remove(rec.key);
7248        if (cleanActivity && rec.key.activity != null) {
7249            rec.key.activity.pendingResults.remove(rec.ref);
7250        }
7251    }
7252
7253    @Override
7254    public String getPackageForIntentSender(IIntentSender pendingResult) {
7255        if (!(pendingResult instanceof PendingIntentRecord)) {
7256            return null;
7257        }
7258        try {
7259            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7260            return res.key.packageName;
7261        } catch (ClassCastException e) {
7262        }
7263        return null;
7264    }
7265
7266    @Override
7267    public int getUidForIntentSender(IIntentSender sender) {
7268        if (sender instanceof PendingIntentRecord) {
7269            try {
7270                PendingIntentRecord res = (PendingIntentRecord)sender;
7271                return res.uid;
7272            } catch (ClassCastException e) {
7273            }
7274        }
7275        return -1;
7276    }
7277
7278    @Override
7279    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7280        if (!(pendingResult instanceof PendingIntentRecord)) {
7281            return false;
7282        }
7283        try {
7284            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7285            if (res.key.allIntents == null) {
7286                return false;
7287            }
7288            for (int i=0; i<res.key.allIntents.length; i++) {
7289                Intent intent = res.key.allIntents[i];
7290                if (intent.getPackage() != null && intent.getComponent() != null) {
7291                    return false;
7292                }
7293            }
7294            return true;
7295        } catch (ClassCastException e) {
7296        }
7297        return false;
7298    }
7299
7300    @Override
7301    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7302        if (!(pendingResult instanceof PendingIntentRecord)) {
7303            return false;
7304        }
7305        try {
7306            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7307            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7308                return true;
7309            }
7310            return false;
7311        } catch (ClassCastException e) {
7312        }
7313        return false;
7314    }
7315
7316    @Override
7317    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7318        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7319                "getIntentForIntentSender()");
7320        if (!(pendingResult instanceof PendingIntentRecord)) {
7321            return null;
7322        }
7323        try {
7324            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7325            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7326        } catch (ClassCastException e) {
7327        }
7328        return null;
7329    }
7330
7331    @Override
7332    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7333        if (!(pendingResult instanceof PendingIntentRecord)) {
7334            return null;
7335        }
7336        try {
7337            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7338            synchronized (this) {
7339                return getTagForIntentSenderLocked(res, prefix);
7340            }
7341        } catch (ClassCastException e) {
7342        }
7343        return null;
7344    }
7345
7346    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7347        final Intent intent = res.key.requestIntent;
7348        if (intent != null) {
7349            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7350                    || res.lastTagPrefix.equals(prefix))) {
7351                return res.lastTag;
7352            }
7353            res.lastTagPrefix = prefix;
7354            final StringBuilder sb = new StringBuilder(128);
7355            if (prefix != null) {
7356                sb.append(prefix);
7357            }
7358            if (intent.getAction() != null) {
7359                sb.append(intent.getAction());
7360            } else if (intent.getComponent() != null) {
7361                intent.getComponent().appendShortString(sb);
7362            } else {
7363                sb.append("?");
7364            }
7365            return res.lastTag = sb.toString();
7366        }
7367        return null;
7368    }
7369
7370    @Override
7371    public void setProcessLimit(int max) {
7372        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7373                "setProcessLimit()");
7374        synchronized (this) {
7375            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7376            mProcessLimitOverride = max;
7377        }
7378        trimApplications();
7379    }
7380
7381    @Override
7382    public int getProcessLimit() {
7383        synchronized (this) {
7384            return mProcessLimitOverride;
7385        }
7386    }
7387
7388    void foregroundTokenDied(ForegroundToken token) {
7389        synchronized (ActivityManagerService.this) {
7390            synchronized (mPidsSelfLocked) {
7391                ForegroundToken cur
7392                    = mForegroundProcesses.get(token.pid);
7393                if (cur != token) {
7394                    return;
7395                }
7396                mForegroundProcesses.remove(token.pid);
7397                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7398                if (pr == null) {
7399                    return;
7400                }
7401                pr.forcingToForeground = null;
7402                updateProcessForegroundLocked(pr, false, false);
7403            }
7404            updateOomAdjLocked();
7405        }
7406    }
7407
7408    @Override
7409    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7410        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7411                "setProcessForeground()");
7412        synchronized(this) {
7413            boolean changed = false;
7414
7415            synchronized (mPidsSelfLocked) {
7416                ProcessRecord pr = mPidsSelfLocked.get(pid);
7417                if (pr == null && isForeground) {
7418                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7419                    return;
7420                }
7421                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7422                if (oldToken != null) {
7423                    oldToken.token.unlinkToDeath(oldToken, 0);
7424                    mForegroundProcesses.remove(pid);
7425                    if (pr != null) {
7426                        pr.forcingToForeground = null;
7427                    }
7428                    changed = true;
7429                }
7430                if (isForeground && token != null) {
7431                    ForegroundToken newToken = new ForegroundToken() {
7432                        @Override
7433                        public void binderDied() {
7434                            foregroundTokenDied(this);
7435                        }
7436                    };
7437                    newToken.pid = pid;
7438                    newToken.token = token;
7439                    try {
7440                        token.linkToDeath(newToken, 0);
7441                        mForegroundProcesses.put(pid, newToken);
7442                        pr.forcingToForeground = token;
7443                        changed = true;
7444                    } catch (RemoteException e) {
7445                        // If the process died while doing this, we will later
7446                        // do the cleanup with the process death link.
7447                    }
7448                }
7449            }
7450
7451            if (changed) {
7452                updateOomAdjLocked();
7453            }
7454        }
7455    }
7456
7457    @Override
7458    public boolean isAppForeground(int uid) throws RemoteException {
7459        synchronized (this) {
7460            UidRecord uidRec = mActiveUids.get(uid);
7461            if (uidRec == null || uidRec.idle) {
7462                return false;
7463            }
7464            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7465        }
7466    }
7467
7468    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7469    // be guarded by permission checking.
7470    int getUidState(int uid) {
7471        synchronized (this) {
7472            UidRecord uidRec = mActiveUids.get(uid);
7473            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7474        }
7475    }
7476
7477    @Override
7478    public boolean isInMultiWindowMode(IBinder token) {
7479        final long origId = Binder.clearCallingIdentity();
7480        try {
7481            synchronized(this) {
7482                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7483                if (r == null) {
7484                    return false;
7485                }
7486                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7487                return !r.task.mFullscreen;
7488            }
7489        } finally {
7490            Binder.restoreCallingIdentity(origId);
7491        }
7492    }
7493
7494    @Override
7495    public boolean isInPictureInPictureMode(IBinder token) {
7496        final long origId = Binder.clearCallingIdentity();
7497        try {
7498            synchronized(this) {
7499                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7500                if (stack == null) {
7501                    return false;
7502                }
7503                return stack.mStackId == PINNED_STACK_ID;
7504            }
7505        } finally {
7506            Binder.restoreCallingIdentity(origId);
7507        }
7508    }
7509
7510    @Override
7511    public void enterPictureInPictureMode(IBinder token) {
7512        final long origId = Binder.clearCallingIdentity();
7513        try {
7514            synchronized(this) {
7515                if (!mSupportsPictureInPicture) {
7516                    throw new IllegalStateException("enterPictureInPictureMode: "
7517                            + "Device doesn't support picture-in-picture mode.");
7518                }
7519
7520                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7521
7522                if (r == null) {
7523                    throw new IllegalStateException("enterPictureInPictureMode: "
7524                            + "Can't find activity for token=" + token);
7525                }
7526
7527                if (!r.supportsPictureInPicture()) {
7528                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7529                            + "Picture-In-Picture not supported for r=" + r);
7530                }
7531
7532                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7533                // current bounds.
7534                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7535                final Rect bounds = (pinnedStack != null)
7536                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7537
7538                mStackSupervisor.moveActivityToPinnedStackLocked(
7539                        r, "enterPictureInPictureMode", bounds);
7540            }
7541        } finally {
7542            Binder.restoreCallingIdentity(origId);
7543        }
7544    }
7545
7546    // =========================================================
7547    // PROCESS INFO
7548    // =========================================================
7549
7550    static class ProcessInfoService extends IProcessInfoService.Stub {
7551        final ActivityManagerService mActivityManagerService;
7552        ProcessInfoService(ActivityManagerService activityManagerService) {
7553            mActivityManagerService = activityManagerService;
7554        }
7555
7556        @Override
7557        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7558            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7559                    /*in*/ pids, /*out*/ states, null);
7560        }
7561
7562        @Override
7563        public void getProcessStatesAndOomScoresFromPids(
7564                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7565            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7566                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7567        }
7568    }
7569
7570    /**
7571     * For each PID in the given input array, write the current process state
7572     * for that process into the states array, or -1 to indicate that no
7573     * process with the given PID exists. If scores array is provided, write
7574     * the oom score for the process into the scores array, with INVALID_ADJ
7575     * indicating the PID doesn't exist.
7576     */
7577    public void getProcessStatesAndOomScoresForPIDs(
7578            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7579        if (scores != null) {
7580            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7581                    "getProcessStatesAndOomScoresForPIDs()");
7582        }
7583
7584        if (pids == null) {
7585            throw new NullPointerException("pids");
7586        } else if (states == null) {
7587            throw new NullPointerException("states");
7588        } else if (pids.length != states.length) {
7589            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7590        } else if (scores != null && pids.length != scores.length) {
7591            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7592        }
7593
7594        synchronized (mPidsSelfLocked) {
7595            for (int i = 0; i < pids.length; i++) {
7596                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7597                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7598                        pr.curProcState;
7599                if (scores != null) {
7600                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7601                }
7602            }
7603        }
7604    }
7605
7606    // =========================================================
7607    // PERMISSIONS
7608    // =========================================================
7609
7610    static class PermissionController extends IPermissionController.Stub {
7611        ActivityManagerService mActivityManagerService;
7612        PermissionController(ActivityManagerService activityManagerService) {
7613            mActivityManagerService = activityManagerService;
7614        }
7615
7616        @Override
7617        public boolean checkPermission(String permission, int pid, int uid) {
7618            return mActivityManagerService.checkPermission(permission, pid,
7619                    uid) == PackageManager.PERMISSION_GRANTED;
7620        }
7621
7622        @Override
7623        public String[] getPackagesForUid(int uid) {
7624            return mActivityManagerService.mContext.getPackageManager()
7625                    .getPackagesForUid(uid);
7626        }
7627
7628        @Override
7629        public boolean isRuntimePermission(String permission) {
7630            try {
7631                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7632                        .getPermissionInfo(permission, 0);
7633                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7634            } catch (NameNotFoundException nnfe) {
7635                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7636            }
7637            return false;
7638        }
7639    }
7640
7641    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7642        @Override
7643        public int checkComponentPermission(String permission, int pid, int uid,
7644                int owningUid, boolean exported) {
7645            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7646                    owningUid, exported);
7647        }
7648
7649        @Override
7650        public Object getAMSLock() {
7651            return ActivityManagerService.this;
7652        }
7653    }
7654
7655    /**
7656     * This can be called with or without the global lock held.
7657     */
7658    int checkComponentPermission(String permission, int pid, int uid,
7659            int owningUid, boolean exported) {
7660        if (pid == MY_PID) {
7661            return PackageManager.PERMISSION_GRANTED;
7662        }
7663        return ActivityManager.checkComponentPermission(permission, uid,
7664                owningUid, exported);
7665    }
7666
7667    /**
7668     * As the only public entry point for permissions checking, this method
7669     * can enforce the semantic that requesting a check on a null global
7670     * permission is automatically denied.  (Internally a null permission
7671     * string is used when calling {@link #checkComponentPermission} in cases
7672     * when only uid-based security is needed.)
7673     *
7674     * This can be called with or without the global lock held.
7675     */
7676    @Override
7677    public int checkPermission(String permission, int pid, int uid) {
7678        if (permission == null) {
7679            return PackageManager.PERMISSION_DENIED;
7680        }
7681        return checkComponentPermission(permission, pid, uid, -1, true);
7682    }
7683
7684    @Override
7685    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7686        if (permission == null) {
7687            return PackageManager.PERMISSION_DENIED;
7688        }
7689
7690        // We might be performing an operation on behalf of an indirect binder
7691        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7692        // client identity accordingly before proceeding.
7693        Identity tlsIdentity = sCallerIdentity.get();
7694        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7695            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7696                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7697            uid = tlsIdentity.uid;
7698            pid = tlsIdentity.pid;
7699        }
7700
7701        return checkComponentPermission(permission, pid, uid, -1, true);
7702    }
7703
7704    /**
7705     * Binder IPC calls go through the public entry point.
7706     * This can be called with or without the global lock held.
7707     */
7708    int checkCallingPermission(String permission) {
7709        return checkPermission(permission,
7710                Binder.getCallingPid(),
7711                UserHandle.getAppId(Binder.getCallingUid()));
7712    }
7713
7714    /**
7715     * This can be called with or without the global lock held.
7716     */
7717    void enforceCallingPermission(String permission, String func) {
7718        if (checkCallingPermission(permission)
7719                == PackageManager.PERMISSION_GRANTED) {
7720            return;
7721        }
7722
7723        String msg = "Permission Denial: " + func + " from pid="
7724                + Binder.getCallingPid()
7725                + ", uid=" + Binder.getCallingUid()
7726                + " requires " + permission;
7727        Slog.w(TAG, msg);
7728        throw new SecurityException(msg);
7729    }
7730
7731    /**
7732     * Determine if UID is holding permissions required to access {@link Uri} in
7733     * the given {@link ProviderInfo}. Final permission checking is always done
7734     * in {@link ContentProvider}.
7735     */
7736    private final boolean checkHoldingPermissionsLocked(
7737            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7738        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7739                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7740        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7741            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7742                    != PERMISSION_GRANTED) {
7743                return false;
7744            }
7745        }
7746        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7747    }
7748
7749    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7750            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7751        if (pi.applicationInfo.uid == uid) {
7752            return true;
7753        } else if (!pi.exported) {
7754            return false;
7755        }
7756
7757        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7758        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7759        try {
7760            // check if target holds top-level <provider> permissions
7761            if (!readMet && pi.readPermission != null && considerUidPermissions
7762                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7763                readMet = true;
7764            }
7765            if (!writeMet && pi.writePermission != null && considerUidPermissions
7766                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7767                writeMet = true;
7768            }
7769
7770            // track if unprotected read/write is allowed; any denied
7771            // <path-permission> below removes this ability
7772            boolean allowDefaultRead = pi.readPermission == null;
7773            boolean allowDefaultWrite = pi.writePermission == null;
7774
7775            // check if target holds any <path-permission> that match uri
7776            final PathPermission[] pps = pi.pathPermissions;
7777            if (pps != null) {
7778                final String path = grantUri.uri.getPath();
7779                int i = pps.length;
7780                while (i > 0 && (!readMet || !writeMet)) {
7781                    i--;
7782                    PathPermission pp = pps[i];
7783                    if (pp.match(path)) {
7784                        if (!readMet) {
7785                            final String pprperm = pp.getReadPermission();
7786                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7787                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7788                                    + ": match=" + pp.match(path)
7789                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7790                            if (pprperm != null) {
7791                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7792                                        == PERMISSION_GRANTED) {
7793                                    readMet = true;
7794                                } else {
7795                                    allowDefaultRead = false;
7796                                }
7797                            }
7798                        }
7799                        if (!writeMet) {
7800                            final String ppwperm = pp.getWritePermission();
7801                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7802                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7803                                    + ": match=" + pp.match(path)
7804                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7805                            if (ppwperm != null) {
7806                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7807                                        == PERMISSION_GRANTED) {
7808                                    writeMet = true;
7809                                } else {
7810                                    allowDefaultWrite = false;
7811                                }
7812                            }
7813                        }
7814                    }
7815                }
7816            }
7817
7818            // grant unprotected <provider> read/write, if not blocked by
7819            // <path-permission> above
7820            if (allowDefaultRead) readMet = true;
7821            if (allowDefaultWrite) writeMet = true;
7822
7823        } catch (RemoteException e) {
7824            return false;
7825        }
7826
7827        return readMet && writeMet;
7828    }
7829
7830    public int getAppStartMode(int uid, String packageName) {
7831        synchronized (this) {
7832            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7833        }
7834    }
7835
7836    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7837            boolean allowWhenForeground) {
7838        UidRecord uidRec = mActiveUids.get(uid);
7839        if (!mLenientBackgroundCheck) {
7840            if (!allowWhenForeground || uidRec == null
7841                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7842                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7843                        packageName) != AppOpsManager.MODE_ALLOWED) {
7844                    return ActivityManager.APP_START_MODE_DELAYED;
7845                }
7846            }
7847
7848        } else if (uidRec == null || uidRec.idle) {
7849            if (callingPid >= 0) {
7850                ProcessRecord proc;
7851                synchronized (mPidsSelfLocked) {
7852                    proc = mPidsSelfLocked.get(callingPid);
7853                }
7854                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7855                    // Whoever is instigating this is in the foreground, so we will allow it
7856                    // to go through.
7857                    return ActivityManager.APP_START_MODE_NORMAL;
7858                }
7859            }
7860            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7861                    != AppOpsManager.MODE_ALLOWED) {
7862                return ActivityManager.APP_START_MODE_DELAYED;
7863            }
7864        }
7865        return ActivityManager.APP_START_MODE_NORMAL;
7866    }
7867
7868    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7869        ProviderInfo pi = null;
7870        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7871        if (cpr != null) {
7872            pi = cpr.info;
7873        } else {
7874            try {
7875                pi = AppGlobals.getPackageManager().resolveContentProvider(
7876                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7877                        userHandle);
7878            } catch (RemoteException ex) {
7879            }
7880        }
7881        return pi;
7882    }
7883
7884    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7885        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7886        if (targetUris != null) {
7887            return targetUris.get(grantUri);
7888        }
7889        return null;
7890    }
7891
7892    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7893            String targetPkg, int targetUid, GrantUri grantUri) {
7894        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7895        if (targetUris == null) {
7896            targetUris = Maps.newArrayMap();
7897            mGrantedUriPermissions.put(targetUid, targetUris);
7898        }
7899
7900        UriPermission perm = targetUris.get(grantUri);
7901        if (perm == null) {
7902            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7903            targetUris.put(grantUri, perm);
7904        }
7905
7906        return perm;
7907    }
7908
7909    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7910            final int modeFlags) {
7911        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7912        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7913                : UriPermission.STRENGTH_OWNED;
7914
7915        // Root gets to do everything.
7916        if (uid == 0) {
7917            return true;
7918        }
7919
7920        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7921        if (perms == null) return false;
7922
7923        // First look for exact match
7924        final UriPermission exactPerm = perms.get(grantUri);
7925        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7926            return true;
7927        }
7928
7929        // No exact match, look for prefixes
7930        final int N = perms.size();
7931        for (int i = 0; i < N; i++) {
7932            final UriPermission perm = perms.valueAt(i);
7933            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7934                    && perm.getStrength(modeFlags) >= minStrength) {
7935                return true;
7936            }
7937        }
7938
7939        return false;
7940    }
7941
7942    /**
7943     * @param uri This uri must NOT contain an embedded userId.
7944     * @param userId The userId in which the uri is to be resolved.
7945     */
7946    @Override
7947    public int checkUriPermission(Uri uri, int pid, int uid,
7948            final int modeFlags, int userId, IBinder callerToken) {
7949        enforceNotIsolatedCaller("checkUriPermission");
7950
7951        // Another redirected-binder-call permissions check as in
7952        // {@link checkPermissionWithToken}.
7953        Identity tlsIdentity = sCallerIdentity.get();
7954        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7955            uid = tlsIdentity.uid;
7956            pid = tlsIdentity.pid;
7957        }
7958
7959        // Our own process gets to do everything.
7960        if (pid == MY_PID) {
7961            return PackageManager.PERMISSION_GRANTED;
7962        }
7963        synchronized (this) {
7964            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7965                    ? PackageManager.PERMISSION_GRANTED
7966                    : PackageManager.PERMISSION_DENIED;
7967        }
7968    }
7969
7970    /**
7971     * Check if the targetPkg can be granted permission to access uri by
7972     * the callingUid using the given modeFlags.  Throws a security exception
7973     * if callingUid is not allowed to do this.  Returns the uid of the target
7974     * if the URI permission grant should be performed; returns -1 if it is not
7975     * needed (for example targetPkg already has permission to access the URI).
7976     * If you already know the uid of the target, you can supply it in
7977     * lastTargetUid else set that to -1.
7978     */
7979    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7980            final int modeFlags, int lastTargetUid) {
7981        if (!Intent.isAccessUriMode(modeFlags)) {
7982            return -1;
7983        }
7984
7985        if (targetPkg != null) {
7986            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7987                    "Checking grant " + targetPkg + " permission to " + grantUri);
7988        }
7989
7990        final IPackageManager pm = AppGlobals.getPackageManager();
7991
7992        // If this is not a content: uri, we can't do anything with it.
7993        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7994            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7995                    "Can't grant URI permission for non-content URI: " + grantUri);
7996            return -1;
7997        }
7998
7999        final String authority = grantUri.uri.getAuthority();
8000        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8001                MATCH_DEBUG_TRIAGED_MISSING);
8002        if (pi == null) {
8003            Slog.w(TAG, "No content provider found for permission check: " +
8004                    grantUri.uri.toSafeString());
8005            return -1;
8006        }
8007
8008        int targetUid = lastTargetUid;
8009        if (targetUid < 0 && targetPkg != null) {
8010            try {
8011                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8012                        UserHandle.getUserId(callingUid));
8013                if (targetUid < 0) {
8014                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015                            "Can't grant URI permission no uid for: " + targetPkg);
8016                    return -1;
8017                }
8018            } catch (RemoteException ex) {
8019                return -1;
8020            }
8021        }
8022
8023        if (targetUid >= 0) {
8024            // First...  does the target actually need this permission?
8025            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8026                // No need to grant the target this permission.
8027                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8028                        "Target " + targetPkg + " already has full permission to " + grantUri);
8029                return -1;
8030            }
8031        } else {
8032            // First...  there is no target package, so can anyone access it?
8033            boolean allowed = pi.exported;
8034            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8035                if (pi.readPermission != null) {
8036                    allowed = false;
8037                }
8038            }
8039            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8040                if (pi.writePermission != null) {
8041                    allowed = false;
8042                }
8043            }
8044            if (allowed) {
8045                return -1;
8046            }
8047        }
8048
8049        /* There is a special cross user grant if:
8050         * - The target is on another user.
8051         * - Apps on the current user can access the uri without any uid permissions.
8052         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8053         * grant uri permissions.
8054         */
8055        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8056                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8057                modeFlags, false /*without considering the uid permissions*/);
8058
8059        // Second...  is the provider allowing granting of URI permissions?
8060        if (!specialCrossUserGrant) {
8061            if (!pi.grantUriPermissions) {
8062                throw new SecurityException("Provider " + pi.packageName
8063                        + "/" + pi.name
8064                        + " does not allow granting of Uri permissions (uri "
8065                        + grantUri + ")");
8066            }
8067            if (pi.uriPermissionPatterns != null) {
8068                final int N = pi.uriPermissionPatterns.length;
8069                boolean allowed = false;
8070                for (int i=0; i<N; i++) {
8071                    if (pi.uriPermissionPatterns[i] != null
8072                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8073                        allowed = true;
8074                        break;
8075                    }
8076                }
8077                if (!allowed) {
8078                    throw new SecurityException("Provider " + pi.packageName
8079                            + "/" + pi.name
8080                            + " does not allow granting of permission to path of Uri "
8081                            + grantUri);
8082                }
8083            }
8084        }
8085
8086        // Third...  does the caller itself have permission to access
8087        // this uri?
8088        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8089            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8090                // Require they hold a strong enough Uri permission
8091                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8092                    throw new SecurityException("Uid " + callingUid
8093                            + " does not have permission to uri " + grantUri);
8094                }
8095            }
8096        }
8097        return targetUid;
8098    }
8099
8100    /**
8101     * @param uri This uri must NOT contain an embedded userId.
8102     * @param userId The userId in which the uri is to be resolved.
8103     */
8104    @Override
8105    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8106            final int modeFlags, int userId) {
8107        enforceNotIsolatedCaller("checkGrantUriPermission");
8108        synchronized(this) {
8109            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8110                    new GrantUri(userId, uri, false), modeFlags, -1);
8111        }
8112    }
8113
8114    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8115            final int modeFlags, UriPermissionOwner owner) {
8116        if (!Intent.isAccessUriMode(modeFlags)) {
8117            return;
8118        }
8119
8120        // So here we are: the caller has the assumed permission
8121        // to the uri, and the target doesn't.  Let's now give this to
8122        // the target.
8123
8124        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8125                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8126
8127        final String authority = grantUri.uri.getAuthority();
8128        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8129                MATCH_DEBUG_TRIAGED_MISSING);
8130        if (pi == null) {
8131            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8132            return;
8133        }
8134
8135        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8136            grantUri.prefix = true;
8137        }
8138        final UriPermission perm = findOrCreateUriPermissionLocked(
8139                pi.packageName, targetPkg, targetUid, grantUri);
8140        perm.grantModes(modeFlags, owner);
8141    }
8142
8143    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8144            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8145        if (targetPkg == null) {
8146            throw new NullPointerException("targetPkg");
8147        }
8148        int targetUid;
8149        final IPackageManager pm = AppGlobals.getPackageManager();
8150        try {
8151            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8152        } catch (RemoteException ex) {
8153            return;
8154        }
8155
8156        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8157                targetUid);
8158        if (targetUid < 0) {
8159            return;
8160        }
8161
8162        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8163                owner);
8164    }
8165
8166    static class NeededUriGrants extends ArrayList<GrantUri> {
8167        final String targetPkg;
8168        final int targetUid;
8169        final int flags;
8170
8171        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8172            this.targetPkg = targetPkg;
8173            this.targetUid = targetUid;
8174            this.flags = flags;
8175        }
8176    }
8177
8178    /**
8179     * Like checkGrantUriPermissionLocked, but takes an Intent.
8180     */
8181    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8182            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8183        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8184                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8185                + " clip=" + (intent != null ? intent.getClipData() : null)
8186                + " from " + intent + "; flags=0x"
8187                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8188
8189        if (targetPkg == null) {
8190            throw new NullPointerException("targetPkg");
8191        }
8192
8193        if (intent == null) {
8194            return null;
8195        }
8196        Uri data = intent.getData();
8197        ClipData clip = intent.getClipData();
8198        if (data == null && clip == null) {
8199            return null;
8200        }
8201        // Default userId for uris in the intent (if they don't specify it themselves)
8202        int contentUserHint = intent.getContentUserHint();
8203        if (contentUserHint == UserHandle.USER_CURRENT) {
8204            contentUserHint = UserHandle.getUserId(callingUid);
8205        }
8206        final IPackageManager pm = AppGlobals.getPackageManager();
8207        int targetUid;
8208        if (needed != null) {
8209            targetUid = needed.targetUid;
8210        } else {
8211            try {
8212                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8213                        targetUserId);
8214            } catch (RemoteException ex) {
8215                return null;
8216            }
8217            if (targetUid < 0) {
8218                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8219                        "Can't grant URI permission no uid for: " + targetPkg
8220                        + " on user " + targetUserId);
8221                return null;
8222            }
8223        }
8224        if (data != null) {
8225            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8226            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8227                    targetUid);
8228            if (targetUid > 0) {
8229                if (needed == null) {
8230                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8231                }
8232                needed.add(grantUri);
8233            }
8234        }
8235        if (clip != null) {
8236            for (int i=0; i<clip.getItemCount(); i++) {
8237                Uri uri = clip.getItemAt(i).getUri();
8238                if (uri != null) {
8239                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8240                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8241                            targetUid);
8242                    if (targetUid > 0) {
8243                        if (needed == null) {
8244                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8245                        }
8246                        needed.add(grantUri);
8247                    }
8248                } else {
8249                    Intent clipIntent = clip.getItemAt(i).getIntent();
8250                    if (clipIntent != null) {
8251                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8252                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8253                        if (newNeeded != null) {
8254                            needed = newNeeded;
8255                        }
8256                    }
8257                }
8258            }
8259        }
8260
8261        return needed;
8262    }
8263
8264    /**
8265     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8266     */
8267    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8268            UriPermissionOwner owner) {
8269        if (needed != null) {
8270            for (int i=0; i<needed.size(); i++) {
8271                GrantUri grantUri = needed.get(i);
8272                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8273                        grantUri, needed.flags, owner);
8274            }
8275        }
8276    }
8277
8278    void grantUriPermissionFromIntentLocked(int callingUid,
8279            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8280        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8281                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8282        if (needed == null) {
8283            return;
8284        }
8285
8286        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8287    }
8288
8289    /**
8290     * @param uri This uri must NOT contain an embedded userId.
8291     * @param userId The userId in which the uri is to be resolved.
8292     */
8293    @Override
8294    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8295            final int modeFlags, int userId) {
8296        enforceNotIsolatedCaller("grantUriPermission");
8297        GrantUri grantUri = new GrantUri(userId, uri, false);
8298        synchronized(this) {
8299            final ProcessRecord r = getRecordForAppLocked(caller);
8300            if (r == null) {
8301                throw new SecurityException("Unable to find app for caller "
8302                        + caller
8303                        + " when granting permission to uri " + grantUri);
8304            }
8305            if (targetPkg == null) {
8306                throw new IllegalArgumentException("null target");
8307            }
8308            if (grantUri == null) {
8309                throw new IllegalArgumentException("null uri");
8310            }
8311
8312            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8313                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8314                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8315                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8316
8317            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8318                    UserHandle.getUserId(r.uid));
8319        }
8320    }
8321
8322    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8323        if (perm.modeFlags == 0) {
8324            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8325                    perm.targetUid);
8326            if (perms != null) {
8327                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8328                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8329
8330                perms.remove(perm.uri);
8331                if (perms.isEmpty()) {
8332                    mGrantedUriPermissions.remove(perm.targetUid);
8333                }
8334            }
8335        }
8336    }
8337
8338    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8339        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8340                "Revoking all granted permissions to " + grantUri);
8341
8342        final IPackageManager pm = AppGlobals.getPackageManager();
8343        final String authority = grantUri.uri.getAuthority();
8344        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8345                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8346        if (pi == null) {
8347            Slog.w(TAG, "No content provider found for permission revoke: "
8348                    + grantUri.toSafeString());
8349            return;
8350        }
8351
8352        // Does the caller have this permission on the URI?
8353        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8354            // If they don't have direct access to the URI, then revoke any
8355            // ownerless URI permissions that have been granted to them.
8356            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8357            if (perms != null) {
8358                boolean persistChanged = false;
8359                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8360                    final UriPermission perm = it.next();
8361                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8362                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8363                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8364                                "Revoking non-owned " + perm.targetUid
8365                                + " permission to " + perm.uri);
8366                        persistChanged |= perm.revokeModes(
8367                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8368                        if (perm.modeFlags == 0) {
8369                            it.remove();
8370                        }
8371                    }
8372                }
8373                if (perms.isEmpty()) {
8374                    mGrantedUriPermissions.remove(callingUid);
8375                }
8376                if (persistChanged) {
8377                    schedulePersistUriGrants();
8378                }
8379            }
8380            return;
8381        }
8382
8383        boolean persistChanged = false;
8384
8385        // Go through all of the permissions and remove any that match.
8386        int N = mGrantedUriPermissions.size();
8387        for (int i = 0; i < N; i++) {
8388            final int targetUid = mGrantedUriPermissions.keyAt(i);
8389            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8390
8391            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8392                final UriPermission perm = it.next();
8393                if (perm.uri.sourceUserId == grantUri.sourceUserId
8394                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8395                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8396                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8397                    persistChanged |= perm.revokeModes(
8398                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8399                    if (perm.modeFlags == 0) {
8400                        it.remove();
8401                    }
8402                }
8403            }
8404
8405            if (perms.isEmpty()) {
8406                mGrantedUriPermissions.remove(targetUid);
8407                N--;
8408                i--;
8409            }
8410        }
8411
8412        if (persistChanged) {
8413            schedulePersistUriGrants();
8414        }
8415    }
8416
8417    /**
8418     * @param uri This uri must NOT contain an embedded userId.
8419     * @param userId The userId in which the uri is to be resolved.
8420     */
8421    @Override
8422    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8423            int userId) {
8424        enforceNotIsolatedCaller("revokeUriPermission");
8425        synchronized(this) {
8426            final ProcessRecord r = getRecordForAppLocked(caller);
8427            if (r == null) {
8428                throw new SecurityException("Unable to find app for caller "
8429                        + caller
8430                        + " when revoking permission to uri " + uri);
8431            }
8432            if (uri == null) {
8433                Slog.w(TAG, "revokeUriPermission: null uri");
8434                return;
8435            }
8436
8437            if (!Intent.isAccessUriMode(modeFlags)) {
8438                return;
8439            }
8440
8441            final String authority = uri.getAuthority();
8442            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8443                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8444            if (pi == null) {
8445                Slog.w(TAG, "No content provider found for permission revoke: "
8446                        + uri.toSafeString());
8447                return;
8448            }
8449
8450            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8451        }
8452    }
8453
8454    /**
8455     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8456     * given package.
8457     *
8458     * @param packageName Package name to match, or {@code null} to apply to all
8459     *            packages.
8460     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8461     *            to all users.
8462     * @param persistable If persistable grants should be removed.
8463     */
8464    private void removeUriPermissionsForPackageLocked(
8465            String packageName, int userHandle, boolean persistable) {
8466        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8467            throw new IllegalArgumentException("Must narrow by either package or user");
8468        }
8469
8470        boolean persistChanged = false;
8471
8472        int N = mGrantedUriPermissions.size();
8473        for (int i = 0; i < N; i++) {
8474            final int targetUid = mGrantedUriPermissions.keyAt(i);
8475            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8476
8477            // Only inspect grants matching user
8478            if (userHandle == UserHandle.USER_ALL
8479                    || userHandle == UserHandle.getUserId(targetUid)) {
8480                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8481                    final UriPermission perm = it.next();
8482
8483                    // Only inspect grants matching package
8484                    if (packageName == null || perm.sourcePkg.equals(packageName)
8485                            || perm.targetPkg.equals(packageName)) {
8486                        persistChanged |= perm.revokeModes(persistable
8487                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8488
8489                        // Only remove when no modes remain; any persisted grants
8490                        // will keep this alive.
8491                        if (perm.modeFlags == 0) {
8492                            it.remove();
8493                        }
8494                    }
8495                }
8496
8497                if (perms.isEmpty()) {
8498                    mGrantedUriPermissions.remove(targetUid);
8499                    N--;
8500                    i--;
8501                }
8502            }
8503        }
8504
8505        if (persistChanged) {
8506            schedulePersistUriGrants();
8507        }
8508    }
8509
8510    @Override
8511    public IBinder newUriPermissionOwner(String name) {
8512        enforceNotIsolatedCaller("newUriPermissionOwner");
8513        synchronized(this) {
8514            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8515            return owner.getExternalTokenLocked();
8516        }
8517    }
8518
8519    @Override
8520    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8521        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8522        synchronized(this) {
8523            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8524            if (r == null) {
8525                throw new IllegalArgumentException("Activity does not exist; token="
8526                        + activityToken);
8527            }
8528            return r.getUriPermissionsLocked().getExternalTokenLocked();
8529        }
8530    }
8531    /**
8532     * @param uri This uri must NOT contain an embedded userId.
8533     * @param sourceUserId The userId in which the uri is to be resolved.
8534     * @param targetUserId The userId of the app that receives the grant.
8535     */
8536    @Override
8537    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8538            final int modeFlags, int sourceUserId, int targetUserId) {
8539        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8540                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8541                "grantUriPermissionFromOwner", null);
8542        synchronized(this) {
8543            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8544            if (owner == null) {
8545                throw new IllegalArgumentException("Unknown owner: " + token);
8546            }
8547            if (fromUid != Binder.getCallingUid()) {
8548                if (Binder.getCallingUid() != Process.myUid()) {
8549                    // Only system code can grant URI permissions on behalf
8550                    // of other users.
8551                    throw new SecurityException("nice try");
8552                }
8553            }
8554            if (targetPkg == null) {
8555                throw new IllegalArgumentException("null target");
8556            }
8557            if (uri == null) {
8558                throw new IllegalArgumentException("null uri");
8559            }
8560
8561            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8562                    modeFlags, owner, targetUserId);
8563        }
8564    }
8565
8566    /**
8567     * @param uri This uri must NOT contain an embedded userId.
8568     * @param userId The userId in which the uri is to be resolved.
8569     */
8570    @Override
8571    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8572        synchronized(this) {
8573            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8574            if (owner == null) {
8575                throw new IllegalArgumentException("Unknown owner: " + token);
8576            }
8577
8578            if (uri == null) {
8579                owner.removeUriPermissionsLocked(mode);
8580            } else {
8581                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8582            }
8583        }
8584    }
8585
8586    private void schedulePersistUriGrants() {
8587        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8588            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8589                    10 * DateUtils.SECOND_IN_MILLIS);
8590        }
8591    }
8592
8593    private void writeGrantedUriPermissions() {
8594        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8595
8596        // Snapshot permissions so we can persist without lock
8597        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8598        synchronized (this) {
8599            final int size = mGrantedUriPermissions.size();
8600            for (int i = 0; i < size; i++) {
8601                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8602                for (UriPermission perm : perms.values()) {
8603                    if (perm.persistedModeFlags != 0) {
8604                        persist.add(perm.snapshot());
8605                    }
8606                }
8607            }
8608        }
8609
8610        FileOutputStream fos = null;
8611        try {
8612            fos = mGrantFile.startWrite();
8613
8614            XmlSerializer out = new FastXmlSerializer();
8615            out.setOutput(fos, StandardCharsets.UTF_8.name());
8616            out.startDocument(null, true);
8617            out.startTag(null, TAG_URI_GRANTS);
8618            for (UriPermission.Snapshot perm : persist) {
8619                out.startTag(null, TAG_URI_GRANT);
8620                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8621                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8622                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8623                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8624                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8625                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8626                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8627                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8628                out.endTag(null, TAG_URI_GRANT);
8629            }
8630            out.endTag(null, TAG_URI_GRANTS);
8631            out.endDocument();
8632
8633            mGrantFile.finishWrite(fos);
8634        } catch (IOException e) {
8635            if (fos != null) {
8636                mGrantFile.failWrite(fos);
8637            }
8638        }
8639    }
8640
8641    private void readGrantedUriPermissionsLocked() {
8642        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8643
8644        final long now = System.currentTimeMillis();
8645
8646        FileInputStream fis = null;
8647        try {
8648            fis = mGrantFile.openRead();
8649            final XmlPullParser in = Xml.newPullParser();
8650            in.setInput(fis, StandardCharsets.UTF_8.name());
8651
8652            int type;
8653            while ((type = in.next()) != END_DOCUMENT) {
8654                final String tag = in.getName();
8655                if (type == START_TAG) {
8656                    if (TAG_URI_GRANT.equals(tag)) {
8657                        final int sourceUserId;
8658                        final int targetUserId;
8659                        final int userHandle = readIntAttribute(in,
8660                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8661                        if (userHandle != UserHandle.USER_NULL) {
8662                            // For backwards compatibility.
8663                            sourceUserId = userHandle;
8664                            targetUserId = userHandle;
8665                        } else {
8666                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8667                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8668                        }
8669                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8670                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8671                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8672                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8673                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8674                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8675
8676                        // Sanity check that provider still belongs to source package
8677                        // Both direct boot aware and unaware packages are fine as we
8678                        // will do filtering at query time to avoid multiple parsing.
8679                        final ProviderInfo pi = getProviderInfoLocked(
8680                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8681                                        | MATCH_DIRECT_BOOT_UNAWARE);
8682                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8683                            int targetUid = -1;
8684                            try {
8685                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8686                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8687                            } catch (RemoteException e) {
8688                            }
8689                            if (targetUid != -1) {
8690                                final UriPermission perm = findOrCreateUriPermissionLocked(
8691                                        sourcePkg, targetPkg, targetUid,
8692                                        new GrantUri(sourceUserId, uri, prefix));
8693                                perm.initPersistedModes(modeFlags, createdTime);
8694                            }
8695                        } else {
8696                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8697                                    + " but instead found " + pi);
8698                        }
8699                    }
8700                }
8701            }
8702        } catch (FileNotFoundException e) {
8703            // Missing grants is okay
8704        } catch (IOException e) {
8705            Slog.wtf(TAG, "Failed reading Uri grants", e);
8706        } catch (XmlPullParserException e) {
8707            Slog.wtf(TAG, "Failed reading Uri grants", e);
8708        } finally {
8709            IoUtils.closeQuietly(fis);
8710        }
8711    }
8712
8713    /**
8714     * @param uri This uri must NOT contain an embedded userId.
8715     * @param userId The userId in which the uri is to be resolved.
8716     */
8717    @Override
8718    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8719        enforceNotIsolatedCaller("takePersistableUriPermission");
8720
8721        Preconditions.checkFlagsArgument(modeFlags,
8722                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8723
8724        synchronized (this) {
8725            final int callingUid = Binder.getCallingUid();
8726            boolean persistChanged = false;
8727            GrantUri grantUri = new GrantUri(userId, uri, false);
8728
8729            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8730                    new GrantUri(userId, uri, false));
8731            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8732                    new GrantUri(userId, uri, true));
8733
8734            final boolean exactValid = (exactPerm != null)
8735                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8736            final boolean prefixValid = (prefixPerm != null)
8737                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8738
8739            if (!(exactValid || prefixValid)) {
8740                throw new SecurityException("No persistable permission grants found for UID "
8741                        + callingUid + " and Uri " + grantUri.toSafeString());
8742            }
8743
8744            if (exactValid) {
8745                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8746            }
8747            if (prefixValid) {
8748                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8749            }
8750
8751            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8752
8753            if (persistChanged) {
8754                schedulePersistUriGrants();
8755            }
8756        }
8757    }
8758
8759    /**
8760     * @param uri This uri must NOT contain an embedded userId.
8761     * @param userId The userId in which the uri is to be resolved.
8762     */
8763    @Override
8764    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8765        enforceNotIsolatedCaller("releasePersistableUriPermission");
8766
8767        Preconditions.checkFlagsArgument(modeFlags,
8768                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8769
8770        synchronized (this) {
8771            final int callingUid = Binder.getCallingUid();
8772            boolean persistChanged = false;
8773
8774            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8775                    new GrantUri(userId, uri, false));
8776            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8777                    new GrantUri(userId, uri, true));
8778            if (exactPerm == null && prefixPerm == null) {
8779                throw new SecurityException("No permission grants found for UID " + callingUid
8780                        + " and Uri " + uri.toSafeString());
8781            }
8782
8783            if (exactPerm != null) {
8784                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8785                removeUriPermissionIfNeededLocked(exactPerm);
8786            }
8787            if (prefixPerm != null) {
8788                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8789                removeUriPermissionIfNeededLocked(prefixPerm);
8790            }
8791
8792            if (persistChanged) {
8793                schedulePersistUriGrants();
8794            }
8795        }
8796    }
8797
8798    /**
8799     * Prune any older {@link UriPermission} for the given UID until outstanding
8800     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8801     *
8802     * @return if any mutations occured that require persisting.
8803     */
8804    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8805        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8806        if (perms == null) return false;
8807        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8808
8809        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8810        for (UriPermission perm : perms.values()) {
8811            if (perm.persistedModeFlags != 0) {
8812                persisted.add(perm);
8813            }
8814        }
8815
8816        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8817        if (trimCount <= 0) return false;
8818
8819        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8820        for (int i = 0; i < trimCount; i++) {
8821            final UriPermission perm = persisted.get(i);
8822
8823            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8824                    "Trimming grant created at " + perm.persistedCreateTime);
8825
8826            perm.releasePersistableModes(~0);
8827            removeUriPermissionIfNeededLocked(perm);
8828        }
8829
8830        return true;
8831    }
8832
8833    @Override
8834    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8835            String packageName, boolean incoming) {
8836        enforceNotIsolatedCaller("getPersistedUriPermissions");
8837        Preconditions.checkNotNull(packageName, "packageName");
8838
8839        final int callingUid = Binder.getCallingUid();
8840        final int callingUserId = UserHandle.getUserId(callingUid);
8841        final IPackageManager pm = AppGlobals.getPackageManager();
8842        try {
8843            final int packageUid = pm.getPackageUid(packageName,
8844                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8845            if (packageUid != callingUid) {
8846                throw new SecurityException(
8847                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8848            }
8849        } catch (RemoteException e) {
8850            throw new SecurityException("Failed to verify package name ownership");
8851        }
8852
8853        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8854        synchronized (this) {
8855            if (incoming) {
8856                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8857                        callingUid);
8858                if (perms == null) {
8859                    Slog.w(TAG, "No permission grants found for " + packageName);
8860                } else {
8861                    for (UriPermission perm : perms.values()) {
8862                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8863                            result.add(perm.buildPersistedPublicApiObject());
8864                        }
8865                    }
8866                }
8867            } else {
8868                final int size = mGrantedUriPermissions.size();
8869                for (int i = 0; i < size; i++) {
8870                    final ArrayMap<GrantUri, UriPermission> perms =
8871                            mGrantedUriPermissions.valueAt(i);
8872                    for (UriPermission perm : perms.values()) {
8873                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8874                            result.add(perm.buildPersistedPublicApiObject());
8875                        }
8876                    }
8877                }
8878            }
8879        }
8880        return new ParceledListSlice<android.content.UriPermission>(result);
8881    }
8882
8883    @Override
8884    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8885            String packageName, int userId) {
8886        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8887                "getGrantedUriPermissions");
8888
8889        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8890        synchronized (this) {
8891            final int size = mGrantedUriPermissions.size();
8892            for (int i = 0; i < size; i++) {
8893                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8894                for (UriPermission perm : perms.values()) {
8895                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8896                            && perm.persistedModeFlags != 0) {
8897                        result.add(perm.buildPersistedPublicApiObject());
8898                    }
8899                }
8900            }
8901        }
8902        return new ParceledListSlice<android.content.UriPermission>(result);
8903    }
8904
8905    @Override
8906    public void clearGrantedUriPermissions(String packageName, int userId) {
8907        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8908                "clearGrantedUriPermissions");
8909        removeUriPermissionsForPackageLocked(packageName, userId, true);
8910    }
8911
8912    @Override
8913    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8914        synchronized (this) {
8915            ProcessRecord app =
8916                who != null ? getRecordForAppLocked(who) : null;
8917            if (app == null) return;
8918
8919            Message msg = Message.obtain();
8920            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8921            msg.obj = app;
8922            msg.arg1 = waiting ? 1 : 0;
8923            mUiHandler.sendMessage(msg);
8924        }
8925    }
8926
8927    @Override
8928    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8929        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8930        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8931        outInfo.availMem = Process.getFreeMemory();
8932        outInfo.totalMem = Process.getTotalMemory();
8933        outInfo.threshold = homeAppMem;
8934        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8935        outInfo.hiddenAppThreshold = cachedAppMem;
8936        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8937                ProcessList.SERVICE_ADJ);
8938        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8939                ProcessList.VISIBLE_APP_ADJ);
8940        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8941                ProcessList.FOREGROUND_APP_ADJ);
8942    }
8943
8944    // =========================================================
8945    // TASK MANAGEMENT
8946    // =========================================================
8947
8948    @Override
8949    public List<IAppTask> getAppTasks(String callingPackage) {
8950        int callingUid = Binder.getCallingUid();
8951        long ident = Binder.clearCallingIdentity();
8952
8953        synchronized(this) {
8954            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8955            try {
8956                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8957
8958                final int N = mRecentTasks.size();
8959                for (int i = 0; i < N; i++) {
8960                    TaskRecord tr = mRecentTasks.get(i);
8961                    // Skip tasks that do not match the caller.  We don't need to verify
8962                    // callingPackage, because we are also limiting to callingUid and know
8963                    // that will limit to the correct security sandbox.
8964                    if (tr.effectiveUid != callingUid) {
8965                        continue;
8966                    }
8967                    Intent intent = tr.getBaseIntent();
8968                    if (intent == null ||
8969                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8970                        continue;
8971                    }
8972                    ActivityManager.RecentTaskInfo taskInfo =
8973                            createRecentTaskInfoFromTaskRecord(tr);
8974                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8975                    list.add(taskImpl);
8976                }
8977            } finally {
8978                Binder.restoreCallingIdentity(ident);
8979            }
8980            return list;
8981        }
8982    }
8983
8984    @Override
8985    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8986        final int callingUid = Binder.getCallingUid();
8987        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8988
8989        synchronized(this) {
8990            if (DEBUG_ALL) Slog.v(
8991                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8992
8993            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8994                    callingUid);
8995
8996            // TODO: Improve with MRU list from all ActivityStacks.
8997            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8998        }
8999
9000        return list;
9001    }
9002
9003    /**
9004     * Creates a new RecentTaskInfo from a TaskRecord.
9005     */
9006    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9007        // Update the task description to reflect any changes in the task stack
9008        tr.updateTaskDescription();
9009
9010        // Compose the recent task info
9011        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9012        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9013        rti.persistentId = tr.taskId;
9014        rti.baseIntent = new Intent(tr.getBaseIntent());
9015        rti.origActivity = tr.origActivity;
9016        rti.realActivity = tr.realActivity;
9017        rti.description = tr.lastDescription;
9018        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9019        rti.userId = tr.userId;
9020        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9021        rti.firstActiveTime = tr.firstActiveTime;
9022        rti.lastActiveTime = tr.lastActiveTime;
9023        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9024        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9025        rti.numActivities = 0;
9026        if (tr.mBounds != null) {
9027            rti.bounds = new Rect(tr.mBounds);
9028        }
9029        rti.isDockable = tr.canGoInDockedStack();
9030        rti.resizeMode = tr.mResizeMode;
9031
9032        ActivityRecord base = null;
9033        ActivityRecord top = null;
9034        ActivityRecord tmp;
9035
9036        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9037            tmp = tr.mActivities.get(i);
9038            if (tmp.finishing) {
9039                continue;
9040            }
9041            base = tmp;
9042            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9043                top = base;
9044            }
9045            rti.numActivities++;
9046        }
9047
9048        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9049        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9050
9051        return rti;
9052    }
9053
9054    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9055        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9056                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9057        if (!allowed) {
9058            if (checkPermission(android.Manifest.permission.GET_TASKS,
9059                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9060                // Temporary compatibility: some existing apps on the system image may
9061                // still be requesting the old permission and not switched to the new
9062                // one; if so, we'll still allow them full access.  This means we need
9063                // to see if they are holding the old permission and are a system app.
9064                try {
9065                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9066                        allowed = true;
9067                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9068                                + " is using old GET_TASKS but privileged; allowing");
9069                    }
9070                } catch (RemoteException e) {
9071                }
9072            }
9073        }
9074        if (!allowed) {
9075            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9076                    + " does not hold REAL_GET_TASKS; limiting output");
9077        }
9078        return allowed;
9079    }
9080
9081    @Override
9082    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9083        final int callingUid = Binder.getCallingUid();
9084        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9085                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9086
9087        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9088        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9089        synchronized (this) {
9090            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9091                    callingUid);
9092            final boolean detailed = checkCallingPermission(
9093                    android.Manifest.permission.GET_DETAILED_TASKS)
9094                    == PackageManager.PERMISSION_GRANTED;
9095
9096            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9097                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9098                return Collections.emptyList();
9099            }
9100            mRecentTasks.loadUserRecentsLocked(userId);
9101
9102            final int recentsCount = mRecentTasks.size();
9103            ArrayList<ActivityManager.RecentTaskInfo> res =
9104                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9105
9106            final Set<Integer> includedUsers;
9107            if (includeProfiles) {
9108                includedUsers = mUserController.getProfileIds(userId);
9109            } else {
9110                includedUsers = new HashSet<>();
9111            }
9112            includedUsers.add(Integer.valueOf(userId));
9113
9114            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9115                TaskRecord tr = mRecentTasks.get(i);
9116                // Only add calling user or related users recent tasks
9117                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9118                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9119                    continue;
9120                }
9121
9122                if (tr.realActivitySuspended) {
9123                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9124                    continue;
9125                }
9126
9127                // Return the entry if desired by the caller.  We always return
9128                // the first entry, because callers always expect this to be the
9129                // foreground app.  We may filter others if the caller has
9130                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9131                // we should exclude the entry.
9132
9133                if (i == 0
9134                        || withExcluded
9135                        || (tr.intent == null)
9136                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9137                                == 0)) {
9138                    if (!allowed) {
9139                        // If the caller doesn't have the GET_TASKS permission, then only
9140                        // allow them to see a small subset of tasks -- their own and home.
9141                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9142                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9143                            continue;
9144                        }
9145                    }
9146                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9147                        if (tr.stack != null && tr.stack.isHomeStack()) {
9148                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9149                                    "Skipping, home stack task: " + tr);
9150                            continue;
9151                        }
9152                    }
9153                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9154                        final ActivityStack stack = tr.stack;
9155                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9156                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9157                                    "Skipping, top task in docked stack: " + tr);
9158                            continue;
9159                        }
9160                    }
9161                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9162                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9163                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9164                                    "Skipping, pinned stack task: " + tr);
9165                            continue;
9166                        }
9167                    }
9168                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9169                        // Don't include auto remove tasks that are finished or finishing.
9170                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9171                                "Skipping, auto-remove without activity: " + tr);
9172                        continue;
9173                    }
9174                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9175                            && !tr.isAvailable) {
9176                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9177                                "Skipping, unavail real act: " + tr);
9178                        continue;
9179                    }
9180
9181                    if (!tr.mUserSetupComplete) {
9182                        // Don't include task launched while user is not done setting-up.
9183                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                "Skipping, user setup not complete: " + tr);
9185                        continue;
9186                    }
9187
9188                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9189                    if (!detailed) {
9190                        rti.baseIntent.replaceExtras((Bundle)null);
9191                    }
9192
9193                    res.add(rti);
9194                    maxNum--;
9195                }
9196            }
9197            return res;
9198        }
9199    }
9200
9201    @Override
9202    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9203        synchronized (this) {
9204            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9205                    "getTaskThumbnail()");
9206            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9207                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9208            if (tr != null) {
9209                return tr.getTaskThumbnailLocked();
9210            }
9211        }
9212        return null;
9213    }
9214
9215    @Override
9216    public int addAppTask(IBinder activityToken, Intent intent,
9217            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9218        final int callingUid = Binder.getCallingUid();
9219        final long callingIdent = Binder.clearCallingIdentity();
9220
9221        try {
9222            synchronized (this) {
9223                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9224                if (r == null) {
9225                    throw new IllegalArgumentException("Activity does not exist; token="
9226                            + activityToken);
9227                }
9228                ComponentName comp = intent.getComponent();
9229                if (comp == null) {
9230                    throw new IllegalArgumentException("Intent " + intent
9231                            + " must specify explicit component");
9232                }
9233                if (thumbnail.getWidth() != mThumbnailWidth
9234                        || thumbnail.getHeight() != mThumbnailHeight) {
9235                    throw new IllegalArgumentException("Bad thumbnail size: got "
9236                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9237                            + mThumbnailWidth + "x" + mThumbnailHeight);
9238                }
9239                if (intent.getSelector() != null) {
9240                    intent.setSelector(null);
9241                }
9242                if (intent.getSourceBounds() != null) {
9243                    intent.setSourceBounds(null);
9244                }
9245                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9246                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9247                        // The caller has added this as an auto-remove task...  that makes no
9248                        // sense, so turn off auto-remove.
9249                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9250                    }
9251                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9252                    // Must be a new task.
9253                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9254                }
9255                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9256                    mLastAddedTaskActivity = null;
9257                }
9258                ActivityInfo ainfo = mLastAddedTaskActivity;
9259                if (ainfo == null) {
9260                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9261                            comp, 0, UserHandle.getUserId(callingUid));
9262                    if (ainfo.applicationInfo.uid != callingUid) {
9263                        throw new SecurityException(
9264                                "Can't add task for another application: target uid="
9265                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9266                    }
9267                }
9268
9269                // Use the full screen as the context for the task thumbnail
9270                final Point displaySize = new Point();
9271                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9272                r.task.stack.getDisplaySize(displaySize);
9273                thumbnailInfo.taskWidth = displaySize.x;
9274                thumbnailInfo.taskHeight = displaySize.y;
9275                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9276
9277                TaskRecord task = new TaskRecord(this,
9278                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9279                        ainfo, intent, description, thumbnailInfo);
9280
9281                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9282                if (trimIdx >= 0) {
9283                    // If this would have caused a trim, then we'll abort because that
9284                    // means it would be added at the end of the list but then just removed.
9285                    return INVALID_TASK_ID;
9286                }
9287
9288                final int N = mRecentTasks.size();
9289                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9290                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9291                    tr.removedFromRecents();
9292                }
9293
9294                task.inRecents = true;
9295                mRecentTasks.add(task);
9296                r.task.stack.addTask(task, false, "addAppTask");
9297
9298                task.setLastThumbnailLocked(thumbnail);
9299                task.freeLastThumbnail();
9300
9301                return task.taskId;
9302            }
9303        } finally {
9304            Binder.restoreCallingIdentity(callingIdent);
9305        }
9306    }
9307
9308    @Override
9309    public Point getAppTaskThumbnailSize() {
9310        synchronized (this) {
9311            return new Point(mThumbnailWidth,  mThumbnailHeight);
9312        }
9313    }
9314
9315    @Override
9316    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9317        synchronized (this) {
9318            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9319            if (r != null) {
9320                r.setTaskDescription(td);
9321                r.task.updateTaskDescription();
9322            }
9323        }
9324    }
9325
9326    @Override
9327    public void setTaskResizeable(int taskId, int resizeableMode) {
9328        synchronized (this) {
9329            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9330                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9331            if (task == null) {
9332                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9333                return;
9334            }
9335            if (task.mResizeMode != resizeableMode) {
9336                task.mResizeMode = resizeableMode;
9337                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9338                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9339                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9340            }
9341        }
9342    }
9343
9344    @Override
9345    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9346        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9347        long ident = Binder.clearCallingIdentity();
9348        try {
9349            synchronized (this) {
9350                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9351                if (task == null) {
9352                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9353                    return;
9354                }
9355                int stackId = task.stack.mStackId;
9356                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9357                // in crop windows resize mode or if the task size is affected by the docked stack
9358                // changing size. No need to update configuration.
9359                if (bounds != null && task.inCropWindowsResizeMode()
9360                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9361                    mWindowManager.scrollTask(task.taskId, bounds);
9362                    return;
9363                }
9364
9365                // Place the task in the right stack if it isn't there already based on
9366                // the requested bounds.
9367                // The stack transition logic is:
9368                // - a null bounds on a freeform task moves that task to fullscreen
9369                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9370                //   that task to freeform
9371                // - otherwise the task is not moved
9372                if (!StackId.isTaskResizeAllowed(stackId)) {
9373                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9374                }
9375                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9376                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9377                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9378                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9379                }
9380                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9381                if (stackId != task.stack.mStackId) {
9382                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9383                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9384                    preserveWindow = false;
9385                }
9386
9387                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9388                        false /* deferResume */);
9389            }
9390        } finally {
9391            Binder.restoreCallingIdentity(ident);
9392        }
9393    }
9394
9395    @Override
9396    public Rect getTaskBounds(int taskId) {
9397        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9398        long ident = Binder.clearCallingIdentity();
9399        Rect rect = new Rect();
9400        try {
9401            synchronized (this) {
9402                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9403                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9404                if (task == null) {
9405                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9406                    return rect;
9407                }
9408                if (task.stack != null) {
9409                    // Return the bounds from window manager since it will be adjusted for various
9410                    // things like the presense of a docked stack for tasks that aren't resizeable.
9411                    mWindowManager.getTaskBounds(task.taskId, rect);
9412                } else {
9413                    // Task isn't in window manager yet since it isn't associated with a stack.
9414                    // Return the persist value from activity manager
9415                    if (task.mBounds != null) {
9416                        rect.set(task.mBounds);
9417                    } else if (task.mLastNonFullscreenBounds != null) {
9418                        rect.set(task.mLastNonFullscreenBounds);
9419                    }
9420                }
9421            }
9422        } finally {
9423            Binder.restoreCallingIdentity(ident);
9424        }
9425        return rect;
9426    }
9427
9428    @Override
9429    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9430        if (userId != UserHandle.getCallingUserId()) {
9431            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9432                    "getTaskDescriptionIcon");
9433        }
9434        final File passedIconFile = new File(filePath);
9435        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9436                passedIconFile.getName());
9437        if (!legitIconFile.getPath().equals(filePath)
9438                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9439            throw new IllegalArgumentException("Bad file path: " + filePath
9440                    + " passed for userId " + userId);
9441        }
9442        return mRecentTasks.getTaskDescriptionIcon(filePath);
9443    }
9444
9445    @Override
9446    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9447            throws RemoteException {
9448        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9449                opts.getCustomInPlaceResId() == 0) {
9450            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9451                    "with valid animation");
9452        }
9453        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9454        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9455                opts.getCustomInPlaceResId());
9456        mWindowManager.executeAppTransition();
9457    }
9458
9459    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9460            boolean removeFromRecents) {
9461        if (removeFromRecents) {
9462            mRecentTasks.remove(tr);
9463            tr.removedFromRecents();
9464        }
9465        ComponentName component = tr.getBaseIntent().getComponent();
9466        if (component == null) {
9467            Slog.w(TAG, "No component for base intent of task: " + tr);
9468            return;
9469        }
9470
9471        // Find any running services associated with this app and stop if needed.
9472        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9473
9474        if (!killProcess) {
9475            return;
9476        }
9477
9478        // Determine if the process(es) for this task should be killed.
9479        final String pkg = component.getPackageName();
9480        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9481        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9482        for (int i = 0; i < pmap.size(); i++) {
9483
9484            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9485            for (int j = 0; j < uids.size(); j++) {
9486                ProcessRecord proc = uids.valueAt(j);
9487                if (proc.userId != tr.userId) {
9488                    // Don't kill process for a different user.
9489                    continue;
9490                }
9491                if (proc == mHomeProcess) {
9492                    // Don't kill the home process along with tasks from the same package.
9493                    continue;
9494                }
9495                if (!proc.pkgList.containsKey(pkg)) {
9496                    // Don't kill process that is not associated with this task.
9497                    continue;
9498                }
9499
9500                for (int k = 0; k < proc.activities.size(); k++) {
9501                    TaskRecord otherTask = proc.activities.get(k).task;
9502                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9503                        // Don't kill process(es) that has an activity in a different task that is
9504                        // also in recents.
9505                        return;
9506                    }
9507                }
9508
9509                if (proc.foregroundServices) {
9510                    // Don't kill process(es) with foreground service.
9511                    return;
9512                }
9513
9514                // Add process to kill list.
9515                procsToKill.add(proc);
9516            }
9517        }
9518
9519        // Kill the running processes.
9520        for (int i = 0; i < procsToKill.size(); i++) {
9521            ProcessRecord pr = procsToKill.get(i);
9522            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9523                    && pr.curReceiver == null) {
9524                pr.kill("remove task", true);
9525            } else {
9526                // We delay killing processes that are not in the background or running a receiver.
9527                pr.waitingToKill = "remove task";
9528            }
9529        }
9530    }
9531
9532    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9533        // Remove all tasks with activities in the specified package from the list of recent tasks
9534        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9535            TaskRecord tr = mRecentTasks.get(i);
9536            if (tr.userId != userId) continue;
9537
9538            ComponentName cn = tr.intent.getComponent();
9539            if (cn != null && cn.getPackageName().equals(packageName)) {
9540                // If the package name matches, remove the task.
9541                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9542            }
9543        }
9544    }
9545
9546    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9547            int userId) {
9548
9549        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9550            TaskRecord tr = mRecentTasks.get(i);
9551            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9552                continue;
9553            }
9554
9555            ComponentName cn = tr.intent.getComponent();
9556            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9557                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9558            if (sameComponent) {
9559                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9560            }
9561        }
9562    }
9563
9564    /**
9565     * Removes the task with the specified task id.
9566     *
9567     * @param taskId Identifier of the task to be removed.
9568     * @param killProcess Kill any process associated with the task if possible.
9569     * @param removeFromRecents Whether to also remove the task from recents.
9570     * @return Returns true if the given task was found and removed.
9571     */
9572    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9573            boolean removeFromRecents) {
9574        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9575                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9576        if (tr != null) {
9577            tr.removeTaskActivitiesLocked();
9578            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9579            if (tr.isPersistable) {
9580                notifyTaskPersisterLocked(null, true);
9581            }
9582            return true;
9583        }
9584        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9585        return false;
9586    }
9587
9588    @Override
9589    public void removeStack(int stackId) {
9590        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9591        if (stackId == HOME_STACK_ID) {
9592            throw new IllegalArgumentException("Removing home stack is not allowed.");
9593        }
9594
9595        synchronized (this) {
9596            final long ident = Binder.clearCallingIdentity();
9597            try {
9598                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9599                if (stack == null) {
9600                    return;
9601                }
9602                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9603                for (int i = tasks.size() - 1; i >= 0; i--) {
9604                    removeTaskByIdLocked(
9605                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9606                }
9607            } finally {
9608                Binder.restoreCallingIdentity(ident);
9609            }
9610        }
9611    }
9612
9613    @Override
9614    public boolean removeTask(int taskId) {
9615        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9616        synchronized (this) {
9617            final long ident = Binder.clearCallingIdentity();
9618            try {
9619                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9620            } finally {
9621                Binder.restoreCallingIdentity(ident);
9622            }
9623        }
9624    }
9625
9626    /**
9627     * TODO: Add mController hook
9628     */
9629    @Override
9630    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9631        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9632
9633        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9634        synchronized(this) {
9635            moveTaskToFrontLocked(taskId, flags, bOptions);
9636        }
9637    }
9638
9639    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9640        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9641
9642        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9643                Binder.getCallingUid(), -1, -1, "Task to front")) {
9644            ActivityOptions.abort(options);
9645            return;
9646        }
9647        final long origId = Binder.clearCallingIdentity();
9648        try {
9649            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9650            if (task == null) {
9651                Slog.d(TAG, "Could not find task for id: "+ taskId);
9652                return;
9653            }
9654            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9655                mStackSupervisor.showLockTaskToast();
9656                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9657                return;
9658            }
9659            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9660            if (prev != null && prev.isRecentsActivity()) {
9661                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9662            }
9663            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9664                    false /* forceNonResizable */);
9665        } finally {
9666            Binder.restoreCallingIdentity(origId);
9667        }
9668        ActivityOptions.abort(options);
9669    }
9670
9671    /**
9672     * Moves an activity, and all of the other activities within the same task, to the bottom
9673     * of the history stack.  The activity's order within the task is unchanged.
9674     *
9675     * @param token A reference to the activity we wish to move
9676     * @param nonRoot If false then this only works if the activity is the root
9677     *                of a task; if true it will work for any activity in a task.
9678     * @return Returns true if the move completed, false if not.
9679     */
9680    @Override
9681    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9682        enforceNotIsolatedCaller("moveActivityTaskToBack");
9683        synchronized(this) {
9684            final long origId = Binder.clearCallingIdentity();
9685            try {
9686                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9687                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9688                if (task != null) {
9689                    if (mStackSupervisor.isLockedTask(task)) {
9690                        mStackSupervisor.showLockTaskToast();
9691                        return false;
9692                    }
9693                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9694                }
9695            } finally {
9696                Binder.restoreCallingIdentity(origId);
9697            }
9698        }
9699        return false;
9700    }
9701
9702    @Override
9703    public void moveTaskBackwards(int task) {
9704        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9705                "moveTaskBackwards()");
9706
9707        synchronized(this) {
9708            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9709                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9710                return;
9711            }
9712            final long origId = Binder.clearCallingIdentity();
9713            moveTaskBackwardsLocked(task);
9714            Binder.restoreCallingIdentity(origId);
9715        }
9716    }
9717
9718    private final void moveTaskBackwardsLocked(int task) {
9719        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9720    }
9721
9722    @Override
9723    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9724            IActivityContainerCallback callback) throws RemoteException {
9725        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9726        synchronized (this) {
9727            if (parentActivityToken == null) {
9728                throw new IllegalArgumentException("parent token must not be null");
9729            }
9730            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9731            if (r == null) {
9732                return null;
9733            }
9734            if (callback == null) {
9735                throw new IllegalArgumentException("callback must not be null");
9736            }
9737            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9738        }
9739    }
9740
9741    @Override
9742    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9743        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9744        synchronized (this) {
9745            mStackSupervisor.deleteActivityContainer(container);
9746        }
9747    }
9748
9749    @Override
9750    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9751        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9752        synchronized (this) {
9753            final int stackId = mStackSupervisor.getNextStackId();
9754            final ActivityStack stack =
9755                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9756            if (stack == null) {
9757                return null;
9758            }
9759            return stack.mActivityContainer;
9760        }
9761    }
9762
9763    @Override
9764    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9765        synchronized (this) {
9766            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9767            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9768                return stack.mActivityContainer.getDisplayId();
9769            }
9770            return Display.DEFAULT_DISPLAY;
9771        }
9772    }
9773
9774    @Override
9775    public int getActivityStackId(IBinder token) throws RemoteException {
9776        synchronized (this) {
9777            ActivityStack stack = ActivityRecord.getStackLocked(token);
9778            if (stack == null) {
9779                return INVALID_STACK_ID;
9780            }
9781            return stack.mStackId;
9782        }
9783    }
9784
9785    @Override
9786    public void exitFreeformMode(IBinder token) throws RemoteException {
9787        synchronized (this) {
9788            long ident = Binder.clearCallingIdentity();
9789            try {
9790                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9791                if (r == null) {
9792                    throw new IllegalArgumentException(
9793                            "exitFreeformMode: No activity record matching token=" + token);
9794                }
9795                final ActivityStack stack = r.getStackLocked(token);
9796                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9797                    throw new IllegalStateException(
9798                            "exitFreeformMode: You can only go fullscreen from freeform.");
9799                }
9800                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9801                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9802                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9803            } finally {
9804                Binder.restoreCallingIdentity(ident);
9805            }
9806        }
9807    }
9808
9809    @Override
9810    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9811        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9812        if (stackId == HOME_STACK_ID) {
9813            throw new IllegalArgumentException(
9814                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9815        }
9816        synchronized (this) {
9817            long ident = Binder.clearCallingIdentity();
9818            try {
9819                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9820                        + " to stackId=" + stackId + " toTop=" + toTop);
9821                if (stackId == DOCKED_STACK_ID) {
9822                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9823                            null /* initialBounds */);
9824                }
9825                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9826                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9827                if (result && stackId == DOCKED_STACK_ID) {
9828                    // If task moved to docked stack - show recents if needed.
9829                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9830                            "moveTaskToDockedStack");
9831                }
9832            } finally {
9833                Binder.restoreCallingIdentity(ident);
9834            }
9835        }
9836    }
9837
9838    @Override
9839    public void swapDockedAndFullscreenStack() throws RemoteException {
9840        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9841        synchronized (this) {
9842            long ident = Binder.clearCallingIdentity();
9843            try {
9844                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9845                        FULLSCREEN_WORKSPACE_STACK_ID);
9846                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9847                        : null;
9848                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9849                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9850                        : null;
9851                if (topTask == null || tasks == null || tasks.size() == 0) {
9852                    Slog.w(TAG,
9853                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9854                    return;
9855                }
9856
9857                // TODO: App transition
9858                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9859
9860                // Defer the resume so resume/pausing while moving stacks is dangerous.
9861                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9862                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9863                        ANIMATE, true /* deferResume */);
9864                final int size = tasks.size();
9865                for (int i = 0; i < size; i++) {
9866                    final int id = tasks.get(i).taskId;
9867                    if (id == topTask.taskId) {
9868                        continue;
9869                    }
9870                    mStackSupervisor.moveTaskToStackLocked(id,
9871                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9872                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9873                }
9874
9875                // Because we deferred the resume, to avoid conflicts with stack switches while
9876                // resuming, we need to do it after all the tasks are moved.
9877                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9878                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9879
9880                mWindowManager.executeAppTransition();
9881            } finally {
9882                Binder.restoreCallingIdentity(ident);
9883            }
9884        }
9885    }
9886
9887    /**
9888     * Moves the input task to the docked stack.
9889     *
9890     * @param taskId Id of task to move.
9891     * @param createMode The mode the docked stack should be created in if it doesn't exist
9892     *                   already. See
9893     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9894     *                   and
9895     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9896     * @param toTop If the task and stack should be moved to the top.
9897     * @param animate Whether we should play an animation for the moving the task
9898     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9899     *                      docked stack. Pass {@code null} to use default bounds.
9900     */
9901    @Override
9902    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9903            Rect initialBounds, boolean moveHomeStackFront) {
9904        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9905        synchronized (this) {
9906            long ident = Binder.clearCallingIdentity();
9907            try {
9908                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9909                        + " to createMode=" + createMode + " toTop=" + toTop);
9910                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9911                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9912                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9913                        animate, DEFER_RESUME);
9914                if (moved) {
9915                    if (moveHomeStackFront) {
9916                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9917                    }
9918                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9919                }
9920                return moved;
9921            } finally {
9922                Binder.restoreCallingIdentity(ident);
9923            }
9924        }
9925    }
9926
9927    /**
9928     * Moves the top activity in the input stackId to the pinned stack.
9929     *
9930     * @param stackId Id of stack to move the top activity to pinned stack.
9931     * @param bounds Bounds to use for pinned stack.
9932     *
9933     * @return True if the top activity of the input stack was successfully moved to the pinned
9934     *          stack.
9935     */
9936    @Override
9937    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9938        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9939        synchronized (this) {
9940            if (!mSupportsPictureInPicture) {
9941                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9942                        + "Device doesn't support picture-in-pciture mode");
9943            }
9944
9945            long ident = Binder.clearCallingIdentity();
9946            try {
9947                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9948            } finally {
9949                Binder.restoreCallingIdentity(ident);
9950            }
9951        }
9952    }
9953
9954    @Override
9955    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9956            boolean preserveWindows, boolean animate, int animationDuration) {
9957        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9958        long ident = Binder.clearCallingIdentity();
9959        try {
9960            synchronized (this) {
9961                if (animate) {
9962                    if (stackId == PINNED_STACK_ID) {
9963                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9964                    } else {
9965                        throw new IllegalArgumentException("Stack: " + stackId
9966                                + " doesn't support animated resize.");
9967                    }
9968                } else {
9969                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9970                            null /* tempTaskInsetBounds */, preserveWindows,
9971                            allowResizeInDockedMode, !DEFER_RESUME);
9972                }
9973            }
9974        } finally {
9975            Binder.restoreCallingIdentity(ident);
9976        }
9977    }
9978
9979    @Override
9980    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9981            Rect tempDockedTaskInsetBounds,
9982            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9983        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9984                "resizeDockedStack()");
9985        long ident = Binder.clearCallingIdentity();
9986        try {
9987            synchronized (this) {
9988                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9989                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9990                        PRESERVE_WINDOWS);
9991            }
9992        } finally {
9993            Binder.restoreCallingIdentity(ident);
9994        }
9995    }
9996
9997    @Override
9998    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9999        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10000                "resizePinnedStack()");
10001        final long ident = Binder.clearCallingIdentity();
10002        try {
10003            synchronized (this) {
10004                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    @Override
10012    public void positionTaskInStack(int taskId, int stackId, int position) {
10013        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10014        if (stackId == HOME_STACK_ID) {
10015            throw new IllegalArgumentException(
10016                    "positionTaskInStack: Attempt to change the position of task "
10017                    + taskId + " in/to home stack");
10018        }
10019        synchronized (this) {
10020            long ident = Binder.clearCallingIdentity();
10021            try {
10022                if (DEBUG_STACK) Slog.d(TAG_STACK,
10023                        "positionTaskInStack: positioning task=" + taskId
10024                        + " in stackId=" + stackId + " at position=" + position);
10025                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10026            } finally {
10027                Binder.restoreCallingIdentity(ident);
10028            }
10029        }
10030    }
10031
10032    @Override
10033    public List<StackInfo> getAllStackInfos() {
10034        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10035        long ident = Binder.clearCallingIdentity();
10036        try {
10037            synchronized (this) {
10038                return mStackSupervisor.getAllStackInfosLocked();
10039            }
10040        } finally {
10041            Binder.restoreCallingIdentity(ident);
10042        }
10043    }
10044
10045    @Override
10046    public StackInfo getStackInfo(int stackId) {
10047        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10048        long ident = Binder.clearCallingIdentity();
10049        try {
10050            synchronized (this) {
10051                return mStackSupervisor.getStackInfoLocked(stackId);
10052            }
10053        } finally {
10054            Binder.restoreCallingIdentity(ident);
10055        }
10056    }
10057
10058    @Override
10059    public boolean isInHomeStack(int taskId) {
10060        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10061        long ident = Binder.clearCallingIdentity();
10062        try {
10063            synchronized (this) {
10064                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10065                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10066                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10067            }
10068        } finally {
10069            Binder.restoreCallingIdentity(ident);
10070        }
10071    }
10072
10073    @Override
10074    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10075        synchronized(this) {
10076            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10077        }
10078    }
10079
10080    @Override
10081    public void updateDeviceOwner(String packageName) {
10082        final int callingUid = Binder.getCallingUid();
10083        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10084            throw new SecurityException("updateDeviceOwner called from non-system process");
10085        }
10086        synchronized (this) {
10087            mDeviceOwnerName = packageName;
10088        }
10089    }
10090
10091    @Override
10092    public void updateLockTaskPackages(int userId, String[] packages) {
10093        final int callingUid = Binder.getCallingUid();
10094        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10095            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10096                    "updateLockTaskPackages()");
10097        }
10098        synchronized (this) {
10099            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10100                    Arrays.toString(packages));
10101            mLockTaskPackages.put(userId, packages);
10102            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10103        }
10104    }
10105
10106
10107    void startLockTaskModeLocked(TaskRecord task) {
10108        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10109        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10110            return;
10111        }
10112
10113        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10114        // is initiated by system after the pinning request was shown and locked mode is initiated
10115        // by an authorized app directly
10116        final int callingUid = Binder.getCallingUid();
10117        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10118        long ident = Binder.clearCallingIdentity();
10119        try {
10120            if (!isSystemInitiated) {
10121                task.mLockTaskUid = callingUid;
10122                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10123                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10124                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10125                    StatusBarManagerInternal statusBarManager =
10126                            LocalServices.getService(StatusBarManagerInternal.class);
10127                    if (statusBarManager != null) {
10128                        statusBarManager.showScreenPinningRequest(task.taskId);
10129                    }
10130                    return;
10131                }
10132
10133                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10134                if (stack == null || task != stack.topTask()) {
10135                    throw new IllegalArgumentException("Invalid task, not in foreground");
10136                }
10137            }
10138            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10139                    "Locking fully");
10140            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10141                    ActivityManager.LOCK_TASK_MODE_PINNED :
10142                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10143                    "startLockTask", true);
10144        } finally {
10145            Binder.restoreCallingIdentity(ident);
10146        }
10147    }
10148
10149    @Override
10150    public void startLockTaskMode(int taskId) {
10151        synchronized (this) {
10152            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10153            if (task != null) {
10154                startLockTaskModeLocked(task);
10155            }
10156        }
10157    }
10158
10159    @Override
10160    public void startLockTaskMode(IBinder token) {
10161        synchronized (this) {
10162            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10163            if (r == null) {
10164                return;
10165            }
10166            final TaskRecord task = r.task;
10167            if (task != null) {
10168                startLockTaskModeLocked(task);
10169            }
10170        }
10171    }
10172
10173    @Override
10174    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10175        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10176        // This makes inner call to look as if it was initiated by system.
10177        long ident = Binder.clearCallingIdentity();
10178        try {
10179            synchronized (this) {
10180                startLockTaskMode(taskId);
10181            }
10182        } finally {
10183            Binder.restoreCallingIdentity(ident);
10184        }
10185    }
10186
10187    @Override
10188    public void stopLockTaskMode() {
10189        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10190        if (lockTask == null) {
10191            // Our work here is done.
10192            return;
10193        }
10194
10195        final int callingUid = Binder.getCallingUid();
10196        final int lockTaskUid = lockTask.mLockTaskUid;
10197        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10198        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10199            // Done.
10200            return;
10201        } else {
10202            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10203            // It is possible lockTaskMode was started by the system process because
10204            // android:lockTaskMode is set to a locking value in the application manifest
10205            // instead of the app calling startLockTaskMode. In this case
10206            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10207            // {@link TaskRecord.effectiveUid} instead. Also caller with
10208            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10209            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10210                    && callingUid != lockTaskUid
10211                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10212                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10213                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10214            }
10215        }
10216        long ident = Binder.clearCallingIdentity();
10217        try {
10218            Log.d(TAG, "stopLockTaskMode");
10219            // Stop lock task
10220            synchronized (this) {
10221                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10222                        "stopLockTask", true);
10223            }
10224            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10225            if (tm != null) {
10226                tm.showInCallScreen(false);
10227            }
10228        } finally {
10229            Binder.restoreCallingIdentity(ident);
10230        }
10231    }
10232
10233    /**
10234     * This API should be called by SystemUI only when user perform certain action to dismiss
10235     * lock task mode. We should only dismiss pinned lock task mode in this case.
10236     */
10237    @Override
10238    public void stopSystemLockTaskMode() throws RemoteException {
10239        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10240            stopLockTaskMode();
10241        } else {
10242            mStackSupervisor.showLockTaskToast();
10243        }
10244    }
10245
10246    @Override
10247    public boolean isInLockTaskMode() {
10248        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10249    }
10250
10251    @Override
10252    public int getLockTaskModeState() {
10253        synchronized (this) {
10254            return mStackSupervisor.getLockTaskModeState();
10255        }
10256    }
10257
10258    @Override
10259    public void showLockTaskEscapeMessage(IBinder token) {
10260        synchronized (this) {
10261            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10262            if (r == null) {
10263                return;
10264            }
10265            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10266        }
10267    }
10268
10269    // =========================================================
10270    // CONTENT PROVIDERS
10271    // =========================================================
10272
10273    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10274        List<ProviderInfo> providers = null;
10275        try {
10276            providers = AppGlobals.getPackageManager()
10277                    .queryContentProviders(app.processName, app.uid,
10278                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10279                                    | MATCH_DEBUG_TRIAGED_MISSING)
10280                    .getList();
10281        } catch (RemoteException ex) {
10282        }
10283        if (DEBUG_MU) Slog.v(TAG_MU,
10284                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10285        int userId = app.userId;
10286        if (providers != null) {
10287            int N = providers.size();
10288            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10289            for (int i=0; i<N; i++) {
10290                // TODO: keep logic in sync with installEncryptionUnawareProviders
10291                ProviderInfo cpi =
10292                    (ProviderInfo)providers.get(i);
10293                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10294                        cpi.name, cpi.flags);
10295                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10296                    // This is a singleton provider, but a user besides the
10297                    // default user is asking to initialize a process it runs
10298                    // in...  well, no, it doesn't actually run in this process,
10299                    // it runs in the process of the default user.  Get rid of it.
10300                    providers.remove(i);
10301                    N--;
10302                    i--;
10303                    continue;
10304                }
10305
10306                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10307                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10308                if (cpr == null) {
10309                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10310                    mProviderMap.putProviderByClass(comp, cpr);
10311                }
10312                if (DEBUG_MU) Slog.v(TAG_MU,
10313                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10314                app.pubProviders.put(cpi.name, cpr);
10315                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10316                    // Don't add this if it is a platform component that is marked
10317                    // to run in multiple processes, because this is actually
10318                    // part of the framework so doesn't make sense to track as a
10319                    // separate apk in the process.
10320                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10321                            mProcessStats);
10322                }
10323                notifyPackageUse(cpi.applicationInfo.packageName,
10324                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10325            }
10326        }
10327        return providers;
10328    }
10329
10330    /**
10331     * Check if {@link ProcessRecord} has a possible chance at accessing the
10332     * given {@link ProviderInfo}. Final permission checking is always done
10333     * in {@link ContentProvider}.
10334     */
10335    private final String checkContentProviderPermissionLocked(
10336            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10337        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10338        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10339        boolean checkedGrants = false;
10340        if (checkUser) {
10341            // Looking for cross-user grants before enforcing the typical cross-users permissions
10342            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10343            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10344                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10345                    return null;
10346                }
10347                checkedGrants = true;
10348            }
10349            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10350                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10351            if (userId != tmpTargetUserId) {
10352                // When we actually went to determine the final targer user ID, this ended
10353                // up different than our initial check for the authority.  This is because
10354                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10355                // SELF.  So we need to re-check the grants again.
10356                checkedGrants = false;
10357            }
10358        }
10359        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10360                cpi.applicationInfo.uid, cpi.exported)
10361                == PackageManager.PERMISSION_GRANTED) {
10362            return null;
10363        }
10364        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10365                cpi.applicationInfo.uid, cpi.exported)
10366                == PackageManager.PERMISSION_GRANTED) {
10367            return null;
10368        }
10369
10370        PathPermission[] pps = cpi.pathPermissions;
10371        if (pps != null) {
10372            int i = pps.length;
10373            while (i > 0) {
10374                i--;
10375                PathPermission pp = pps[i];
10376                String pprperm = pp.getReadPermission();
10377                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10378                        cpi.applicationInfo.uid, cpi.exported)
10379                        == PackageManager.PERMISSION_GRANTED) {
10380                    return null;
10381                }
10382                String ppwperm = pp.getWritePermission();
10383                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10384                        cpi.applicationInfo.uid, cpi.exported)
10385                        == PackageManager.PERMISSION_GRANTED) {
10386                    return null;
10387                }
10388            }
10389        }
10390        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10391            return null;
10392        }
10393
10394        String msg;
10395        if (!cpi.exported) {
10396            msg = "Permission Denial: opening provider " + cpi.name
10397                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10398                    + ", uid=" + callingUid + ") that is not exported from uid "
10399                    + cpi.applicationInfo.uid;
10400        } else {
10401            msg = "Permission Denial: opening provider " + cpi.name
10402                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10403                    + ", uid=" + callingUid + ") requires "
10404                    + cpi.readPermission + " or " + cpi.writePermission;
10405        }
10406        Slog.w(TAG, msg);
10407        return msg;
10408    }
10409
10410    /**
10411     * Returns if the ContentProvider has granted a uri to callingUid
10412     */
10413    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10414        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10415        if (perms != null) {
10416            for (int i=perms.size()-1; i>=0; i--) {
10417                GrantUri grantUri = perms.keyAt(i);
10418                if (grantUri.sourceUserId == userId || !checkUser) {
10419                    if (matchesProvider(grantUri.uri, cpi)) {
10420                        return true;
10421                    }
10422                }
10423            }
10424        }
10425        return false;
10426    }
10427
10428    /**
10429     * Returns true if the uri authority is one of the authorities specified in the provider.
10430     */
10431    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10432        String uriAuth = uri.getAuthority();
10433        String cpiAuth = cpi.authority;
10434        if (cpiAuth.indexOf(';') == -1) {
10435            return cpiAuth.equals(uriAuth);
10436        }
10437        String[] cpiAuths = cpiAuth.split(";");
10438        int length = cpiAuths.length;
10439        for (int i = 0; i < length; i++) {
10440            if (cpiAuths[i].equals(uriAuth)) return true;
10441        }
10442        return false;
10443    }
10444
10445    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10446            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10447        if (r != null) {
10448            for (int i=0; i<r.conProviders.size(); i++) {
10449                ContentProviderConnection conn = r.conProviders.get(i);
10450                if (conn.provider == cpr) {
10451                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10452                            "Adding provider requested by "
10453                            + r.processName + " from process "
10454                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10455                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10456                    if (stable) {
10457                        conn.stableCount++;
10458                        conn.numStableIncs++;
10459                    } else {
10460                        conn.unstableCount++;
10461                        conn.numUnstableIncs++;
10462                    }
10463                    return conn;
10464                }
10465            }
10466            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10467            if (stable) {
10468                conn.stableCount = 1;
10469                conn.numStableIncs = 1;
10470            } else {
10471                conn.unstableCount = 1;
10472                conn.numUnstableIncs = 1;
10473            }
10474            cpr.connections.add(conn);
10475            r.conProviders.add(conn);
10476            startAssociationLocked(r.uid, r.processName, r.curProcState,
10477                    cpr.uid, cpr.name, cpr.info.processName);
10478            return conn;
10479        }
10480        cpr.addExternalProcessHandleLocked(externalProcessToken);
10481        return null;
10482    }
10483
10484    boolean decProviderCountLocked(ContentProviderConnection conn,
10485            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10486        if (conn != null) {
10487            cpr = conn.provider;
10488            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10489                    "Removing provider requested by "
10490                    + conn.client.processName + " from process "
10491                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10492                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10493            if (stable) {
10494                conn.stableCount--;
10495            } else {
10496                conn.unstableCount--;
10497            }
10498            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10499                cpr.connections.remove(conn);
10500                conn.client.conProviders.remove(conn);
10501                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10502                    // The client is more important than last activity -- note the time this
10503                    // is happening, so we keep the old provider process around a bit as last
10504                    // activity to avoid thrashing it.
10505                    if (cpr.proc != null) {
10506                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10507                    }
10508                }
10509                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10510                return true;
10511            }
10512            return false;
10513        }
10514        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10515        return false;
10516    }
10517
10518    private void checkTime(long startTime, String where) {
10519        long now = SystemClock.uptimeMillis();
10520        if ((now-startTime) > 50) {
10521            // If we are taking more than 50ms, log about it.
10522            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10523        }
10524    }
10525
10526    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10527            PROC_SPACE_TERM,
10528            PROC_SPACE_TERM|PROC_PARENS,
10529            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10530    };
10531
10532    private final long[] mProcessStateStatsLongs = new long[1];
10533
10534    boolean isProcessAliveLocked(ProcessRecord proc) {
10535        if (proc.procStatFile == null) {
10536            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10537        }
10538        mProcessStateStatsLongs[0] = 0;
10539        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10540                mProcessStateStatsLongs, null)) {
10541            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10542            return false;
10543        }
10544        final long state = mProcessStateStatsLongs[0];
10545        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10546                + (char)state);
10547        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10548    }
10549
10550    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10551            String name, IBinder token, boolean stable, int userId) {
10552        ContentProviderRecord cpr;
10553        ContentProviderConnection conn = null;
10554        ProviderInfo cpi = null;
10555
10556        synchronized(this) {
10557            long startTime = SystemClock.uptimeMillis();
10558
10559            ProcessRecord r = null;
10560            if (caller != null) {
10561                r = getRecordForAppLocked(caller);
10562                if (r == null) {
10563                    throw new SecurityException(
10564                            "Unable to find app for caller " + caller
10565                          + " (pid=" + Binder.getCallingPid()
10566                          + ") when getting content provider " + name);
10567                }
10568            }
10569
10570            boolean checkCrossUser = true;
10571
10572            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10573
10574            // First check if this content provider has been published...
10575            cpr = mProviderMap.getProviderByName(name, userId);
10576            // If that didn't work, check if it exists for user 0 and then
10577            // verify that it's a singleton provider before using it.
10578            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10579                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10580                if (cpr != null) {
10581                    cpi = cpr.info;
10582                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10583                            cpi.name, cpi.flags)
10584                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10585                        userId = UserHandle.USER_SYSTEM;
10586                        checkCrossUser = false;
10587                    } else {
10588                        cpr = null;
10589                        cpi = null;
10590                    }
10591                }
10592            }
10593
10594            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10595            if (providerRunning) {
10596                cpi = cpr.info;
10597                String msg;
10598                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10599                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10600                        != null) {
10601                    throw new SecurityException(msg);
10602                }
10603                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10604
10605                if (r != null && cpr.canRunHere(r)) {
10606                    // This provider has been published or is in the process
10607                    // of being published...  but it is also allowed to run
10608                    // in the caller's process, so don't make a connection
10609                    // and just let the caller instantiate its own instance.
10610                    ContentProviderHolder holder = cpr.newHolder(null);
10611                    // don't give caller the provider object, it needs
10612                    // to make its own.
10613                    holder.provider = null;
10614                    return holder;
10615                }
10616
10617                final long origId = Binder.clearCallingIdentity();
10618
10619                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10620
10621                // In this case the provider instance already exists, so we can
10622                // return it right away.
10623                conn = incProviderCountLocked(r, cpr, token, stable);
10624                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10625                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10626                        // If this is a perceptible app accessing the provider,
10627                        // make sure to count it as being accessed and thus
10628                        // back up on the LRU list.  This is good because
10629                        // content providers are often expensive to start.
10630                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10631                        updateLruProcessLocked(cpr.proc, false, null);
10632                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10633                    }
10634                }
10635
10636                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10637                final int verifiedAdj = cpr.proc.verifiedAdj;
10638                boolean success = updateOomAdjLocked(cpr.proc);
10639                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10640                // if the process has been successfully adjusted.  So to reduce races with
10641                // it, we will check whether the process still exists.  Note that this doesn't
10642                // completely get rid of races with LMK killing the process, but should make
10643                // them much smaller.
10644                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10645                    success = false;
10646                }
10647                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10648                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10649                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10650                // NOTE: there is still a race here where a signal could be
10651                // pending on the process even though we managed to update its
10652                // adj level.  Not sure what to do about this, but at least
10653                // the race is now smaller.
10654                if (!success) {
10655                    // Uh oh...  it looks like the provider's process
10656                    // has been killed on us.  We need to wait for a new
10657                    // process to be started, and make sure its death
10658                    // doesn't kill our process.
10659                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10660                            + " is crashing; detaching " + r);
10661                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10662                    checkTime(startTime, "getContentProviderImpl: before appDied");
10663                    appDiedLocked(cpr.proc);
10664                    checkTime(startTime, "getContentProviderImpl: after appDied");
10665                    if (!lastRef) {
10666                        // This wasn't the last ref our process had on
10667                        // the provider...  we have now been killed, bail.
10668                        return null;
10669                    }
10670                    providerRunning = false;
10671                    conn = null;
10672                } else {
10673                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10674                }
10675
10676                Binder.restoreCallingIdentity(origId);
10677            }
10678
10679            if (!providerRunning) {
10680                try {
10681                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10682                    cpi = AppGlobals.getPackageManager().
10683                        resolveContentProvider(name,
10684                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10685                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10686                } catch (RemoteException ex) {
10687                }
10688                if (cpi == null) {
10689                    return null;
10690                }
10691                // If the provider is a singleton AND
10692                // (it's a call within the same user || the provider is a
10693                // privileged app)
10694                // Then allow connecting to the singleton provider
10695                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10696                        cpi.name, cpi.flags)
10697                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10698                if (singleton) {
10699                    userId = UserHandle.USER_SYSTEM;
10700                }
10701                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10702                checkTime(startTime, "getContentProviderImpl: got app info for user");
10703
10704                String msg;
10705                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10706                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10707                        != null) {
10708                    throw new SecurityException(msg);
10709                }
10710                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10711
10712                if (!mProcessesReady
10713                        && !cpi.processName.equals("system")) {
10714                    // If this content provider does not run in the system
10715                    // process, and the system is not yet ready to run other
10716                    // processes, then fail fast instead of hanging.
10717                    throw new IllegalArgumentException(
10718                            "Attempt to launch content provider before system ready");
10719                }
10720
10721                // Make sure that the user who owns this provider is running.  If not,
10722                // we don't want to allow it to run.
10723                if (!mUserController.isUserRunningLocked(userId, 0)) {
10724                    Slog.w(TAG, "Unable to launch app "
10725                            + cpi.applicationInfo.packageName + "/"
10726                            + cpi.applicationInfo.uid + " for provider "
10727                            + name + ": user " + userId + " is stopped");
10728                    return null;
10729                }
10730
10731                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10732                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10733                cpr = mProviderMap.getProviderByClass(comp, userId);
10734                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10735                final boolean firstClass = cpr == null;
10736                if (firstClass) {
10737                    final long ident = Binder.clearCallingIdentity();
10738
10739                    // If permissions need a review before any of the app components can run,
10740                    // we return no provider and launch a review activity if the calling app
10741                    // is in the foreground.
10742                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10743                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10744                            return null;
10745                        }
10746                    }
10747
10748                    try {
10749                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10750                        ApplicationInfo ai =
10751                            AppGlobals.getPackageManager().
10752                                getApplicationInfo(
10753                                        cpi.applicationInfo.packageName,
10754                                        STOCK_PM_FLAGS, userId);
10755                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10756                        if (ai == null) {
10757                            Slog.w(TAG, "No package info for content provider "
10758                                    + cpi.name);
10759                            return null;
10760                        }
10761                        ai = getAppInfoForUser(ai, userId);
10762                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10763                    } catch (RemoteException ex) {
10764                        // pm is in same process, this will never happen.
10765                    } finally {
10766                        Binder.restoreCallingIdentity(ident);
10767                    }
10768                }
10769
10770                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10771
10772                if (r != null && cpr.canRunHere(r)) {
10773                    // If this is a multiprocess provider, then just return its
10774                    // info and allow the caller to instantiate it.  Only do
10775                    // this if the provider is the same user as the caller's
10776                    // process, or can run as root (so can be in any process).
10777                    return cpr.newHolder(null);
10778                }
10779
10780                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10781                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10782                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10783
10784                // This is single process, and our app is now connecting to it.
10785                // See if we are already in the process of launching this
10786                // provider.
10787                final int N = mLaunchingProviders.size();
10788                int i;
10789                for (i = 0; i < N; i++) {
10790                    if (mLaunchingProviders.get(i) == cpr) {
10791                        break;
10792                    }
10793                }
10794
10795                // If the provider is not already being launched, then get it
10796                // started.
10797                if (i >= N) {
10798                    final long origId = Binder.clearCallingIdentity();
10799
10800                    try {
10801                        // Content provider is now in use, its package can't be stopped.
10802                        try {
10803                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10804                            AppGlobals.getPackageManager().setPackageStoppedState(
10805                                    cpr.appInfo.packageName, false, userId);
10806                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10807                        } catch (RemoteException e) {
10808                        } catch (IllegalArgumentException e) {
10809                            Slog.w(TAG, "Failed trying to unstop package "
10810                                    + cpr.appInfo.packageName + ": " + e);
10811                        }
10812
10813                        // Use existing process if already started
10814                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10815                        ProcessRecord proc = getProcessRecordLocked(
10816                                cpi.processName, cpr.appInfo.uid, false);
10817                        if (proc != null && proc.thread != null && !proc.killed) {
10818                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10819                                    "Installing in existing process " + proc);
10820                            if (!proc.pubProviders.containsKey(cpi.name)) {
10821                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10822                                proc.pubProviders.put(cpi.name, cpr);
10823                                try {
10824                                    proc.thread.scheduleInstallProvider(cpi);
10825                                } catch (RemoteException e) {
10826                                }
10827                            }
10828                        } else {
10829                            checkTime(startTime, "getContentProviderImpl: before start process");
10830                            proc = startProcessLocked(cpi.processName,
10831                                    cpr.appInfo, false, 0, "content provider",
10832                                    new ComponentName(cpi.applicationInfo.packageName,
10833                                            cpi.name), false, false, false);
10834                            checkTime(startTime, "getContentProviderImpl: after start process");
10835                            if (proc == null) {
10836                                Slog.w(TAG, "Unable to launch app "
10837                                        + cpi.applicationInfo.packageName + "/"
10838                                        + cpi.applicationInfo.uid + " for provider "
10839                                        + name + ": process is bad");
10840                                return null;
10841                            }
10842                        }
10843                        cpr.launchingApp = proc;
10844                        mLaunchingProviders.add(cpr);
10845                    } finally {
10846                        Binder.restoreCallingIdentity(origId);
10847                    }
10848                }
10849
10850                checkTime(startTime, "getContentProviderImpl: updating data structures");
10851
10852                // Make sure the provider is published (the same provider class
10853                // may be published under multiple names).
10854                if (firstClass) {
10855                    mProviderMap.putProviderByClass(comp, cpr);
10856                }
10857
10858                mProviderMap.putProviderByName(name, cpr);
10859                conn = incProviderCountLocked(r, cpr, token, stable);
10860                if (conn != null) {
10861                    conn.waiting = true;
10862                }
10863            }
10864            checkTime(startTime, "getContentProviderImpl: done!");
10865        }
10866
10867        // Wait for the provider to be published...
10868        synchronized (cpr) {
10869            while (cpr.provider == null) {
10870                if (cpr.launchingApp == null) {
10871                    Slog.w(TAG, "Unable to launch app "
10872                            + cpi.applicationInfo.packageName + "/"
10873                            + cpi.applicationInfo.uid + " for provider "
10874                            + name + ": launching app became null");
10875                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10876                            UserHandle.getUserId(cpi.applicationInfo.uid),
10877                            cpi.applicationInfo.packageName,
10878                            cpi.applicationInfo.uid, name);
10879                    return null;
10880                }
10881                try {
10882                    if (DEBUG_MU) Slog.v(TAG_MU,
10883                            "Waiting to start provider " + cpr
10884                            + " launchingApp=" + cpr.launchingApp);
10885                    if (conn != null) {
10886                        conn.waiting = true;
10887                    }
10888                    cpr.wait();
10889                } catch (InterruptedException ex) {
10890                } finally {
10891                    if (conn != null) {
10892                        conn.waiting = false;
10893                    }
10894                }
10895            }
10896        }
10897        return cpr != null ? cpr.newHolder(conn) : null;
10898    }
10899
10900    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10901            ProcessRecord r, final int userId) {
10902        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10903                cpi.packageName, userId)) {
10904
10905            final boolean callerForeground = r == null || r.setSchedGroup
10906                    != ProcessList.SCHED_GROUP_BACKGROUND;
10907
10908            // Show a permission review UI only for starting from a foreground app
10909            if (!callerForeground) {
10910                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10911                        + cpi.packageName + " requires a permissions review");
10912                return false;
10913            }
10914
10915            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10916            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10917                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10918            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10919
10920            if (DEBUG_PERMISSIONS_REVIEW) {
10921                Slog.i(TAG, "u" + userId + " Launching permission review "
10922                        + "for package " + cpi.packageName);
10923            }
10924
10925            final UserHandle userHandle = new UserHandle(userId);
10926            mHandler.post(new Runnable() {
10927                @Override
10928                public void run() {
10929                    mContext.startActivityAsUser(intent, userHandle);
10930                }
10931            });
10932
10933            return false;
10934        }
10935
10936        return true;
10937    }
10938
10939    PackageManagerInternal getPackageManagerInternalLocked() {
10940        if (mPackageManagerInt == null) {
10941            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10942        }
10943        return mPackageManagerInt;
10944    }
10945
10946    @Override
10947    public final ContentProviderHolder getContentProvider(
10948            IApplicationThread caller, String name, int userId, boolean stable) {
10949        enforceNotIsolatedCaller("getContentProvider");
10950        if (caller == null) {
10951            String msg = "null IApplicationThread when getting content provider "
10952                    + name;
10953            Slog.w(TAG, msg);
10954            throw new SecurityException(msg);
10955        }
10956        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10957        // with cross-user grant.
10958        return getContentProviderImpl(caller, name, null, stable, userId);
10959    }
10960
10961    public ContentProviderHolder getContentProviderExternal(
10962            String name, int userId, IBinder token) {
10963        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10964            "Do not have permission in call getContentProviderExternal()");
10965        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10966                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10967        return getContentProviderExternalUnchecked(name, token, userId);
10968    }
10969
10970    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10971            IBinder token, int userId) {
10972        return getContentProviderImpl(null, name, token, true, userId);
10973    }
10974
10975    /**
10976     * Drop a content provider from a ProcessRecord's bookkeeping
10977     */
10978    public void removeContentProvider(IBinder connection, boolean stable) {
10979        enforceNotIsolatedCaller("removeContentProvider");
10980        long ident = Binder.clearCallingIdentity();
10981        try {
10982            synchronized (this) {
10983                ContentProviderConnection conn;
10984                try {
10985                    conn = (ContentProviderConnection)connection;
10986                } catch (ClassCastException e) {
10987                    String msg ="removeContentProvider: " + connection
10988                            + " not a ContentProviderConnection";
10989                    Slog.w(TAG, msg);
10990                    throw new IllegalArgumentException(msg);
10991                }
10992                if (conn == null) {
10993                    throw new NullPointerException("connection is null");
10994                }
10995                if (decProviderCountLocked(conn, null, null, stable)) {
10996                    updateOomAdjLocked();
10997                }
10998            }
10999        } finally {
11000            Binder.restoreCallingIdentity(ident);
11001        }
11002    }
11003
11004    public void removeContentProviderExternal(String name, IBinder token) {
11005        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11006            "Do not have permission in call removeContentProviderExternal()");
11007        int userId = UserHandle.getCallingUserId();
11008        long ident = Binder.clearCallingIdentity();
11009        try {
11010            removeContentProviderExternalUnchecked(name, token, userId);
11011        } finally {
11012            Binder.restoreCallingIdentity(ident);
11013        }
11014    }
11015
11016    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11017        synchronized (this) {
11018            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11019            if(cpr == null) {
11020                //remove from mProvidersByClass
11021                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11022                return;
11023            }
11024
11025            //update content provider record entry info
11026            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11027            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11028            if (localCpr.hasExternalProcessHandles()) {
11029                if (localCpr.removeExternalProcessHandleLocked(token)) {
11030                    updateOomAdjLocked();
11031                } else {
11032                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11033                            + " with no external reference for token: "
11034                            + token + ".");
11035                }
11036            } else {
11037                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11038                        + " with no external references.");
11039            }
11040        }
11041    }
11042
11043    public final void publishContentProviders(IApplicationThread caller,
11044            List<ContentProviderHolder> providers) {
11045        if (providers == null) {
11046            return;
11047        }
11048
11049        enforceNotIsolatedCaller("publishContentProviders");
11050        synchronized (this) {
11051            final ProcessRecord r = getRecordForAppLocked(caller);
11052            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11053            if (r == null) {
11054                throw new SecurityException(
11055                        "Unable to find app for caller " + caller
11056                      + " (pid=" + Binder.getCallingPid()
11057                      + ") when publishing content providers");
11058            }
11059
11060            final long origId = Binder.clearCallingIdentity();
11061
11062            final int N = providers.size();
11063            for (int i = 0; i < N; i++) {
11064                ContentProviderHolder src = providers.get(i);
11065                if (src == null || src.info == null || src.provider == null) {
11066                    continue;
11067                }
11068                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11069                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11070                if (dst != null) {
11071                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11072                    mProviderMap.putProviderByClass(comp, dst);
11073                    String names[] = dst.info.authority.split(";");
11074                    for (int j = 0; j < names.length; j++) {
11075                        mProviderMap.putProviderByName(names[j], dst);
11076                    }
11077
11078                    int launchingCount = mLaunchingProviders.size();
11079                    int j;
11080                    boolean wasInLaunchingProviders = false;
11081                    for (j = 0; j < launchingCount; j++) {
11082                        if (mLaunchingProviders.get(j) == dst) {
11083                            mLaunchingProviders.remove(j);
11084                            wasInLaunchingProviders = true;
11085                            j--;
11086                            launchingCount--;
11087                        }
11088                    }
11089                    if (wasInLaunchingProviders) {
11090                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11091                    }
11092                    synchronized (dst) {
11093                        dst.provider = src.provider;
11094                        dst.proc = r;
11095                        dst.notifyAll();
11096                    }
11097                    updateOomAdjLocked(r);
11098                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11099                            src.info.authority);
11100                }
11101            }
11102
11103            Binder.restoreCallingIdentity(origId);
11104        }
11105    }
11106
11107    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11108        ContentProviderConnection conn;
11109        try {
11110            conn = (ContentProviderConnection)connection;
11111        } catch (ClassCastException e) {
11112            String msg ="refContentProvider: " + connection
11113                    + " not a ContentProviderConnection";
11114            Slog.w(TAG, msg);
11115            throw new IllegalArgumentException(msg);
11116        }
11117        if (conn == null) {
11118            throw new NullPointerException("connection is null");
11119        }
11120
11121        synchronized (this) {
11122            if (stable > 0) {
11123                conn.numStableIncs += stable;
11124            }
11125            stable = conn.stableCount + stable;
11126            if (stable < 0) {
11127                throw new IllegalStateException("stableCount < 0: " + stable);
11128            }
11129
11130            if (unstable > 0) {
11131                conn.numUnstableIncs += unstable;
11132            }
11133            unstable = conn.unstableCount + unstable;
11134            if (unstable < 0) {
11135                throw new IllegalStateException("unstableCount < 0: " + unstable);
11136            }
11137
11138            if ((stable+unstable) <= 0) {
11139                throw new IllegalStateException("ref counts can't go to zero here: stable="
11140                        + stable + " unstable=" + unstable);
11141            }
11142            conn.stableCount = stable;
11143            conn.unstableCount = unstable;
11144            return !conn.dead;
11145        }
11146    }
11147
11148    public void unstableProviderDied(IBinder connection) {
11149        ContentProviderConnection conn;
11150        try {
11151            conn = (ContentProviderConnection)connection;
11152        } catch (ClassCastException e) {
11153            String msg ="refContentProvider: " + connection
11154                    + " not a ContentProviderConnection";
11155            Slog.w(TAG, msg);
11156            throw new IllegalArgumentException(msg);
11157        }
11158        if (conn == null) {
11159            throw new NullPointerException("connection is null");
11160        }
11161
11162        // Safely retrieve the content provider associated with the connection.
11163        IContentProvider provider;
11164        synchronized (this) {
11165            provider = conn.provider.provider;
11166        }
11167
11168        if (provider == null) {
11169            // Um, yeah, we're way ahead of you.
11170            return;
11171        }
11172
11173        // Make sure the caller is being honest with us.
11174        if (provider.asBinder().pingBinder()) {
11175            // Er, no, still looks good to us.
11176            synchronized (this) {
11177                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11178                        + " says " + conn + " died, but we don't agree");
11179                return;
11180            }
11181        }
11182
11183        // Well look at that!  It's dead!
11184        synchronized (this) {
11185            if (conn.provider.provider != provider) {
11186                // But something changed...  good enough.
11187                return;
11188            }
11189
11190            ProcessRecord proc = conn.provider.proc;
11191            if (proc == null || proc.thread == null) {
11192                // Seems like the process is already cleaned up.
11193                return;
11194            }
11195
11196            // As far as we're concerned, this is just like receiving a
11197            // death notification...  just a bit prematurely.
11198            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11199                    + ") early provider death");
11200            final long ident = Binder.clearCallingIdentity();
11201            try {
11202                appDiedLocked(proc);
11203            } finally {
11204                Binder.restoreCallingIdentity(ident);
11205            }
11206        }
11207    }
11208
11209    @Override
11210    public void appNotRespondingViaProvider(IBinder connection) {
11211        enforceCallingPermission(
11212                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11213
11214        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11215        if (conn == null) {
11216            Slog.w(TAG, "ContentProviderConnection is null");
11217            return;
11218        }
11219
11220        final ProcessRecord host = conn.provider.proc;
11221        if (host == null) {
11222            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11223            return;
11224        }
11225
11226        mHandler.post(new Runnable() {
11227            @Override
11228            public void run() {
11229                mAppErrors.appNotResponding(host, null, null, false,
11230                        "ContentProvider not responding");
11231            }
11232        });
11233    }
11234
11235    public final void installSystemProviders() {
11236        List<ProviderInfo> providers;
11237        synchronized (this) {
11238            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11239            providers = generateApplicationProvidersLocked(app);
11240            if (providers != null) {
11241                for (int i=providers.size()-1; i>=0; i--) {
11242                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11243                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11244                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11245                                + ": not system .apk");
11246                        providers.remove(i);
11247                    }
11248                }
11249            }
11250        }
11251        if (providers != null) {
11252            mSystemThread.installSystemProviders(providers);
11253        }
11254
11255        mCoreSettingsObserver = new CoreSettingsObserver(this);
11256        mFontScaleSettingObserver = new FontScaleSettingObserver();
11257
11258        //mUsageStatsService.monitorPackages();
11259    }
11260
11261    private void startPersistentApps(int matchFlags) {
11262        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11263
11264        synchronized (this) {
11265            try {
11266                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11267                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11268                for (ApplicationInfo app : apps) {
11269                    if (!"android".equals(app.packageName)) {
11270                        addAppLocked(app, false, null /* ABI override */);
11271                    }
11272                }
11273            } catch (RemoteException ex) {
11274            }
11275        }
11276    }
11277
11278    /**
11279     * When a user is unlocked, we need to install encryption-unaware providers
11280     * belonging to any running apps.
11281     */
11282    private void installEncryptionUnawareProviders(int userId) {
11283        // We're only interested in providers that are encryption unaware, and
11284        // we don't care about uninstalled apps, since there's no way they're
11285        // running at this point.
11286        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11287
11288        synchronized (this) {
11289            final int NP = mProcessNames.getMap().size();
11290            for (int ip = 0; ip < NP; ip++) {
11291                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11292                final int NA = apps.size();
11293                for (int ia = 0; ia < NA; ia++) {
11294                    final ProcessRecord app = apps.valueAt(ia);
11295                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11296
11297                    final int NG = app.pkgList.size();
11298                    for (int ig = 0; ig < NG; ig++) {
11299                        try {
11300                            final String pkgName = app.pkgList.keyAt(ig);
11301                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11302                                    .getPackageInfo(pkgName, matchFlags, userId);
11303                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11304                                for (ProviderInfo pi : pkgInfo.providers) {
11305                                    // TODO: keep in sync with generateApplicationProvidersLocked
11306                                    final boolean processMatch = Objects.equals(pi.processName,
11307                                            app.processName) || pi.multiprocess;
11308                                    final boolean userMatch = isSingleton(pi.processName,
11309                                            pi.applicationInfo, pi.name, pi.flags)
11310                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11311                                    if (processMatch && userMatch) {
11312                                        Log.v(TAG, "Installing " + pi);
11313                                        app.thread.scheduleInstallProvider(pi);
11314                                    } else {
11315                                        Log.v(TAG, "Skipping " + pi);
11316                                    }
11317                                }
11318                            }
11319                        } catch (RemoteException ignored) {
11320                        }
11321                    }
11322                }
11323            }
11324        }
11325    }
11326
11327    /**
11328     * Allows apps to retrieve the MIME type of a URI.
11329     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11330     * users, then it does not need permission to access the ContentProvider.
11331     * Either, it needs cross-user uri grants.
11332     *
11333     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11334     *
11335     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11336     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11337     */
11338    public String getProviderMimeType(Uri uri, int userId) {
11339        enforceNotIsolatedCaller("getProviderMimeType");
11340        final String name = uri.getAuthority();
11341        int callingUid = Binder.getCallingUid();
11342        int callingPid = Binder.getCallingPid();
11343        long ident = 0;
11344        boolean clearedIdentity = false;
11345        synchronized (this) {
11346            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11347        }
11348        if (canClearIdentity(callingPid, callingUid, userId)) {
11349            clearedIdentity = true;
11350            ident = Binder.clearCallingIdentity();
11351        }
11352        ContentProviderHolder holder = null;
11353        try {
11354            holder = getContentProviderExternalUnchecked(name, null, userId);
11355            if (holder != null) {
11356                return holder.provider.getType(uri);
11357            }
11358        } catch (RemoteException e) {
11359            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11360            return null;
11361        } catch (Exception e) {
11362            Log.w(TAG, "Exception while determining type of " + uri, e);
11363            return null;
11364        } finally {
11365            // We need to clear the identity to call removeContentProviderExternalUnchecked
11366            if (!clearedIdentity) {
11367                ident = Binder.clearCallingIdentity();
11368            }
11369            try {
11370                if (holder != null) {
11371                    removeContentProviderExternalUnchecked(name, null, userId);
11372                }
11373            } finally {
11374                Binder.restoreCallingIdentity(ident);
11375            }
11376        }
11377
11378        return null;
11379    }
11380
11381    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11382        if (UserHandle.getUserId(callingUid) == userId) {
11383            return true;
11384        }
11385        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11386                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11387                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11388                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11389                return true;
11390        }
11391        return false;
11392    }
11393
11394    // =========================================================
11395    // GLOBAL MANAGEMENT
11396    // =========================================================
11397
11398    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11399            boolean isolated, int isolatedUid) {
11400        String proc = customProcess != null ? customProcess : info.processName;
11401        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11402        final int userId = UserHandle.getUserId(info.uid);
11403        int uid = info.uid;
11404        if (isolated) {
11405            if (isolatedUid == 0) {
11406                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11407                while (true) {
11408                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11409                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11410                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11411                    }
11412                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11413                    mNextIsolatedProcessUid++;
11414                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11415                        // No process for this uid, use it.
11416                        break;
11417                    }
11418                    stepsLeft--;
11419                    if (stepsLeft <= 0) {
11420                        return null;
11421                    }
11422                }
11423            } else {
11424                // Special case for startIsolatedProcess (internal only), where
11425                // the uid of the isolated process is specified by the caller.
11426                uid = isolatedUid;
11427            }
11428        }
11429        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11430        if (!mBooted && !mBooting
11431                && userId == UserHandle.USER_SYSTEM
11432                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11433            r.persistent = true;
11434        }
11435        addProcessNameLocked(r);
11436        return r;
11437    }
11438
11439    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11440            String abiOverride) {
11441        ProcessRecord app;
11442        if (!isolated) {
11443            app = getProcessRecordLocked(info.processName, info.uid, true);
11444        } else {
11445            app = null;
11446        }
11447
11448        if (app == null) {
11449            app = newProcessRecordLocked(info, null, isolated, 0);
11450            updateLruProcessLocked(app, false, null);
11451            updateOomAdjLocked();
11452        }
11453
11454        // This package really, really can not be stopped.
11455        try {
11456            AppGlobals.getPackageManager().setPackageStoppedState(
11457                    info.packageName, false, UserHandle.getUserId(app.uid));
11458        } catch (RemoteException e) {
11459        } catch (IllegalArgumentException e) {
11460            Slog.w(TAG, "Failed trying to unstop package "
11461                    + info.packageName + ": " + e);
11462        }
11463
11464        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11465            app.persistent = true;
11466            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11467        }
11468        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11469            mPersistentStartingProcesses.add(app);
11470            startProcessLocked(app, "added application", app.processName, abiOverride,
11471                    null /* entryPoint */, null /* entryPointArgs */);
11472        }
11473
11474        return app;
11475    }
11476
11477    public void unhandledBack() {
11478        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11479                "unhandledBack()");
11480
11481        synchronized(this) {
11482            final long origId = Binder.clearCallingIdentity();
11483            try {
11484                getFocusedStack().unhandledBackLocked();
11485            } finally {
11486                Binder.restoreCallingIdentity(origId);
11487            }
11488        }
11489    }
11490
11491    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11492        enforceNotIsolatedCaller("openContentUri");
11493        final int userId = UserHandle.getCallingUserId();
11494        String name = uri.getAuthority();
11495        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11496        ParcelFileDescriptor pfd = null;
11497        if (cph != null) {
11498            // We record the binder invoker's uid in thread-local storage before
11499            // going to the content provider to open the file.  Later, in the code
11500            // that handles all permissions checks, we look for this uid and use
11501            // that rather than the Activity Manager's own uid.  The effect is that
11502            // we do the check against the caller's permissions even though it looks
11503            // to the content provider like the Activity Manager itself is making
11504            // the request.
11505            Binder token = new Binder();
11506            sCallerIdentity.set(new Identity(
11507                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11508            try {
11509                pfd = cph.provider.openFile(null, uri, "r", null, token);
11510            } catch (FileNotFoundException e) {
11511                // do nothing; pfd will be returned null
11512            } finally {
11513                // Ensure that whatever happens, we clean up the identity state
11514                sCallerIdentity.remove();
11515                // Ensure we're done with the provider.
11516                removeContentProviderExternalUnchecked(name, null, userId);
11517            }
11518        } else {
11519            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11520        }
11521        return pfd;
11522    }
11523
11524    // Actually is sleeping or shutting down or whatever else in the future
11525    // is an inactive state.
11526    boolean isSleepingOrShuttingDownLocked() {
11527        return isSleepingLocked() || mShuttingDown;
11528    }
11529
11530    boolean isShuttingDownLocked() {
11531        return mShuttingDown;
11532    }
11533
11534    boolean isSleepingLocked() {
11535        return mSleeping;
11536    }
11537
11538    void onWakefulnessChanged(int wakefulness) {
11539        synchronized(this) {
11540            mWakefulness = wakefulness;
11541            updateSleepIfNeededLocked();
11542        }
11543    }
11544
11545    void finishRunningVoiceLocked() {
11546        if (mRunningVoice != null) {
11547            mRunningVoice = null;
11548            mVoiceWakeLock.release();
11549            updateSleepIfNeededLocked();
11550        }
11551    }
11552
11553    void startTimeTrackingFocusedActivityLocked() {
11554        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11555            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11556        }
11557    }
11558
11559    void updateSleepIfNeededLocked() {
11560        if (mSleeping && !shouldSleepLocked()) {
11561            mSleeping = false;
11562            startTimeTrackingFocusedActivityLocked();
11563            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11564            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11565            updateOomAdjLocked();
11566        } else if (!mSleeping && shouldSleepLocked()) {
11567            mSleeping = true;
11568            if (mCurAppTimeTracker != null) {
11569                mCurAppTimeTracker.stop();
11570            }
11571            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11572            mStackSupervisor.goingToSleepLocked();
11573            updateOomAdjLocked();
11574
11575            // Initialize the wake times of all processes.
11576            checkExcessivePowerUsageLocked(false);
11577            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11578            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11579            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11580        }
11581    }
11582
11583    private boolean shouldSleepLocked() {
11584        // Resume applications while running a voice interactor.
11585        if (mRunningVoice != null) {
11586            return false;
11587        }
11588
11589        // TODO: Transform the lock screen state into a sleep token instead.
11590        switch (mWakefulness) {
11591            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11592            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11593            case PowerManagerInternal.WAKEFULNESS_DOZING:
11594                // Pause applications whenever the lock screen is shown or any sleep
11595                // tokens have been acquired.
11596                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11597            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11598            default:
11599                // If we're asleep then pause applications unconditionally.
11600                return true;
11601        }
11602    }
11603
11604    /** Pokes the task persister. */
11605    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11606        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11607    }
11608
11609    /** Notifies all listeners when the task stack has changed. */
11610    void notifyTaskStackChangedLocked() {
11611        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11612        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11613        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11614        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11615    }
11616
11617    /** Notifies all listeners when an Activity is pinned. */
11618    void notifyActivityPinnedLocked() {
11619        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11620        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11621    }
11622
11623    /**
11624     * Notifies all listeners when an attempt was made to start an an activity that is already
11625     * running in the pinned stack and the activity was not actually started, but the task is
11626     * either brought to the front or a new Intent is delivered to it.
11627     */
11628    void notifyPinnedActivityRestartAttemptLocked() {
11629        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11630        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11631    }
11632
11633    /** Notifies all listeners when the pinned stack animation ends. */
11634    @Override
11635    public void notifyPinnedStackAnimationEnded() {
11636        synchronized (this) {
11637            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11638            mHandler.obtainMessage(
11639                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11640        }
11641    }
11642
11643    @Override
11644    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11645        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11646    }
11647
11648    @Override
11649    public boolean shutdown(int timeout) {
11650        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11651                != PackageManager.PERMISSION_GRANTED) {
11652            throw new SecurityException("Requires permission "
11653                    + android.Manifest.permission.SHUTDOWN);
11654        }
11655
11656        boolean timedout = false;
11657
11658        synchronized(this) {
11659            mShuttingDown = true;
11660            updateEventDispatchingLocked();
11661            timedout = mStackSupervisor.shutdownLocked(timeout);
11662        }
11663
11664        mAppOpsService.shutdown();
11665        if (mUsageStatsService != null) {
11666            mUsageStatsService.prepareShutdown();
11667        }
11668        mBatteryStatsService.shutdown();
11669        synchronized (this) {
11670            mProcessStats.shutdownLocked();
11671            notifyTaskPersisterLocked(null, true);
11672        }
11673
11674        return timedout;
11675    }
11676
11677    public final void activitySlept(IBinder token) {
11678        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11679
11680        final long origId = Binder.clearCallingIdentity();
11681
11682        synchronized (this) {
11683            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11684            if (r != null) {
11685                mStackSupervisor.activitySleptLocked(r);
11686            }
11687        }
11688
11689        Binder.restoreCallingIdentity(origId);
11690    }
11691
11692    private String lockScreenShownToString() {
11693        switch (mLockScreenShown) {
11694            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11695            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11696            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11697            default: return "Unknown=" + mLockScreenShown;
11698        }
11699    }
11700
11701    void logLockScreen(String msg) {
11702        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11703                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11704                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11705                + " mSleeping=" + mSleeping);
11706    }
11707
11708    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11709        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11710        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11711        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11712            boolean wasRunningVoice = mRunningVoice != null;
11713            mRunningVoice = session;
11714            if (!wasRunningVoice) {
11715                mVoiceWakeLock.acquire();
11716                updateSleepIfNeededLocked();
11717            }
11718        }
11719    }
11720
11721    private void updateEventDispatchingLocked() {
11722        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11723    }
11724
11725    public void setLockScreenShown(boolean showing, boolean occluded) {
11726        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11727                != PackageManager.PERMISSION_GRANTED) {
11728            throw new SecurityException("Requires permission "
11729                    + android.Manifest.permission.DEVICE_POWER);
11730        }
11731
11732        synchronized(this) {
11733            long ident = Binder.clearCallingIdentity();
11734            try {
11735                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11736                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11737                if (showing && occluded) {
11738                    // The lock screen is currently showing, but is occluded by a window that can
11739                    // show on top of the lock screen. In this can we want to dismiss the docked
11740                    // stack since it will be complicated/risky to try to put the activity on top
11741                    // of the lock screen in the right fullscreen configuration.
11742                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11743                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11744                }
11745
11746                updateSleepIfNeededLocked();
11747            } finally {
11748                Binder.restoreCallingIdentity(ident);
11749            }
11750        }
11751    }
11752
11753    @Override
11754    public void notifyLockedProfile(@UserIdInt int userId) {
11755        try {
11756            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11757                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11758            }
11759        } catch (RemoteException ex) {
11760            throw new SecurityException("Fail to check is caller a privileged app", ex);
11761        }
11762
11763        synchronized (this) {
11764            if (mStackSupervisor.isUserLockedProfile(userId)) {
11765                final long ident = Binder.clearCallingIdentity();
11766                try {
11767                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11768                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11769                        // If there is no device lock, we will show the profile's credential page.
11770                        mActivityStarter.showConfirmDeviceCredential(userId);
11771                    } else {
11772                        // Showing launcher to avoid user entering credential twice.
11773                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11774                    }
11775                } finally {
11776                    Binder.restoreCallingIdentity(ident);
11777                }
11778            }
11779        }
11780    }
11781
11782    @Override
11783    public void startConfirmDeviceCredentialIntent(Intent intent) {
11784        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11785        synchronized (this) {
11786            final long ident = Binder.clearCallingIdentity();
11787            try {
11788                mActivityStarter.startConfirmCredentialIntent(intent);
11789            } finally {
11790                Binder.restoreCallingIdentity(ident);
11791            }
11792        }
11793    }
11794
11795    @Override
11796    public void stopAppSwitches() {
11797        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11798                != PackageManager.PERMISSION_GRANTED) {
11799            throw new SecurityException("viewquires permission "
11800                    + android.Manifest.permission.STOP_APP_SWITCHES);
11801        }
11802
11803        synchronized(this) {
11804            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11805                    + APP_SWITCH_DELAY_TIME;
11806            mDidAppSwitch = false;
11807            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11808            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11809            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11810        }
11811    }
11812
11813    public void resumeAppSwitches() {
11814        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11815                != PackageManager.PERMISSION_GRANTED) {
11816            throw new SecurityException("Requires permission "
11817                    + android.Manifest.permission.STOP_APP_SWITCHES);
11818        }
11819
11820        synchronized(this) {
11821            // Note that we don't execute any pending app switches... we will
11822            // let those wait until either the timeout, or the next start
11823            // activity request.
11824            mAppSwitchesAllowedTime = 0;
11825        }
11826    }
11827
11828    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11829            int callingPid, int callingUid, String name) {
11830        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11831            return true;
11832        }
11833
11834        int perm = checkComponentPermission(
11835                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11836                sourceUid, -1, true);
11837        if (perm == PackageManager.PERMISSION_GRANTED) {
11838            return true;
11839        }
11840
11841        // If the actual IPC caller is different from the logical source, then
11842        // also see if they are allowed to control app switches.
11843        if (callingUid != -1 && callingUid != sourceUid) {
11844            perm = checkComponentPermission(
11845                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11846                    callingUid, -1, true);
11847            if (perm == PackageManager.PERMISSION_GRANTED) {
11848                return true;
11849            }
11850        }
11851
11852        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11853        return false;
11854    }
11855
11856    public void setDebugApp(String packageName, boolean waitForDebugger,
11857            boolean persistent) {
11858        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11859                "setDebugApp()");
11860
11861        long ident = Binder.clearCallingIdentity();
11862        try {
11863            // Note that this is not really thread safe if there are multiple
11864            // callers into it at the same time, but that's not a situation we
11865            // care about.
11866            if (persistent) {
11867                final ContentResolver resolver = mContext.getContentResolver();
11868                Settings.Global.putString(
11869                    resolver, Settings.Global.DEBUG_APP,
11870                    packageName);
11871                Settings.Global.putInt(
11872                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11873                    waitForDebugger ? 1 : 0);
11874            }
11875
11876            synchronized (this) {
11877                if (!persistent) {
11878                    mOrigDebugApp = mDebugApp;
11879                    mOrigWaitForDebugger = mWaitForDebugger;
11880                }
11881                mDebugApp = packageName;
11882                mWaitForDebugger = waitForDebugger;
11883                mDebugTransient = !persistent;
11884                if (packageName != null) {
11885                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11886                            false, UserHandle.USER_ALL, "set debug app");
11887                }
11888            }
11889        } finally {
11890            Binder.restoreCallingIdentity(ident);
11891        }
11892    }
11893
11894    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11895        synchronized (this) {
11896            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11897            if (!isDebuggable) {
11898                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11899                    throw new SecurityException("Process not debuggable: " + app.packageName);
11900                }
11901            }
11902
11903            mTrackAllocationApp = processName;
11904        }
11905    }
11906
11907    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11908        synchronized (this) {
11909            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11910            if (!isDebuggable) {
11911                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11912                    throw new SecurityException("Process not debuggable: " + app.packageName);
11913                }
11914            }
11915            mProfileApp = processName;
11916            mProfileFile = profilerInfo.profileFile;
11917            if (mProfileFd != null) {
11918                try {
11919                    mProfileFd.close();
11920                } catch (IOException e) {
11921                }
11922                mProfileFd = null;
11923            }
11924            mProfileFd = profilerInfo.profileFd;
11925            mSamplingInterval = profilerInfo.samplingInterval;
11926            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11927            mProfileType = 0;
11928        }
11929    }
11930
11931    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11932        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11933        if (!isDebuggable) {
11934            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11935                throw new SecurityException("Process not debuggable: " + app.packageName);
11936            }
11937        }
11938        mNativeDebuggingApp = processName;
11939    }
11940
11941    @Override
11942    public void setAlwaysFinish(boolean enabled) {
11943        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11944                "setAlwaysFinish()");
11945
11946        long ident = Binder.clearCallingIdentity();
11947        try {
11948            Settings.Global.putInt(
11949                    mContext.getContentResolver(),
11950                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11951
11952            synchronized (this) {
11953                mAlwaysFinishActivities = enabled;
11954            }
11955        } finally {
11956            Binder.restoreCallingIdentity(ident);
11957        }
11958    }
11959
11960    @Override
11961    public void setLenientBackgroundCheck(boolean enabled) {
11962        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11963                "setLenientBackgroundCheck()");
11964
11965        long ident = Binder.clearCallingIdentity();
11966        try {
11967            Settings.Global.putInt(
11968                    mContext.getContentResolver(),
11969                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11970
11971            synchronized (this) {
11972                mLenientBackgroundCheck = enabled;
11973            }
11974        } finally {
11975            Binder.restoreCallingIdentity(ident);
11976        }
11977    }
11978
11979    @Override
11980    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11981        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11982                "setActivityController()");
11983        synchronized (this) {
11984            mController = controller;
11985            mControllerIsAMonkey = imAMonkey;
11986            Watchdog.getInstance().setActivityController(controller);
11987        }
11988    }
11989
11990    @Override
11991    public void setUserIsMonkey(boolean userIsMonkey) {
11992        synchronized (this) {
11993            synchronized (mPidsSelfLocked) {
11994                final int callingPid = Binder.getCallingPid();
11995                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11996                if (precessRecord == null) {
11997                    throw new SecurityException("Unknown process: " + callingPid);
11998                }
11999                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12000                    throw new SecurityException("Only an instrumentation process "
12001                            + "with a UiAutomation can call setUserIsMonkey");
12002                }
12003            }
12004            mUserIsMonkey = userIsMonkey;
12005        }
12006    }
12007
12008    @Override
12009    public boolean isUserAMonkey() {
12010        synchronized (this) {
12011            // If there is a controller also implies the user is a monkey.
12012            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12013        }
12014    }
12015
12016    public void requestBugReport(int bugreportType) {
12017        String service = null;
12018        switch (bugreportType) {
12019            case ActivityManager.BUGREPORT_OPTION_FULL:
12020                service = "bugreport";
12021                break;
12022            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12023                service = "bugreportplus";
12024                break;
12025            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12026                service = "bugreportremote";
12027                break;
12028        }
12029        if (service == null) {
12030            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12031                    + bugreportType);
12032        }
12033        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12034        SystemProperties.set("ctl.start", service);
12035    }
12036
12037    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12038        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12039    }
12040
12041    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12042        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12043            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12044        }
12045        return KEY_DISPATCHING_TIMEOUT;
12046    }
12047
12048    @Override
12049    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12050        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12051                != PackageManager.PERMISSION_GRANTED) {
12052            throw new SecurityException("Requires permission "
12053                    + android.Manifest.permission.FILTER_EVENTS);
12054        }
12055        ProcessRecord proc;
12056        long timeout;
12057        synchronized (this) {
12058            synchronized (mPidsSelfLocked) {
12059                proc = mPidsSelfLocked.get(pid);
12060            }
12061            timeout = getInputDispatchingTimeoutLocked(proc);
12062        }
12063
12064        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12065            return -1;
12066        }
12067
12068        return timeout;
12069    }
12070
12071    /**
12072     * Handle input dispatching timeouts.
12073     * Returns whether input dispatching should be aborted or not.
12074     */
12075    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12076            final ActivityRecord activity, final ActivityRecord parent,
12077            final boolean aboveSystem, String reason) {
12078        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12079                != PackageManager.PERMISSION_GRANTED) {
12080            throw new SecurityException("Requires permission "
12081                    + android.Manifest.permission.FILTER_EVENTS);
12082        }
12083
12084        final String annotation;
12085        if (reason == null) {
12086            annotation = "Input dispatching timed out";
12087        } else {
12088            annotation = "Input dispatching timed out (" + reason + ")";
12089        }
12090
12091        if (proc != null) {
12092            synchronized (this) {
12093                if (proc.debugging) {
12094                    return false;
12095                }
12096
12097                if (mDidDexOpt) {
12098                    // Give more time since we were dexopting.
12099                    mDidDexOpt = false;
12100                    return false;
12101                }
12102
12103                if (proc.instrumentationClass != null) {
12104                    Bundle info = new Bundle();
12105                    info.putString("shortMsg", "keyDispatchingTimedOut");
12106                    info.putString("longMsg", annotation);
12107                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12108                    return true;
12109                }
12110            }
12111            mHandler.post(new Runnable() {
12112                @Override
12113                public void run() {
12114                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12115                }
12116            });
12117        }
12118
12119        return true;
12120    }
12121
12122    @Override
12123    public Bundle getAssistContextExtras(int requestType) {
12124        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12125                null, null, true /* focused */, true /* newSessionId */,
12126                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12127        if (pae == null) {
12128            return null;
12129        }
12130        synchronized (pae) {
12131            while (!pae.haveResult) {
12132                try {
12133                    pae.wait();
12134                } catch (InterruptedException e) {
12135                }
12136            }
12137        }
12138        synchronized (this) {
12139            buildAssistBundleLocked(pae, pae.result);
12140            mPendingAssistExtras.remove(pae);
12141            mUiHandler.removeCallbacks(pae);
12142        }
12143        return pae.extras;
12144    }
12145
12146    @Override
12147    public boolean isAssistDataAllowedOnCurrentActivity() {
12148        int userId;
12149        synchronized (this) {
12150            userId = mUserController.getCurrentUserIdLocked();
12151            ActivityRecord activity = getFocusedStack().topActivity();
12152            if (activity == null) {
12153                return false;
12154            }
12155            userId = activity.userId;
12156        }
12157        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12158                Context.DEVICE_POLICY_SERVICE);
12159        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12160    }
12161
12162    @Override
12163    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12164        long ident = Binder.clearCallingIdentity();
12165        try {
12166            synchronized (this) {
12167                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12168                ActivityRecord top = getFocusedStack().topActivity();
12169                if (top != caller) {
12170                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12171                            + " is not current top " + top);
12172                    return false;
12173                }
12174                if (!top.nowVisible) {
12175                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12176                            + " is not visible");
12177                    return false;
12178                }
12179            }
12180            AssistUtils utils = new AssistUtils(mContext);
12181            return utils.showSessionForActiveService(args,
12182                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12183        } finally {
12184            Binder.restoreCallingIdentity(ident);
12185        }
12186    }
12187
12188    @Override
12189    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12190            Bundle receiverExtras,
12191            IBinder activityToken, boolean focused, boolean newSessionId) {
12192        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12193                activityToken, focused, newSessionId,
12194                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12195                != null;
12196    }
12197
12198    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12199            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12200            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12201        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12202                "enqueueAssistContext()");
12203        synchronized (this) {
12204            ActivityRecord activity = getFocusedStack().topActivity();
12205            if (activity == null) {
12206                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12207                return null;
12208            }
12209            if (activity.app == null || activity.app.thread == null) {
12210                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12211                return null;
12212            }
12213            if (focused) {
12214                if (activityToken != null) {
12215                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12216                    if (activity != caller) {
12217                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12218                                + " is not current top " + activity);
12219                        return null;
12220                    }
12221                }
12222            } else {
12223                activity = ActivityRecord.forTokenLocked(activityToken);
12224                if (activity == null) {
12225                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12226                            + " couldn't be found");
12227                    return null;
12228                }
12229            }
12230
12231            PendingAssistExtras pae;
12232            Bundle extras = new Bundle();
12233            if (args != null) {
12234                extras.putAll(args);
12235            }
12236            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12237            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12238            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12239                    userHandle);
12240            // Increment the sessionId if necessary
12241            if (newSessionId) {
12242                mViSessionId++;
12243            }
12244            try {
12245                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12246                        requestType, mViSessionId);
12247                mPendingAssistExtras.add(pae);
12248                mUiHandler.postDelayed(pae, timeout);
12249            } catch (RemoteException e) {
12250                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12251                return null;
12252            }
12253            return pae;
12254        }
12255    }
12256
12257    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12258        IResultReceiver receiver;
12259        synchronized (this) {
12260            mPendingAssistExtras.remove(pae);
12261            receiver = pae.receiver;
12262        }
12263        if (receiver != null) {
12264            // Caller wants result sent back to them.
12265            Bundle sendBundle = new Bundle();
12266            // At least return the receiver extras
12267            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12268                    pae.receiverExtras);
12269            try {
12270                pae.receiver.send(0, sendBundle);
12271            } catch (RemoteException e) {
12272            }
12273        }
12274    }
12275
12276    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12277        if (result != null) {
12278            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12279        }
12280        if (pae.hint != null) {
12281            pae.extras.putBoolean(pae.hint, true);
12282        }
12283    }
12284
12285    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12286            AssistContent content, Uri referrer) {
12287        PendingAssistExtras pae = (PendingAssistExtras)token;
12288        synchronized (pae) {
12289            pae.result = extras;
12290            pae.structure = structure;
12291            pae.content = content;
12292            if (referrer != null) {
12293                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12294            }
12295            pae.haveResult = true;
12296            pae.notifyAll();
12297            if (pae.intent == null && pae.receiver == null) {
12298                // Caller is just waiting for the result.
12299                return;
12300            }
12301        }
12302
12303        // We are now ready to launch the assist activity.
12304        IResultReceiver sendReceiver = null;
12305        Bundle sendBundle = null;
12306        synchronized (this) {
12307            buildAssistBundleLocked(pae, extras);
12308            boolean exists = mPendingAssistExtras.remove(pae);
12309            mUiHandler.removeCallbacks(pae);
12310            if (!exists) {
12311                // Timed out.
12312                return;
12313            }
12314            if ((sendReceiver=pae.receiver) != null) {
12315                // Caller wants result sent back to them.
12316                sendBundle = new Bundle();
12317                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12318                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12319                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12320                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12321                        pae.receiverExtras);
12322            }
12323        }
12324        if (sendReceiver != null) {
12325            try {
12326                sendReceiver.send(0, sendBundle);
12327            } catch (RemoteException e) {
12328            }
12329            return;
12330        }
12331
12332        long ident = Binder.clearCallingIdentity();
12333        try {
12334            pae.intent.replaceExtras(pae.extras);
12335            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12336                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12337                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12338            closeSystemDialogs("assist");
12339            try {
12340                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12341            } catch (ActivityNotFoundException e) {
12342                Slog.w(TAG, "No activity to handle assist action.", e);
12343            }
12344        } finally {
12345            Binder.restoreCallingIdentity(ident);
12346        }
12347    }
12348
12349    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12350            Bundle args) {
12351        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12352                true /* focused */, true /* newSessionId */,
12353                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12354    }
12355
12356    public void registerProcessObserver(IProcessObserver observer) {
12357        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12358                "registerProcessObserver()");
12359        synchronized (this) {
12360            mProcessObservers.register(observer);
12361        }
12362    }
12363
12364    @Override
12365    public void unregisterProcessObserver(IProcessObserver observer) {
12366        synchronized (this) {
12367            mProcessObservers.unregister(observer);
12368        }
12369    }
12370
12371    @Override
12372    public void registerUidObserver(IUidObserver observer, int which) {
12373        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12374                "registerUidObserver()");
12375        synchronized (this) {
12376            mUidObservers.register(observer, which);
12377        }
12378    }
12379
12380    @Override
12381    public void unregisterUidObserver(IUidObserver observer) {
12382        synchronized (this) {
12383            mUidObservers.unregister(observer);
12384        }
12385    }
12386
12387    @Override
12388    public boolean convertFromTranslucent(IBinder token) {
12389        final long origId = Binder.clearCallingIdentity();
12390        try {
12391            synchronized (this) {
12392                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12393                if (r == null) {
12394                    return false;
12395                }
12396                final boolean translucentChanged = r.changeWindowTranslucency(true);
12397                if (translucentChanged) {
12398                    r.task.stack.releaseBackgroundResources(r);
12399                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12400                }
12401                mWindowManager.setAppFullscreen(token, true);
12402                return translucentChanged;
12403            }
12404        } finally {
12405            Binder.restoreCallingIdentity(origId);
12406        }
12407    }
12408
12409    @Override
12410    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12411        final long origId = Binder.clearCallingIdentity();
12412        try {
12413            synchronized (this) {
12414                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12415                if (r == null) {
12416                    return false;
12417                }
12418                int index = r.task.mActivities.lastIndexOf(r);
12419                if (index > 0) {
12420                    ActivityRecord under = r.task.mActivities.get(index - 1);
12421                    under.returningOptions = options;
12422                }
12423                final boolean translucentChanged = r.changeWindowTranslucency(false);
12424                if (translucentChanged) {
12425                    r.task.stack.convertActivityToTranslucent(r);
12426                }
12427                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12428                mWindowManager.setAppFullscreen(token, false);
12429                return translucentChanged;
12430            }
12431        } finally {
12432            Binder.restoreCallingIdentity(origId);
12433        }
12434    }
12435
12436    @Override
12437    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12438        final long origId = Binder.clearCallingIdentity();
12439        try {
12440            synchronized (this) {
12441                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12442                if (r != null) {
12443                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12444                }
12445            }
12446            return false;
12447        } finally {
12448            Binder.restoreCallingIdentity(origId);
12449        }
12450    }
12451
12452    @Override
12453    public boolean isBackgroundVisibleBehind(IBinder token) {
12454        final long origId = Binder.clearCallingIdentity();
12455        try {
12456            synchronized (this) {
12457                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12458                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12459                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12460                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12461                return visible;
12462            }
12463        } finally {
12464            Binder.restoreCallingIdentity(origId);
12465        }
12466    }
12467
12468    @Override
12469    public ActivityOptions getActivityOptions(IBinder token) {
12470        final long origId = Binder.clearCallingIdentity();
12471        try {
12472            synchronized (this) {
12473                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12474                if (r != null) {
12475                    final ActivityOptions activityOptions = r.pendingOptions;
12476                    r.pendingOptions = null;
12477                    return activityOptions;
12478                }
12479                return null;
12480            }
12481        } finally {
12482            Binder.restoreCallingIdentity(origId);
12483        }
12484    }
12485
12486    @Override
12487    public void setImmersive(IBinder token, boolean immersive) {
12488        synchronized(this) {
12489            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12490            if (r == null) {
12491                throw new IllegalArgumentException();
12492            }
12493            r.immersive = immersive;
12494
12495            // update associated state if we're frontmost
12496            if (r == mFocusedActivity) {
12497                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12498                applyUpdateLockStateLocked(r);
12499            }
12500        }
12501    }
12502
12503    @Override
12504    public boolean isImmersive(IBinder token) {
12505        synchronized (this) {
12506            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12507            if (r == null) {
12508                throw new IllegalArgumentException();
12509            }
12510            return r.immersive;
12511        }
12512    }
12513
12514    @Override
12515    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12516        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12517            throw new UnsupportedOperationException("VR mode not supported on this device!");
12518        }
12519
12520        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12521
12522        ActivityRecord r;
12523        synchronized (this) {
12524            r = ActivityRecord.isInStackLocked(token);
12525        }
12526
12527        if (r == null) {
12528            throw new IllegalArgumentException();
12529        }
12530
12531        int err;
12532        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12533                VrManagerInternal.NO_ERROR) {
12534            return err;
12535        }
12536
12537        synchronized(this) {
12538            r.requestedVrComponent = (enabled) ? packageName : null;
12539
12540            // Update associated state if this activity is currently focused
12541            if (r == mFocusedActivity) {
12542                applyUpdateVrModeLocked(r);
12543            }
12544            return 0;
12545        }
12546    }
12547
12548    @Override
12549    public boolean isVrModePackageEnabled(ComponentName packageName) {
12550        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12551            throw new UnsupportedOperationException("VR mode not supported on this device!");
12552        }
12553
12554        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12555
12556        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12557                VrManagerInternal.NO_ERROR;
12558    }
12559
12560    public boolean isTopActivityImmersive() {
12561        enforceNotIsolatedCaller("startActivity");
12562        synchronized (this) {
12563            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12564            return (r != null) ? r.immersive : false;
12565        }
12566    }
12567
12568    @Override
12569    public boolean isTopOfTask(IBinder token) {
12570        synchronized (this) {
12571            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12572            if (r == null) {
12573                throw new IllegalArgumentException();
12574            }
12575            return r.task.getTopActivity() == r;
12576        }
12577    }
12578
12579    public final void enterSafeMode() {
12580        synchronized(this) {
12581            // It only makes sense to do this before the system is ready
12582            // and started launching other packages.
12583            if (!mSystemReady) {
12584                try {
12585                    AppGlobals.getPackageManager().enterSafeMode();
12586                } catch (RemoteException e) {
12587                }
12588            }
12589
12590            mSafeMode = true;
12591        }
12592    }
12593
12594    public final void showSafeModeOverlay() {
12595        View v = LayoutInflater.from(mContext).inflate(
12596                com.android.internal.R.layout.safe_mode, null);
12597        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12598        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12599        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12600        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12601        lp.gravity = Gravity.BOTTOM | Gravity.START;
12602        lp.format = v.getBackground().getOpacity();
12603        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12604                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12605        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12606        ((WindowManager)mContext.getSystemService(
12607                Context.WINDOW_SERVICE)).addView(v, lp);
12608    }
12609
12610    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12611        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12612            return;
12613        }
12614        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12615        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12616        synchronized (stats) {
12617            if (mBatteryStatsService.isOnBattery()) {
12618                mBatteryStatsService.enforceCallingPermission();
12619                int MY_UID = Binder.getCallingUid();
12620                final int uid;
12621                if (sender == null) {
12622                    uid = sourceUid;
12623                } else {
12624                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12625                }
12626                BatteryStatsImpl.Uid.Pkg pkg =
12627                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12628                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12629                pkg.noteWakeupAlarmLocked(tag);
12630            }
12631        }
12632    }
12633
12634    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12635        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12636            return;
12637        }
12638        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12639        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12640        synchronized (stats) {
12641            mBatteryStatsService.enforceCallingPermission();
12642            int MY_UID = Binder.getCallingUid();
12643            final int uid;
12644            if (sender == null) {
12645                uid = sourceUid;
12646            } else {
12647                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12648            }
12649            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12650        }
12651    }
12652
12653    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12654        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12655            return;
12656        }
12657        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12658        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12659        synchronized (stats) {
12660            mBatteryStatsService.enforceCallingPermission();
12661            int MY_UID = Binder.getCallingUid();
12662            final int uid;
12663            if (sender == null) {
12664                uid = sourceUid;
12665            } else {
12666                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12667            }
12668            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12669        }
12670    }
12671
12672    public boolean killPids(int[] pids, String pReason, boolean secure) {
12673        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12674            throw new SecurityException("killPids only available to the system");
12675        }
12676        String reason = (pReason == null) ? "Unknown" : pReason;
12677        // XXX Note: don't acquire main activity lock here, because the window
12678        // manager calls in with its locks held.
12679
12680        boolean killed = false;
12681        synchronized (mPidsSelfLocked) {
12682            int worstType = 0;
12683            for (int i=0; i<pids.length; i++) {
12684                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12685                if (proc != null) {
12686                    int type = proc.setAdj;
12687                    if (type > worstType) {
12688                        worstType = type;
12689                    }
12690                }
12691            }
12692
12693            // If the worst oom_adj is somewhere in the cached proc LRU range,
12694            // then constrain it so we will kill all cached procs.
12695            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12696                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12697                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12698            }
12699
12700            // If this is not a secure call, don't let it kill processes that
12701            // are important.
12702            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12703                worstType = ProcessList.SERVICE_ADJ;
12704            }
12705
12706            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12707            for (int i=0; i<pids.length; i++) {
12708                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12709                if (proc == null) {
12710                    continue;
12711                }
12712                int adj = proc.setAdj;
12713                if (adj >= worstType && !proc.killedByAm) {
12714                    proc.kill(reason, true);
12715                    killed = true;
12716                }
12717            }
12718        }
12719        return killed;
12720    }
12721
12722    @Override
12723    public void killUid(int appId, int userId, String reason) {
12724        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12725        synchronized (this) {
12726            final long identity = Binder.clearCallingIdentity();
12727            try {
12728                killPackageProcessesLocked(null, appId, userId,
12729                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12730                        reason != null ? reason : "kill uid");
12731            } finally {
12732                Binder.restoreCallingIdentity(identity);
12733            }
12734        }
12735    }
12736
12737    @Override
12738    public boolean killProcessesBelowForeground(String reason) {
12739        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12740            throw new SecurityException("killProcessesBelowForeground() only available to system");
12741        }
12742
12743        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12744    }
12745
12746    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12747        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12748            throw new SecurityException("killProcessesBelowAdj() only available to system");
12749        }
12750
12751        boolean killed = false;
12752        synchronized (mPidsSelfLocked) {
12753            final int size = mPidsSelfLocked.size();
12754            for (int i = 0; i < size; i++) {
12755                final int pid = mPidsSelfLocked.keyAt(i);
12756                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12757                if (proc == null) continue;
12758
12759                final int adj = proc.setAdj;
12760                if (adj > belowAdj && !proc.killedByAm) {
12761                    proc.kill(reason, true);
12762                    killed = true;
12763                }
12764            }
12765        }
12766        return killed;
12767    }
12768
12769    @Override
12770    public void hang(final IBinder who, boolean allowRestart) {
12771        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12772                != PackageManager.PERMISSION_GRANTED) {
12773            throw new SecurityException("Requires permission "
12774                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12775        }
12776
12777        final IBinder.DeathRecipient death = new DeathRecipient() {
12778            @Override
12779            public void binderDied() {
12780                synchronized (this) {
12781                    notifyAll();
12782                }
12783            }
12784        };
12785
12786        try {
12787            who.linkToDeath(death, 0);
12788        } catch (RemoteException e) {
12789            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12790            return;
12791        }
12792
12793        synchronized (this) {
12794            Watchdog.getInstance().setAllowRestart(allowRestart);
12795            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12796            synchronized (death) {
12797                while (who.isBinderAlive()) {
12798                    try {
12799                        death.wait();
12800                    } catch (InterruptedException e) {
12801                    }
12802                }
12803            }
12804            Watchdog.getInstance().setAllowRestart(true);
12805        }
12806    }
12807
12808    @Override
12809    public void restart() {
12810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12811                != PackageManager.PERMISSION_GRANTED) {
12812            throw new SecurityException("Requires permission "
12813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12814        }
12815
12816        Log.i(TAG, "Sending shutdown broadcast...");
12817
12818        BroadcastReceiver br = new BroadcastReceiver() {
12819            @Override public void onReceive(Context context, Intent intent) {
12820                // Now the broadcast is done, finish up the low-level shutdown.
12821                Log.i(TAG, "Shutting down activity manager...");
12822                shutdown(10000);
12823                Log.i(TAG, "Shutdown complete, restarting!");
12824                Process.killProcess(Process.myPid());
12825                System.exit(10);
12826            }
12827        };
12828
12829        // First send the high-level shut down broadcast.
12830        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12831        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12832        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12833        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12834        mContext.sendOrderedBroadcastAsUser(intent,
12835                UserHandle.ALL, null, br, mHandler, 0, null, null);
12836        */
12837        br.onReceive(mContext, intent);
12838    }
12839
12840    private long getLowRamTimeSinceIdle(long now) {
12841        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12842    }
12843
12844    @Override
12845    public void performIdleMaintenance() {
12846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12847                != PackageManager.PERMISSION_GRANTED) {
12848            throw new SecurityException("Requires permission "
12849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12850        }
12851
12852        synchronized (this) {
12853            final long now = SystemClock.uptimeMillis();
12854            final long timeSinceLastIdle = now - mLastIdleTime;
12855            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12856            mLastIdleTime = now;
12857            mLowRamTimeSinceLastIdle = 0;
12858            if (mLowRamStartTime != 0) {
12859                mLowRamStartTime = now;
12860            }
12861
12862            StringBuilder sb = new StringBuilder(128);
12863            sb.append("Idle maintenance over ");
12864            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12865            sb.append(" low RAM for ");
12866            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12867            Slog.i(TAG, sb.toString());
12868
12869            // If at least 1/3 of our time since the last idle period has been spent
12870            // with RAM low, then we want to kill processes.
12871            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12872
12873            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12874                ProcessRecord proc = mLruProcesses.get(i);
12875                if (proc.notCachedSinceIdle) {
12876                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12877                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12878                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12879                        if (doKilling && proc.initialIdlePss != 0
12880                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12881                            sb = new StringBuilder(128);
12882                            sb.append("Kill");
12883                            sb.append(proc.processName);
12884                            sb.append(" in idle maint: pss=");
12885                            sb.append(proc.lastPss);
12886                            sb.append(", swapPss=");
12887                            sb.append(proc.lastSwapPss);
12888                            sb.append(", initialPss=");
12889                            sb.append(proc.initialIdlePss);
12890                            sb.append(", period=");
12891                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12892                            sb.append(", lowRamPeriod=");
12893                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12894                            Slog.wtfQuiet(TAG, sb.toString());
12895                            proc.kill("idle maint (pss " + proc.lastPss
12896                                    + " from " + proc.initialIdlePss + ")", true);
12897                        }
12898                    }
12899                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12900                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12901                    proc.notCachedSinceIdle = true;
12902                    proc.initialIdlePss = 0;
12903                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12904                            mTestPssMode, isSleepingLocked(), now);
12905                }
12906            }
12907
12908            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12909            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12910        }
12911    }
12912
12913    @Override
12914    public void sendIdleJobTrigger() {
12915        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12916                != PackageManager.PERMISSION_GRANTED) {
12917            throw new SecurityException("Requires permission "
12918                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12919        }
12920
12921        final long ident = Binder.clearCallingIdentity();
12922        try {
12923            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12924                    .setPackage("android")
12925                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12926            broadcastIntent(null, intent, null, null, 0, null, null, null,
12927                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12928        } finally {
12929            Binder.restoreCallingIdentity(ident);
12930        }
12931    }
12932
12933    private void retrieveSettings() {
12934        final ContentResolver resolver = mContext.getContentResolver();
12935        final boolean freeformWindowManagement =
12936                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12937                        || Settings.Global.getInt(
12938                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12939        final boolean supportsPictureInPicture =
12940                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12941
12942        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12943        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12944        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12945        final boolean alwaysFinishActivities =
12946                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12947        final boolean lenientBackgroundCheck =
12948                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12949        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12950        final boolean forceResizable = Settings.Global.getInt(
12951                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12952        final boolean supportsLeanbackOnly =
12953                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12954
12955        // Transfer any global setting for forcing RTL layout, into a System Property
12956        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12957
12958        final Configuration configuration = new Configuration();
12959        Settings.System.getConfiguration(resolver, configuration);
12960        if (forceRtl) {
12961            // This will take care of setting the correct layout direction flags
12962            configuration.setLayoutDirection(configuration.locale);
12963        }
12964
12965        synchronized (this) {
12966            mDebugApp = mOrigDebugApp = debugApp;
12967            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12968            mAlwaysFinishActivities = alwaysFinishActivities;
12969            mLenientBackgroundCheck = lenientBackgroundCheck;
12970            mSupportsLeanbackOnly = supportsLeanbackOnly;
12971            mForceResizableActivities = forceResizable;
12972            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12973            if (supportsMultiWindow || forceResizable) {
12974                mSupportsMultiWindow = true;
12975                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12976                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12977            } else {
12978                mSupportsMultiWindow = false;
12979                mSupportsFreeformWindowManagement = false;
12980                mSupportsPictureInPicture = false;
12981            }
12982            // This happens before any activities are started, so we can
12983            // change mConfiguration in-place.
12984            updateConfigurationLocked(configuration, null, true);
12985            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12986                    "Initial config: " + mConfiguration);
12987
12988            // Load resources only after the current configuration has been set.
12989            final Resources res = mContext.getResources();
12990            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12991            mThumbnailWidth = res.getDimensionPixelSize(
12992                    com.android.internal.R.dimen.thumbnail_width);
12993            mThumbnailHeight = res.getDimensionPixelSize(
12994                    com.android.internal.R.dimen.thumbnail_height);
12995            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12996                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12997            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12998                    com.android.internal.R.string.config_appsNotReportingCrashes));
12999            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13000                mFullscreenThumbnailScale = (float) res
13001                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13002                    (float) mConfiguration.screenWidthDp;
13003            } else {
13004                mFullscreenThumbnailScale = res.getFraction(
13005                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13006            }
13007        }
13008    }
13009
13010    public boolean testIsSystemReady() {
13011        // no need to synchronize(this) just to read & return the value
13012        return mSystemReady;
13013    }
13014
13015    public void systemReady(final Runnable goingCallback) {
13016        synchronized(this) {
13017            if (mSystemReady) {
13018                // If we're done calling all the receivers, run the next "boot phase" passed in
13019                // by the SystemServer
13020                if (goingCallback != null) {
13021                    goingCallback.run();
13022                }
13023                return;
13024            }
13025
13026            mLocalDeviceIdleController
13027                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13028
13029            // Make sure we have the current profile info, since it is needed for security checks.
13030            mUserController.onSystemReady();
13031            mRecentTasks.onSystemReadyLocked();
13032            mAppOpsService.systemReady();
13033            mSystemReady = true;
13034        }
13035
13036        ArrayList<ProcessRecord> procsToKill = null;
13037        synchronized(mPidsSelfLocked) {
13038            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13039                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13040                if (!isAllowedWhileBooting(proc.info)){
13041                    if (procsToKill == null) {
13042                        procsToKill = new ArrayList<ProcessRecord>();
13043                    }
13044                    procsToKill.add(proc);
13045                }
13046            }
13047        }
13048
13049        synchronized(this) {
13050            if (procsToKill != null) {
13051                for (int i=procsToKill.size()-1; i>=0; i--) {
13052                    ProcessRecord proc = procsToKill.get(i);
13053                    Slog.i(TAG, "Removing system update proc: " + proc);
13054                    removeProcessLocked(proc, true, false, "system update done");
13055                }
13056            }
13057
13058            // Now that we have cleaned up any update processes, we
13059            // are ready to start launching real processes and know that
13060            // we won't trample on them any more.
13061            mProcessesReady = true;
13062        }
13063
13064        Slog.i(TAG, "System now ready");
13065        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13066            SystemClock.uptimeMillis());
13067
13068        synchronized(this) {
13069            // Make sure we have no pre-ready processes sitting around.
13070
13071            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13072                ResolveInfo ri = mContext.getPackageManager()
13073                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13074                                STOCK_PM_FLAGS);
13075                CharSequence errorMsg = null;
13076                if (ri != null) {
13077                    ActivityInfo ai = ri.activityInfo;
13078                    ApplicationInfo app = ai.applicationInfo;
13079                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13080                        mTopAction = Intent.ACTION_FACTORY_TEST;
13081                        mTopData = null;
13082                        mTopComponent = new ComponentName(app.packageName,
13083                                ai.name);
13084                    } else {
13085                        errorMsg = mContext.getResources().getText(
13086                                com.android.internal.R.string.factorytest_not_system);
13087                    }
13088                } else {
13089                    errorMsg = mContext.getResources().getText(
13090                            com.android.internal.R.string.factorytest_no_action);
13091                }
13092                if (errorMsg != null) {
13093                    mTopAction = null;
13094                    mTopData = null;
13095                    mTopComponent = null;
13096                    Message msg = Message.obtain();
13097                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13098                    msg.getData().putCharSequence("msg", errorMsg);
13099                    mUiHandler.sendMessage(msg);
13100                }
13101            }
13102        }
13103
13104        retrieveSettings();
13105        final int currentUserId;
13106        synchronized (this) {
13107            currentUserId = mUserController.getCurrentUserIdLocked();
13108            readGrantedUriPermissionsLocked();
13109        }
13110
13111        if (goingCallback != null) goingCallback.run();
13112
13113        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13114                Integer.toString(currentUserId), currentUserId);
13115        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13116                Integer.toString(currentUserId), currentUserId);
13117        mSystemServiceManager.startUser(currentUserId);
13118
13119        synchronized (this) {
13120            // Only start up encryption-aware persistent apps; once user is
13121            // unlocked we'll come back around and start unaware apps
13122            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13123
13124            // Start up initial activity.
13125            mBooting = true;
13126            // Enable home activity for system user, so that the system can always boot
13127            if (UserManager.isSplitSystemUser()) {
13128                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13129                try {
13130                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13131                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13132                            UserHandle.USER_SYSTEM);
13133                } catch (RemoteException e) {
13134                    throw e.rethrowAsRuntimeException();
13135                }
13136            }
13137            startHomeActivityLocked(currentUserId, "systemReady");
13138
13139            try {
13140                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13141                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13142                            + " data partition or your device will be unstable.");
13143                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13144                }
13145            } catch (RemoteException e) {
13146            }
13147
13148            if (!Build.isBuildConsistent()) {
13149                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13150                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13151            }
13152
13153            long ident = Binder.clearCallingIdentity();
13154            try {
13155                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13156                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13157                        | Intent.FLAG_RECEIVER_FOREGROUND);
13158                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13159                broadcastIntentLocked(null, null, intent,
13160                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13161                        null, false, false, MY_PID, Process.SYSTEM_UID,
13162                        currentUserId);
13163                intent = new Intent(Intent.ACTION_USER_STARTING);
13164                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13165                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13166                broadcastIntentLocked(null, null, intent,
13167                        null, new IIntentReceiver.Stub() {
13168                            @Override
13169                            public void performReceive(Intent intent, int resultCode, String data,
13170                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13171                                    throws RemoteException {
13172                            }
13173                        }, 0, null, null,
13174                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13175                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13176            } catch (Throwable t) {
13177                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13178            } finally {
13179                Binder.restoreCallingIdentity(ident);
13180            }
13181            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13182            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13183        }
13184    }
13185
13186    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13187        synchronized (this) {
13188            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13189        }
13190    }
13191
13192    void skipCurrentReceiverLocked(ProcessRecord app) {
13193        for (BroadcastQueue queue : mBroadcastQueues) {
13194            queue.skipCurrentReceiverLocked(app);
13195        }
13196    }
13197
13198    /**
13199     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13200     * The application process will exit immediately after this call returns.
13201     * @param app object of the crashing app, null for the system server
13202     * @param crashInfo describing the exception
13203     */
13204    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13205        ProcessRecord r = findAppProcess(app, "Crash");
13206        final String processName = app == null ? "system_server"
13207                : (r == null ? "unknown" : r.processName);
13208
13209        handleApplicationCrashInner("crash", r, processName, crashInfo);
13210    }
13211
13212    /* Native crash reporting uses this inner version because it needs to be somewhat
13213     * decoupled from the AM-managed cleanup lifecycle
13214     */
13215    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13216            ApplicationErrorReport.CrashInfo crashInfo) {
13217        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13218                UserHandle.getUserId(Binder.getCallingUid()), processName,
13219                r == null ? -1 : r.info.flags,
13220                crashInfo.exceptionClassName,
13221                crashInfo.exceptionMessage,
13222                crashInfo.throwFileName,
13223                crashInfo.throwLineNumber);
13224
13225        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13226
13227        mAppErrors.crashApplication(r, crashInfo);
13228    }
13229
13230    public void handleApplicationStrictModeViolation(
13231            IBinder app,
13232            int violationMask,
13233            StrictMode.ViolationInfo info) {
13234        ProcessRecord r = findAppProcess(app, "StrictMode");
13235        if (r == null) {
13236            return;
13237        }
13238
13239        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13240            Integer stackFingerprint = info.hashCode();
13241            boolean logIt = true;
13242            synchronized (mAlreadyLoggedViolatedStacks) {
13243                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13244                    logIt = false;
13245                    // TODO: sub-sample into EventLog for these, with
13246                    // the info.durationMillis?  Then we'd get
13247                    // the relative pain numbers, without logging all
13248                    // the stack traces repeatedly.  We'd want to do
13249                    // likewise in the client code, which also does
13250                    // dup suppression, before the Binder call.
13251                } else {
13252                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13253                        mAlreadyLoggedViolatedStacks.clear();
13254                    }
13255                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13256                }
13257            }
13258            if (logIt) {
13259                logStrictModeViolationToDropBox(r, info);
13260            }
13261        }
13262
13263        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13264            AppErrorResult result = new AppErrorResult();
13265            synchronized (this) {
13266                final long origId = Binder.clearCallingIdentity();
13267
13268                Message msg = Message.obtain();
13269                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13270                HashMap<String, Object> data = new HashMap<String, Object>();
13271                data.put("result", result);
13272                data.put("app", r);
13273                data.put("violationMask", violationMask);
13274                data.put("info", info);
13275                msg.obj = data;
13276                mUiHandler.sendMessage(msg);
13277
13278                Binder.restoreCallingIdentity(origId);
13279            }
13280            int res = result.get();
13281            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13282        }
13283    }
13284
13285    // Depending on the policy in effect, there could be a bunch of
13286    // these in quick succession so we try to batch these together to
13287    // minimize disk writes, number of dropbox entries, and maximize
13288    // compression, by having more fewer, larger records.
13289    private void logStrictModeViolationToDropBox(
13290            ProcessRecord process,
13291            StrictMode.ViolationInfo info) {
13292        if (info == null) {
13293            return;
13294        }
13295        final boolean isSystemApp = process == null ||
13296                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13297                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13298        final String processName = process == null ? "unknown" : process.processName;
13299        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13300        final DropBoxManager dbox = (DropBoxManager)
13301                mContext.getSystemService(Context.DROPBOX_SERVICE);
13302
13303        // Exit early if the dropbox isn't configured to accept this report type.
13304        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13305
13306        boolean bufferWasEmpty;
13307        boolean needsFlush;
13308        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13309        synchronized (sb) {
13310            bufferWasEmpty = sb.length() == 0;
13311            appendDropBoxProcessHeaders(process, processName, sb);
13312            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13313            sb.append("System-App: ").append(isSystemApp).append("\n");
13314            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13315            if (info.violationNumThisLoop != 0) {
13316                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13317            }
13318            if (info.numAnimationsRunning != 0) {
13319                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13320            }
13321            if (info.broadcastIntentAction != null) {
13322                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13323            }
13324            if (info.durationMillis != -1) {
13325                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13326            }
13327            if (info.numInstances != -1) {
13328                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13329            }
13330            if (info.tags != null) {
13331                for (String tag : info.tags) {
13332                    sb.append("Span-Tag: ").append(tag).append("\n");
13333                }
13334            }
13335            sb.append("\n");
13336            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13337                sb.append(info.crashInfo.stackTrace);
13338                sb.append("\n");
13339            }
13340            if (info.message != null) {
13341                sb.append(info.message);
13342                sb.append("\n");
13343            }
13344
13345            // Only buffer up to ~64k.  Various logging bits truncate
13346            // things at 128k.
13347            needsFlush = (sb.length() > 64 * 1024);
13348        }
13349
13350        // Flush immediately if the buffer's grown too large, or this
13351        // is a non-system app.  Non-system apps are isolated with a
13352        // different tag & policy and not batched.
13353        //
13354        // Batching is useful during internal testing with
13355        // StrictMode settings turned up high.  Without batching,
13356        // thousands of separate files could be created on boot.
13357        if (!isSystemApp || needsFlush) {
13358            new Thread("Error dump: " + dropboxTag) {
13359                @Override
13360                public void run() {
13361                    String report;
13362                    synchronized (sb) {
13363                        report = sb.toString();
13364                        sb.delete(0, sb.length());
13365                        sb.trimToSize();
13366                    }
13367                    if (report.length() != 0) {
13368                        dbox.addText(dropboxTag, report);
13369                    }
13370                }
13371            }.start();
13372            return;
13373        }
13374
13375        // System app batching:
13376        if (!bufferWasEmpty) {
13377            // An existing dropbox-writing thread is outstanding, so
13378            // we don't need to start it up.  The existing thread will
13379            // catch the buffer appends we just did.
13380            return;
13381        }
13382
13383        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13384        // (After this point, we shouldn't access AMS internal data structures.)
13385        new Thread("Error dump: " + dropboxTag) {
13386            @Override
13387            public void run() {
13388                // 5 second sleep to let stacks arrive and be batched together
13389                try {
13390                    Thread.sleep(5000);  // 5 seconds
13391                } catch (InterruptedException e) {}
13392
13393                String errorReport;
13394                synchronized (mStrictModeBuffer) {
13395                    errorReport = mStrictModeBuffer.toString();
13396                    if (errorReport.length() == 0) {
13397                        return;
13398                    }
13399                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13400                    mStrictModeBuffer.trimToSize();
13401                }
13402                dbox.addText(dropboxTag, errorReport);
13403            }
13404        }.start();
13405    }
13406
13407    /**
13408     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13409     * @param app object of the crashing app, null for the system server
13410     * @param tag reported by the caller
13411     * @param system whether this wtf is coming from the system
13412     * @param crashInfo describing the context of the error
13413     * @return true if the process should exit immediately (WTF is fatal)
13414     */
13415    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13416            final ApplicationErrorReport.CrashInfo crashInfo) {
13417        final int callingUid = Binder.getCallingUid();
13418        final int callingPid = Binder.getCallingPid();
13419
13420        if (system) {
13421            // If this is coming from the system, we could very well have low-level
13422            // system locks held, so we want to do this all asynchronously.  And we
13423            // never want this to become fatal, so there is that too.
13424            mHandler.post(new Runnable() {
13425                @Override public void run() {
13426                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13427                }
13428            });
13429            return false;
13430        }
13431
13432        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13433                crashInfo);
13434
13435        if (r != null && r.pid != Process.myPid() &&
13436                Settings.Global.getInt(mContext.getContentResolver(),
13437                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13438            mAppErrors.crashApplication(r, crashInfo);
13439            return true;
13440        } else {
13441            return false;
13442        }
13443    }
13444
13445    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13446            final ApplicationErrorReport.CrashInfo crashInfo) {
13447        final ProcessRecord r = findAppProcess(app, "WTF");
13448        final String processName = app == null ? "system_server"
13449                : (r == null ? "unknown" : r.processName);
13450
13451        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13452                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13453
13454        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13455
13456        return r;
13457    }
13458
13459    /**
13460     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13461     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13462     */
13463    private ProcessRecord findAppProcess(IBinder app, String reason) {
13464        if (app == null) {
13465            return null;
13466        }
13467
13468        synchronized (this) {
13469            final int NP = mProcessNames.getMap().size();
13470            for (int ip=0; ip<NP; ip++) {
13471                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13472                final int NA = apps.size();
13473                for (int ia=0; ia<NA; ia++) {
13474                    ProcessRecord p = apps.valueAt(ia);
13475                    if (p.thread != null && p.thread.asBinder() == app) {
13476                        return p;
13477                    }
13478                }
13479            }
13480
13481            Slog.w(TAG, "Can't find mystery application for " + reason
13482                    + " from pid=" + Binder.getCallingPid()
13483                    + " uid=" + Binder.getCallingUid() + ": " + app);
13484            return null;
13485        }
13486    }
13487
13488    /**
13489     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13490     * to append various headers to the dropbox log text.
13491     */
13492    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13493            StringBuilder sb) {
13494        // Watchdog thread ends up invoking this function (with
13495        // a null ProcessRecord) to add the stack file to dropbox.
13496        // Do not acquire a lock on this (am) in such cases, as it
13497        // could cause a potential deadlock, if and when watchdog
13498        // is invoked due to unavailability of lock on am and it
13499        // would prevent watchdog from killing system_server.
13500        if (process == null) {
13501            sb.append("Process: ").append(processName).append("\n");
13502            return;
13503        }
13504        // Note: ProcessRecord 'process' is guarded by the service
13505        // instance.  (notably process.pkgList, which could otherwise change
13506        // concurrently during execution of this method)
13507        synchronized (this) {
13508            sb.append("Process: ").append(processName).append("\n");
13509            int flags = process.info.flags;
13510            IPackageManager pm = AppGlobals.getPackageManager();
13511            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13512            for (int ip=0; ip<process.pkgList.size(); ip++) {
13513                String pkg = process.pkgList.keyAt(ip);
13514                sb.append("Package: ").append(pkg);
13515                try {
13516                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13517                    if (pi != null) {
13518                        sb.append(" v").append(pi.versionCode);
13519                        if (pi.versionName != null) {
13520                            sb.append(" (").append(pi.versionName).append(")");
13521                        }
13522                    }
13523                } catch (RemoteException e) {
13524                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13525                }
13526                sb.append("\n");
13527            }
13528        }
13529    }
13530
13531    private static String processClass(ProcessRecord process) {
13532        if (process == null || process.pid == MY_PID) {
13533            return "system_server";
13534        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13535            return "system_app";
13536        } else {
13537            return "data_app";
13538        }
13539    }
13540
13541    private volatile long mWtfClusterStart;
13542    private volatile int mWtfClusterCount;
13543
13544    /**
13545     * Write a description of an error (crash, WTF, ANR) to the drop box.
13546     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13547     * @param process which caused the error, null means the system server
13548     * @param activity which triggered the error, null if unknown
13549     * @param parent activity related to the error, null if unknown
13550     * @param subject line related to the error, null if absent
13551     * @param report in long form describing the error, null if absent
13552     * @param dataFile text file to include in the report, null if none
13553     * @param crashInfo giving an application stack trace, null if absent
13554     */
13555    public void addErrorToDropBox(String eventType,
13556            ProcessRecord process, String processName, ActivityRecord activity,
13557            ActivityRecord parent, String subject,
13558            final String report, final File dataFile,
13559            final ApplicationErrorReport.CrashInfo crashInfo) {
13560        // NOTE -- this must never acquire the ActivityManagerService lock,
13561        // otherwise the watchdog may be prevented from resetting the system.
13562
13563        final String dropboxTag = processClass(process) + "_" + eventType;
13564        final DropBoxManager dbox = (DropBoxManager)
13565                mContext.getSystemService(Context.DROPBOX_SERVICE);
13566
13567        // Exit early if the dropbox isn't configured to accept this report type.
13568        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13569
13570        // Rate-limit how often we're willing to do the heavy lifting below to
13571        // collect and record logs; currently 5 logs per 10 second period.
13572        final long now = SystemClock.elapsedRealtime();
13573        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13574            mWtfClusterStart = now;
13575            mWtfClusterCount = 1;
13576        } else {
13577            if (mWtfClusterCount++ >= 5) return;
13578        }
13579
13580        final StringBuilder sb = new StringBuilder(1024);
13581        appendDropBoxProcessHeaders(process, processName, sb);
13582        if (process != null) {
13583            sb.append("Foreground: ")
13584                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13585                    .append("\n");
13586        }
13587        if (activity != null) {
13588            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13589        }
13590        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13591            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13592        }
13593        if (parent != null && parent != activity) {
13594            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13595        }
13596        if (subject != null) {
13597            sb.append("Subject: ").append(subject).append("\n");
13598        }
13599        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13600        if (Debug.isDebuggerConnected()) {
13601            sb.append("Debugger: Connected\n");
13602        }
13603        sb.append("\n");
13604
13605        // Do the rest in a worker thread to avoid blocking the caller on I/O
13606        // (After this point, we shouldn't access AMS internal data structures.)
13607        Thread worker = new Thread("Error dump: " + dropboxTag) {
13608            @Override
13609            public void run() {
13610                if (report != null) {
13611                    sb.append(report);
13612                }
13613
13614                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13615                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13616                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13617                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13618
13619                if (dataFile != null && maxDataFileSize > 0) {
13620                    try {
13621                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13622                                    "\n\n[[TRUNCATED]]"));
13623                    } catch (IOException e) {
13624                        Slog.e(TAG, "Error reading " + dataFile, e);
13625                    }
13626                }
13627                if (crashInfo != null && crashInfo.stackTrace != null) {
13628                    sb.append(crashInfo.stackTrace);
13629                }
13630
13631                if (lines > 0) {
13632                    sb.append("\n");
13633
13634                    // Merge several logcat streams, and take the last N lines
13635                    InputStreamReader input = null;
13636                    try {
13637                        java.lang.Process logcat = new ProcessBuilder(
13638                                "/system/bin/timeout", "-k", "15s", "10s",
13639                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13640                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13641                                        .redirectErrorStream(true).start();
13642
13643                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13644                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13645                        input = new InputStreamReader(logcat.getInputStream());
13646
13647                        int num;
13648                        char[] buf = new char[8192];
13649                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13650                    } catch (IOException e) {
13651                        Slog.e(TAG, "Error running logcat", e);
13652                    } finally {
13653                        if (input != null) try { input.close(); } catch (IOException e) {}
13654                    }
13655                }
13656
13657                dbox.addText(dropboxTag, sb.toString());
13658            }
13659        };
13660
13661        if (process == null) {
13662            // If process is null, we are being called from some internal code
13663            // and may be about to die -- run this synchronously.
13664            worker.run();
13665        } else {
13666            worker.start();
13667        }
13668    }
13669
13670    @Override
13671    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13672        enforceNotIsolatedCaller("getProcessesInErrorState");
13673        // assume our apps are happy - lazy create the list
13674        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13675
13676        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13677                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13678        int userId = UserHandle.getUserId(Binder.getCallingUid());
13679
13680        synchronized (this) {
13681
13682            // iterate across all processes
13683            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13684                ProcessRecord app = mLruProcesses.get(i);
13685                if (!allUsers && app.userId != userId) {
13686                    continue;
13687                }
13688                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13689                    // This one's in trouble, so we'll generate a report for it
13690                    // crashes are higher priority (in case there's a crash *and* an anr)
13691                    ActivityManager.ProcessErrorStateInfo report = null;
13692                    if (app.crashing) {
13693                        report = app.crashingReport;
13694                    } else if (app.notResponding) {
13695                        report = app.notRespondingReport;
13696                    }
13697
13698                    if (report != null) {
13699                        if (errList == null) {
13700                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13701                        }
13702                        errList.add(report);
13703                    } else {
13704                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13705                                " crashing = " + app.crashing +
13706                                " notResponding = " + app.notResponding);
13707                    }
13708                }
13709            }
13710        }
13711
13712        return errList;
13713    }
13714
13715    static int procStateToImportance(int procState, int memAdj,
13716            ActivityManager.RunningAppProcessInfo currApp) {
13717        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13718        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13719            currApp.lru = memAdj;
13720        } else {
13721            currApp.lru = 0;
13722        }
13723        return imp;
13724    }
13725
13726    private void fillInProcMemInfo(ProcessRecord app,
13727            ActivityManager.RunningAppProcessInfo outInfo) {
13728        outInfo.pid = app.pid;
13729        outInfo.uid = app.info.uid;
13730        if (mHeavyWeightProcess == app) {
13731            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13732        }
13733        if (app.persistent) {
13734            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13735        }
13736        if (app.activities.size() > 0) {
13737            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13738        }
13739        outInfo.lastTrimLevel = app.trimMemoryLevel;
13740        int adj = app.curAdj;
13741        int procState = app.curProcState;
13742        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13743        outInfo.importanceReasonCode = app.adjTypeCode;
13744        outInfo.processState = app.curProcState;
13745    }
13746
13747    @Override
13748    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13749        enforceNotIsolatedCaller("getRunningAppProcesses");
13750
13751        final int callingUid = Binder.getCallingUid();
13752
13753        // Lazy instantiation of list
13754        List<ActivityManager.RunningAppProcessInfo> runList = null;
13755        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13756                callingUid) == PackageManager.PERMISSION_GRANTED;
13757        final int userId = UserHandle.getUserId(callingUid);
13758        final boolean allUids = isGetTasksAllowed(
13759                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13760
13761        synchronized (this) {
13762            // Iterate across all processes
13763            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13764                ProcessRecord app = mLruProcesses.get(i);
13765                if ((!allUsers && app.userId != userId)
13766                        || (!allUids && app.uid != callingUid)) {
13767                    continue;
13768                }
13769                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13770                    // Generate process state info for running application
13771                    ActivityManager.RunningAppProcessInfo currApp =
13772                        new ActivityManager.RunningAppProcessInfo(app.processName,
13773                                app.pid, app.getPackageList());
13774                    fillInProcMemInfo(app, currApp);
13775                    if (app.adjSource instanceof ProcessRecord) {
13776                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13777                        currApp.importanceReasonImportance =
13778                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13779                                        app.adjSourceProcState);
13780                    } else if (app.adjSource instanceof ActivityRecord) {
13781                        ActivityRecord r = (ActivityRecord)app.adjSource;
13782                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13783                    }
13784                    if (app.adjTarget instanceof ComponentName) {
13785                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13786                    }
13787                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13788                    //        + " lru=" + currApp.lru);
13789                    if (runList == null) {
13790                        runList = new ArrayList<>();
13791                    }
13792                    runList.add(currApp);
13793                }
13794            }
13795        }
13796        return runList;
13797    }
13798
13799    @Override
13800    public List<ApplicationInfo> getRunningExternalApplications() {
13801        enforceNotIsolatedCaller("getRunningExternalApplications");
13802        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13803        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13804        if (runningApps != null && runningApps.size() > 0) {
13805            Set<String> extList = new HashSet<String>();
13806            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13807                if (app.pkgList != null) {
13808                    for (String pkg : app.pkgList) {
13809                        extList.add(pkg);
13810                    }
13811                }
13812            }
13813            IPackageManager pm = AppGlobals.getPackageManager();
13814            for (String pkg : extList) {
13815                try {
13816                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13817                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13818                        retList.add(info);
13819                    }
13820                } catch (RemoteException e) {
13821                }
13822            }
13823        }
13824        return retList;
13825    }
13826
13827    @Override
13828    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13829        enforceNotIsolatedCaller("getMyMemoryState");
13830        synchronized (this) {
13831            ProcessRecord proc;
13832            synchronized (mPidsSelfLocked) {
13833                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13834            }
13835            fillInProcMemInfo(proc, outInfo);
13836        }
13837    }
13838
13839    @Override
13840    public int getMemoryTrimLevel() {
13841        enforceNotIsolatedCaller("getMyMemoryState");
13842        synchronized (this) {
13843            return mLastMemoryLevel;
13844        }
13845    }
13846
13847    @Override
13848    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13849            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13850        (new ActivityManagerShellCommand(this, false)).exec(
13851                this, in, out, err, args, resultReceiver);
13852    }
13853
13854    @Override
13855    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13856        if (checkCallingPermission(android.Manifest.permission.DUMP)
13857                != PackageManager.PERMISSION_GRANTED) {
13858            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13859                    + Binder.getCallingPid()
13860                    + ", uid=" + Binder.getCallingUid()
13861                    + " without permission "
13862                    + android.Manifest.permission.DUMP);
13863            return;
13864        }
13865
13866        boolean dumpAll = false;
13867        boolean dumpClient = false;
13868        boolean dumpCheckin = false;
13869        boolean dumpCheckinFormat = false;
13870        String dumpPackage = null;
13871
13872        int opti = 0;
13873        while (opti < args.length) {
13874            String opt = args[opti];
13875            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13876                break;
13877            }
13878            opti++;
13879            if ("-a".equals(opt)) {
13880                dumpAll = true;
13881            } else if ("-c".equals(opt)) {
13882                dumpClient = true;
13883            } else if ("-p".equals(opt)) {
13884                if (opti < args.length) {
13885                    dumpPackage = args[opti];
13886                    opti++;
13887                } else {
13888                    pw.println("Error: -p option requires package argument");
13889                    return;
13890                }
13891                dumpClient = true;
13892            } else if ("--checkin".equals(opt)) {
13893                dumpCheckin = dumpCheckinFormat = true;
13894            } else if ("-C".equals(opt)) {
13895                dumpCheckinFormat = true;
13896            } else if ("-h".equals(opt)) {
13897                ActivityManagerShellCommand.dumpHelp(pw, true);
13898                return;
13899            } else {
13900                pw.println("Unknown argument: " + opt + "; use -h for help");
13901            }
13902        }
13903
13904        long origId = Binder.clearCallingIdentity();
13905        boolean more = false;
13906        // Is the caller requesting to dump a particular piece of data?
13907        if (opti < args.length) {
13908            String cmd = args[opti];
13909            opti++;
13910            if ("activities".equals(cmd) || "a".equals(cmd)) {
13911                synchronized (this) {
13912                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13913                }
13914            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13915                synchronized (this) {
13916                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13917                }
13918            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13919                String[] newArgs;
13920                String name;
13921                if (opti >= args.length) {
13922                    name = null;
13923                    newArgs = EMPTY_STRING_ARRAY;
13924                } else {
13925                    dumpPackage = args[opti];
13926                    opti++;
13927                    newArgs = new String[args.length - opti];
13928                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13929                            args.length - opti);
13930                }
13931                synchronized (this) {
13932                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13933                }
13934            } else if ("broadcast-stats".equals(cmd)) {
13935                String[] newArgs;
13936                String name;
13937                if (opti >= args.length) {
13938                    name = null;
13939                    newArgs = EMPTY_STRING_ARRAY;
13940                } else {
13941                    dumpPackage = args[opti];
13942                    opti++;
13943                    newArgs = new String[args.length - opti];
13944                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13945                            args.length - opti);
13946                }
13947                synchronized (this) {
13948                    if (dumpCheckinFormat) {
13949                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13950                                dumpPackage);
13951                    } else {
13952                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13953                    }
13954                }
13955            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13956                String[] newArgs;
13957                String name;
13958                if (opti >= args.length) {
13959                    name = null;
13960                    newArgs = EMPTY_STRING_ARRAY;
13961                } else {
13962                    dumpPackage = args[opti];
13963                    opti++;
13964                    newArgs = new String[args.length - opti];
13965                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13966                            args.length - opti);
13967                }
13968                synchronized (this) {
13969                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13970                }
13971            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13972                String[] newArgs;
13973                String name;
13974                if (opti >= args.length) {
13975                    name = null;
13976                    newArgs = EMPTY_STRING_ARRAY;
13977                } else {
13978                    dumpPackage = args[opti];
13979                    opti++;
13980                    newArgs = new String[args.length - opti];
13981                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13982                            args.length - opti);
13983                }
13984                synchronized (this) {
13985                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13986                }
13987            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13988                synchronized (this) {
13989                    dumpOomLocked(fd, pw, args, opti, true);
13990                }
13991            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13992                synchronized (this) {
13993                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13994                }
13995            } else if ("provider".equals(cmd)) {
13996                String[] newArgs;
13997                String name;
13998                if (opti >= args.length) {
13999                    name = null;
14000                    newArgs = EMPTY_STRING_ARRAY;
14001                } else {
14002                    name = args[opti];
14003                    opti++;
14004                    newArgs = new String[args.length - opti];
14005                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14006                }
14007                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14008                    pw.println("No providers match: " + name);
14009                    pw.println("Use -h for help.");
14010                }
14011            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14012                synchronized (this) {
14013                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14014                }
14015            } else if ("service".equals(cmd)) {
14016                String[] newArgs;
14017                String name;
14018                if (opti >= args.length) {
14019                    name = null;
14020                    newArgs = EMPTY_STRING_ARRAY;
14021                } else {
14022                    name = args[opti];
14023                    opti++;
14024                    newArgs = new String[args.length - opti];
14025                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14026                            args.length - opti);
14027                }
14028                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14029                    pw.println("No services match: " + name);
14030                    pw.println("Use -h for help.");
14031                }
14032            } else if ("package".equals(cmd)) {
14033                String[] newArgs;
14034                if (opti >= args.length) {
14035                    pw.println("package: no package name specified");
14036                    pw.println("Use -h for help.");
14037                } else {
14038                    dumpPackage = args[opti];
14039                    opti++;
14040                    newArgs = new String[args.length - opti];
14041                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14042                            args.length - opti);
14043                    args = newArgs;
14044                    opti = 0;
14045                    more = true;
14046                }
14047            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14048                synchronized (this) {
14049                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14050                }
14051            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14052                if (dumpClient) {
14053                    ActiveServices.ServiceDumper dumper;
14054                    synchronized (this) {
14055                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14056                                dumpPackage);
14057                    }
14058                    dumper.dumpWithClient();
14059                } else {
14060                    synchronized (this) {
14061                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14062                                dumpPackage).dumpLocked();
14063                    }
14064                }
14065            } else if ("locks".equals(cmd)) {
14066                LockGuard.dump(fd, pw, args);
14067            } else {
14068                // Dumping a single activity?
14069                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14070                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14071                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14072                    if (res < 0) {
14073                        pw.println("Bad activity command, or no activities match: " + cmd);
14074                        pw.println("Use -h for help.");
14075                    }
14076                }
14077            }
14078            if (!more) {
14079                Binder.restoreCallingIdentity(origId);
14080                return;
14081            }
14082        }
14083
14084        // No piece of data specified, dump everything.
14085        if (dumpCheckinFormat) {
14086            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14087        } else if (dumpClient) {
14088            ActiveServices.ServiceDumper sdumper;
14089            synchronized (this) {
14090                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14091                pw.println();
14092                if (dumpAll) {
14093                    pw.println("-------------------------------------------------------------------------------");
14094                }
14095                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14096                pw.println();
14097                if (dumpAll) {
14098                    pw.println("-------------------------------------------------------------------------------");
14099                }
14100                if (dumpAll || dumpPackage != null) {
14101                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14102                    pw.println();
14103                    if (dumpAll) {
14104                        pw.println("-------------------------------------------------------------------------------");
14105                    }
14106                }
14107                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14108                pw.println();
14109                if (dumpAll) {
14110                    pw.println("-------------------------------------------------------------------------------");
14111                }
14112                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14113                pw.println();
14114                if (dumpAll) {
14115                    pw.println("-------------------------------------------------------------------------------");
14116                }
14117                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14118                        dumpPackage);
14119            }
14120            sdumper.dumpWithClient();
14121            pw.println();
14122            synchronized (this) {
14123                if (dumpAll) {
14124                    pw.println("-------------------------------------------------------------------------------");
14125                }
14126                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14127                pw.println();
14128                if (dumpAll) {
14129                    pw.println("-------------------------------------------------------------------------------");
14130                }
14131                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14132                if (mAssociations.size() > 0) {
14133                    pw.println();
14134                    if (dumpAll) {
14135                        pw.println("-------------------------------------------------------------------------------");
14136                    }
14137                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14138                }
14139                pw.println();
14140                if (dumpAll) {
14141                    pw.println("-------------------------------------------------------------------------------");
14142                }
14143                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14144            }
14145
14146        } else {
14147            synchronized (this) {
14148                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14149                pw.println();
14150                if (dumpAll) {
14151                    pw.println("-------------------------------------------------------------------------------");
14152                }
14153                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14154                pw.println();
14155                if (dumpAll) {
14156                    pw.println("-------------------------------------------------------------------------------");
14157                }
14158                if (dumpAll || dumpPackage != null) {
14159                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14160                    pw.println();
14161                    if (dumpAll) {
14162                        pw.println("-------------------------------------------------------------------------------");
14163                    }
14164                }
14165                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14166                pw.println();
14167                if (dumpAll) {
14168                    pw.println("-------------------------------------------------------------------------------");
14169                }
14170                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14171                pw.println();
14172                if (dumpAll) {
14173                    pw.println("-------------------------------------------------------------------------------");
14174                }
14175                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14176                        .dumpLocked();
14177                pw.println();
14178                if (dumpAll) {
14179                    pw.println("-------------------------------------------------------------------------------");
14180                }
14181                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14182                pw.println();
14183                if (dumpAll) {
14184                    pw.println("-------------------------------------------------------------------------------");
14185                }
14186                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14187                if (mAssociations.size() > 0) {
14188                    pw.println();
14189                    if (dumpAll) {
14190                        pw.println("-------------------------------------------------------------------------------");
14191                    }
14192                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14193                }
14194                pw.println();
14195                if (dumpAll) {
14196                    pw.println("-------------------------------------------------------------------------------");
14197                }
14198                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14199            }
14200        }
14201        Binder.restoreCallingIdentity(origId);
14202    }
14203
14204    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14205            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14206        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14207
14208        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14209                dumpPackage);
14210        boolean needSep = printedAnything;
14211
14212        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14213                dumpPackage, needSep, "  mFocusedActivity: ");
14214        if (printed) {
14215            printedAnything = true;
14216            needSep = false;
14217        }
14218
14219        if (dumpPackage == null) {
14220            if (needSep) {
14221                pw.println();
14222            }
14223            needSep = true;
14224            printedAnything = true;
14225            mStackSupervisor.dump(pw, "  ");
14226        }
14227
14228        if (!printedAnything) {
14229            pw.println("  (nothing)");
14230        }
14231    }
14232
14233    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14234            int opti, boolean dumpAll, String dumpPackage) {
14235        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14236
14237        boolean printedAnything = false;
14238
14239        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14240            boolean printedHeader = false;
14241
14242            final int N = mRecentTasks.size();
14243            for (int i=0; i<N; i++) {
14244                TaskRecord tr = mRecentTasks.get(i);
14245                if (dumpPackage != null) {
14246                    if (tr.realActivity == null ||
14247                            !dumpPackage.equals(tr.realActivity)) {
14248                        continue;
14249                    }
14250                }
14251                if (!printedHeader) {
14252                    pw.println("  Recent tasks:");
14253                    printedHeader = true;
14254                    printedAnything = true;
14255                }
14256                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14257                        pw.println(tr);
14258                if (dumpAll) {
14259                    mRecentTasks.get(i).dump(pw, "    ");
14260                }
14261            }
14262        }
14263
14264        if (!printedAnything) {
14265            pw.println("  (nothing)");
14266        }
14267    }
14268
14269    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14270            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14271        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14272
14273        int dumpUid = 0;
14274        if (dumpPackage != null) {
14275            IPackageManager pm = AppGlobals.getPackageManager();
14276            try {
14277                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14278            } catch (RemoteException e) {
14279            }
14280        }
14281
14282        boolean printedAnything = false;
14283
14284        final long now = SystemClock.uptimeMillis();
14285
14286        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14287            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14288                    = mAssociations.valueAt(i1);
14289            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14290                SparseArray<ArrayMap<String, Association>> sourceUids
14291                        = targetComponents.valueAt(i2);
14292                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14293                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14294                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14295                        Association ass = sourceProcesses.valueAt(i4);
14296                        if (dumpPackage != null) {
14297                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14298                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14299                                continue;
14300                            }
14301                        }
14302                        printedAnything = true;
14303                        pw.print("  ");
14304                        pw.print(ass.mTargetProcess);
14305                        pw.print("/");
14306                        UserHandle.formatUid(pw, ass.mTargetUid);
14307                        pw.print(" <- ");
14308                        pw.print(ass.mSourceProcess);
14309                        pw.print("/");
14310                        UserHandle.formatUid(pw, ass.mSourceUid);
14311                        pw.println();
14312                        pw.print("    via ");
14313                        pw.print(ass.mTargetComponent.flattenToShortString());
14314                        pw.println();
14315                        pw.print("    ");
14316                        long dur = ass.mTime;
14317                        if (ass.mNesting > 0) {
14318                            dur += now - ass.mStartTime;
14319                        }
14320                        TimeUtils.formatDuration(dur, pw);
14321                        pw.print(" (");
14322                        pw.print(ass.mCount);
14323                        pw.print(" times)");
14324                        pw.print("  ");
14325                        for (int i=0; i<ass.mStateTimes.length; i++) {
14326                            long amt = ass.mStateTimes[i];
14327                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14328                                amt += now - ass.mLastStateUptime;
14329                            }
14330                            if (amt != 0) {
14331                                pw.print(" ");
14332                                pw.print(ProcessList.makeProcStateString(
14333                                            i + ActivityManager.MIN_PROCESS_STATE));
14334                                pw.print("=");
14335                                TimeUtils.formatDuration(amt, pw);
14336                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14337                                    pw.print("*");
14338                                }
14339                            }
14340                        }
14341                        pw.println();
14342                        if (ass.mNesting > 0) {
14343                            pw.print("    Currently active: ");
14344                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14345                            pw.println();
14346                        }
14347                    }
14348                }
14349            }
14350
14351        }
14352
14353        if (!printedAnything) {
14354            pw.println("  (nothing)");
14355        }
14356    }
14357
14358    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14359            String header, boolean needSep) {
14360        boolean printed = false;
14361        int whichAppId = -1;
14362        if (dumpPackage != null) {
14363            try {
14364                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14365                        dumpPackage, 0);
14366                whichAppId = UserHandle.getAppId(info.uid);
14367            } catch (NameNotFoundException e) {
14368                e.printStackTrace();
14369            }
14370        }
14371        for (int i=0; i<uids.size(); i++) {
14372            UidRecord uidRec = uids.valueAt(i);
14373            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14374                continue;
14375            }
14376            if (!printed) {
14377                printed = true;
14378                if (needSep) {
14379                    pw.println();
14380                }
14381                pw.print("  ");
14382                pw.println(header);
14383                needSep = true;
14384            }
14385            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14386            pw.print(": "); pw.println(uidRec);
14387        }
14388        return printed;
14389    }
14390
14391    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14392            int opti, boolean dumpAll, String dumpPackage) {
14393        boolean needSep = false;
14394        boolean printedAnything = false;
14395        int numPers = 0;
14396
14397        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14398
14399        if (dumpAll) {
14400            final int NP = mProcessNames.getMap().size();
14401            for (int ip=0; ip<NP; ip++) {
14402                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14403                final int NA = procs.size();
14404                for (int ia=0; ia<NA; ia++) {
14405                    ProcessRecord r = procs.valueAt(ia);
14406                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14407                        continue;
14408                    }
14409                    if (!needSep) {
14410                        pw.println("  All known processes:");
14411                        needSep = true;
14412                        printedAnything = true;
14413                    }
14414                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14415                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14416                        pw.print(" "); pw.println(r);
14417                    r.dump(pw, "    ");
14418                    if (r.persistent) {
14419                        numPers++;
14420                    }
14421                }
14422            }
14423        }
14424
14425        if (mIsolatedProcesses.size() > 0) {
14426            boolean printed = false;
14427            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14428                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14429                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14430                    continue;
14431                }
14432                if (!printed) {
14433                    if (needSep) {
14434                        pw.println();
14435                    }
14436                    pw.println("  Isolated process list (sorted by uid):");
14437                    printedAnything = true;
14438                    printed = true;
14439                    needSep = true;
14440                }
14441                pw.println(String.format("%sIsolated #%2d: %s",
14442                        "    ", i, r.toString()));
14443            }
14444        }
14445
14446        if (mActiveUids.size() > 0) {
14447            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14448                printedAnything = needSep = true;
14449            }
14450        }
14451        if (mValidateUids.size() > 0) {
14452            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14453                printedAnything = needSep = true;
14454            }
14455        }
14456
14457        if (mLruProcesses.size() > 0) {
14458            if (needSep) {
14459                pw.println();
14460            }
14461            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14462                    pw.print(" total, non-act at ");
14463                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14464                    pw.print(", non-svc at ");
14465                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14466                    pw.println("):");
14467            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14468            needSep = true;
14469            printedAnything = true;
14470        }
14471
14472        if (dumpAll || dumpPackage != null) {
14473            synchronized (mPidsSelfLocked) {
14474                boolean printed = false;
14475                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14476                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14477                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14478                        continue;
14479                    }
14480                    if (!printed) {
14481                        if (needSep) pw.println();
14482                        needSep = true;
14483                        pw.println("  PID mappings:");
14484                        printed = true;
14485                        printedAnything = true;
14486                    }
14487                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14488                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14489                }
14490            }
14491        }
14492
14493        if (mForegroundProcesses.size() > 0) {
14494            synchronized (mPidsSelfLocked) {
14495                boolean printed = false;
14496                for (int i=0; i<mForegroundProcesses.size(); i++) {
14497                    ProcessRecord r = mPidsSelfLocked.get(
14498                            mForegroundProcesses.valueAt(i).pid);
14499                    if (dumpPackage != null && (r == null
14500                            || !r.pkgList.containsKey(dumpPackage))) {
14501                        continue;
14502                    }
14503                    if (!printed) {
14504                        if (needSep) pw.println();
14505                        needSep = true;
14506                        pw.println("  Foreground Processes:");
14507                        printed = true;
14508                        printedAnything = true;
14509                    }
14510                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14511                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14512                }
14513            }
14514        }
14515
14516        if (mPersistentStartingProcesses.size() > 0) {
14517            if (needSep) pw.println();
14518            needSep = true;
14519            printedAnything = true;
14520            pw.println("  Persisent processes that are starting:");
14521            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14522                    "Starting Norm", "Restarting PERS", dumpPackage);
14523        }
14524
14525        if (mRemovedProcesses.size() > 0) {
14526            if (needSep) pw.println();
14527            needSep = true;
14528            printedAnything = true;
14529            pw.println("  Processes that are being removed:");
14530            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14531                    "Removed Norm", "Removed PERS", dumpPackage);
14532        }
14533
14534        if (mProcessesOnHold.size() > 0) {
14535            if (needSep) pw.println();
14536            needSep = true;
14537            printedAnything = true;
14538            pw.println("  Processes that are on old until the system is ready:");
14539            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14540                    "OnHold Norm", "OnHold PERS", dumpPackage);
14541        }
14542
14543        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14544
14545        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14546        if (needSep) {
14547            printedAnything = true;
14548        }
14549
14550        if (dumpPackage == null) {
14551            pw.println();
14552            needSep = false;
14553            mUserController.dump(pw, dumpAll);
14554        }
14555        if (mHomeProcess != null && (dumpPackage == null
14556                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14557            if (needSep) {
14558                pw.println();
14559                needSep = false;
14560            }
14561            pw.println("  mHomeProcess: " + mHomeProcess);
14562        }
14563        if (mPreviousProcess != null && (dumpPackage == null
14564                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14565            if (needSep) {
14566                pw.println();
14567                needSep = false;
14568            }
14569            pw.println("  mPreviousProcess: " + mPreviousProcess);
14570        }
14571        if (dumpAll) {
14572            StringBuilder sb = new StringBuilder(128);
14573            sb.append("  mPreviousProcessVisibleTime: ");
14574            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14575            pw.println(sb);
14576        }
14577        if (mHeavyWeightProcess != null && (dumpPackage == null
14578                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14579            if (needSep) {
14580                pw.println();
14581                needSep = false;
14582            }
14583            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14584        }
14585        if (dumpPackage == null) {
14586            pw.println("  mConfiguration: " + mConfiguration);
14587        }
14588        if (dumpAll) {
14589            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14590            if (mCompatModePackages.getPackages().size() > 0) {
14591                boolean printed = false;
14592                for (Map.Entry<String, Integer> entry
14593                        : mCompatModePackages.getPackages().entrySet()) {
14594                    String pkg = entry.getKey();
14595                    int mode = entry.getValue();
14596                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14597                        continue;
14598                    }
14599                    if (!printed) {
14600                        pw.println("  mScreenCompatPackages:");
14601                        printed = true;
14602                    }
14603                    pw.print("    "); pw.print(pkg); pw.print(": ");
14604                            pw.print(mode); pw.println();
14605                }
14606            }
14607        }
14608        if (dumpPackage == null) {
14609            pw.println("  mWakefulness="
14610                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14611            pw.println("  mSleepTokens=" + mSleepTokens);
14612            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14613                    + lockScreenShownToString());
14614            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14615            if (mRunningVoice != null) {
14616                pw.println("  mRunningVoice=" + mRunningVoice);
14617                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14618            }
14619        }
14620        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14621                || mOrigWaitForDebugger) {
14622            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14623                    || dumpPackage.equals(mOrigDebugApp)) {
14624                if (needSep) {
14625                    pw.println();
14626                    needSep = false;
14627                }
14628                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14629                        + " mDebugTransient=" + mDebugTransient
14630                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14631            }
14632        }
14633        if (mCurAppTimeTracker != null) {
14634            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14635        }
14636        if (mMemWatchProcesses.getMap().size() > 0) {
14637            pw.println("  Mem watch processes:");
14638            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14639                    = mMemWatchProcesses.getMap();
14640            for (int i=0; i<procs.size(); i++) {
14641                final String proc = procs.keyAt(i);
14642                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14643                for (int j=0; j<uids.size(); j++) {
14644                    if (needSep) {
14645                        pw.println();
14646                        needSep = false;
14647                    }
14648                    StringBuilder sb = new StringBuilder();
14649                    sb.append("    ").append(proc).append('/');
14650                    UserHandle.formatUid(sb, uids.keyAt(j));
14651                    Pair<Long, String> val = uids.valueAt(j);
14652                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14653                    if (val.second != null) {
14654                        sb.append(", report to ").append(val.second);
14655                    }
14656                    pw.println(sb.toString());
14657                }
14658            }
14659            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14660            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14661            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14662                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14663        }
14664        if (mTrackAllocationApp != null) {
14665            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14666                if (needSep) {
14667                    pw.println();
14668                    needSep = false;
14669                }
14670                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14671            }
14672        }
14673        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14674                || mProfileFd != null) {
14675            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14676                if (needSep) {
14677                    pw.println();
14678                    needSep = false;
14679                }
14680                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14681                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14682                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14683                        + mAutoStopProfiler);
14684                pw.println("  mProfileType=" + mProfileType);
14685            }
14686        }
14687        if (mNativeDebuggingApp != null) {
14688            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14689                if (needSep) {
14690                    pw.println();
14691                    needSep = false;
14692                }
14693                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14694            }
14695        }
14696        if (dumpPackage == null) {
14697            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14698                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14699                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14700            }
14701            if (mController != null) {
14702                pw.println("  mController=" + mController
14703                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14704            }
14705            if (dumpAll) {
14706                pw.println("  Total persistent processes: " + numPers);
14707                pw.println("  mProcessesReady=" + mProcessesReady
14708                        + " mSystemReady=" + mSystemReady
14709                        + " mBooted=" + mBooted
14710                        + " mFactoryTest=" + mFactoryTest);
14711                pw.println("  mBooting=" + mBooting
14712                        + " mCallFinishBooting=" + mCallFinishBooting
14713                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14714                pw.print("  mLastPowerCheckRealtime=");
14715                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14716                        pw.println("");
14717                pw.print("  mLastPowerCheckUptime=");
14718                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14719                        pw.println("");
14720                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14721                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14722                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14723                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14724                        + " (" + mLruProcesses.size() + " total)"
14725                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14726                        + " mNumServiceProcs=" + mNumServiceProcs
14727                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14728                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14729                        + " mLastMemoryLevel=" + mLastMemoryLevel
14730                        + " mLastNumProcesses=" + mLastNumProcesses);
14731                long now = SystemClock.uptimeMillis();
14732                pw.print("  mLastIdleTime=");
14733                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14734                        pw.print(" mLowRamSinceLastIdle=");
14735                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14736                        pw.println();
14737            }
14738        }
14739
14740        if (!printedAnything) {
14741            pw.println("  (nothing)");
14742        }
14743    }
14744
14745    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14746            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14747        if (mProcessesToGc.size() > 0) {
14748            boolean printed = false;
14749            long now = SystemClock.uptimeMillis();
14750            for (int i=0; i<mProcessesToGc.size(); i++) {
14751                ProcessRecord proc = mProcessesToGc.get(i);
14752                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14753                    continue;
14754                }
14755                if (!printed) {
14756                    if (needSep) pw.println();
14757                    needSep = true;
14758                    pw.println("  Processes that are waiting to GC:");
14759                    printed = true;
14760                }
14761                pw.print("    Process "); pw.println(proc);
14762                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14763                        pw.print(", last gced=");
14764                        pw.print(now-proc.lastRequestedGc);
14765                        pw.print(" ms ago, last lowMem=");
14766                        pw.print(now-proc.lastLowMemory);
14767                        pw.println(" ms ago");
14768
14769            }
14770        }
14771        return needSep;
14772    }
14773
14774    void printOomLevel(PrintWriter pw, String name, int adj) {
14775        pw.print("    ");
14776        if (adj >= 0) {
14777            pw.print(' ');
14778            if (adj < 10) pw.print(' ');
14779        } else {
14780            if (adj > -10) pw.print(' ');
14781        }
14782        pw.print(adj);
14783        pw.print(": ");
14784        pw.print(name);
14785        pw.print(" (");
14786        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14787        pw.println(")");
14788    }
14789
14790    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14791            int opti, boolean dumpAll) {
14792        boolean needSep = false;
14793
14794        if (mLruProcesses.size() > 0) {
14795            if (needSep) pw.println();
14796            needSep = true;
14797            pw.println("  OOM levels:");
14798            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14799            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14800            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14801            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14802            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14803            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14804            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14805            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14806            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14807            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14808            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14809            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14810            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14811            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14812
14813            if (needSep) pw.println();
14814            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14815                    pw.print(" total, non-act at ");
14816                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14817                    pw.print(", non-svc at ");
14818                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14819                    pw.println("):");
14820            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14821            needSep = true;
14822        }
14823
14824        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14825
14826        pw.println();
14827        pw.println("  mHomeProcess: " + mHomeProcess);
14828        pw.println("  mPreviousProcess: " + mPreviousProcess);
14829        if (mHeavyWeightProcess != null) {
14830            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14831        }
14832
14833        return true;
14834    }
14835
14836    /**
14837     * There are three ways to call this:
14838     *  - no provider specified: dump all the providers
14839     *  - a flattened component name that matched an existing provider was specified as the
14840     *    first arg: dump that one provider
14841     *  - the first arg isn't the flattened component name of an existing provider:
14842     *    dump all providers whose component contains the first arg as a substring
14843     */
14844    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14845            int opti, boolean dumpAll) {
14846        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14847    }
14848
14849    static class ItemMatcher {
14850        ArrayList<ComponentName> components;
14851        ArrayList<String> strings;
14852        ArrayList<Integer> objects;
14853        boolean all;
14854
14855        ItemMatcher() {
14856            all = true;
14857        }
14858
14859        void build(String name) {
14860            ComponentName componentName = ComponentName.unflattenFromString(name);
14861            if (componentName != null) {
14862                if (components == null) {
14863                    components = new ArrayList<ComponentName>();
14864                }
14865                components.add(componentName);
14866                all = false;
14867            } else {
14868                int objectId = 0;
14869                // Not a '/' separated full component name; maybe an object ID?
14870                try {
14871                    objectId = Integer.parseInt(name, 16);
14872                    if (objects == null) {
14873                        objects = new ArrayList<Integer>();
14874                    }
14875                    objects.add(objectId);
14876                    all = false;
14877                } catch (RuntimeException e) {
14878                    // Not an integer; just do string match.
14879                    if (strings == null) {
14880                        strings = new ArrayList<String>();
14881                    }
14882                    strings.add(name);
14883                    all = false;
14884                }
14885            }
14886        }
14887
14888        int build(String[] args, int opti) {
14889            for (; opti<args.length; opti++) {
14890                String name = args[opti];
14891                if ("--".equals(name)) {
14892                    return opti+1;
14893                }
14894                build(name);
14895            }
14896            return opti;
14897        }
14898
14899        boolean match(Object object, ComponentName comp) {
14900            if (all) {
14901                return true;
14902            }
14903            if (components != null) {
14904                for (int i=0; i<components.size(); i++) {
14905                    if (components.get(i).equals(comp)) {
14906                        return true;
14907                    }
14908                }
14909            }
14910            if (objects != null) {
14911                for (int i=0; i<objects.size(); i++) {
14912                    if (System.identityHashCode(object) == objects.get(i)) {
14913                        return true;
14914                    }
14915                }
14916            }
14917            if (strings != null) {
14918                String flat = comp.flattenToString();
14919                for (int i=0; i<strings.size(); i++) {
14920                    if (flat.contains(strings.get(i))) {
14921                        return true;
14922                    }
14923                }
14924            }
14925            return false;
14926        }
14927    }
14928
14929    /**
14930     * There are three things that cmd can be:
14931     *  - a flattened component name that matches an existing activity
14932     *  - the cmd arg isn't the flattened component name of an existing activity:
14933     *    dump all activity whose component contains the cmd as a substring
14934     *  - A hex number of the ActivityRecord object instance.
14935     */
14936    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14937            int opti, boolean dumpAll) {
14938        ArrayList<ActivityRecord> activities;
14939
14940        synchronized (this) {
14941            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14942        }
14943
14944        if (activities.size() <= 0) {
14945            return false;
14946        }
14947
14948        String[] newArgs = new String[args.length - opti];
14949        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14950
14951        TaskRecord lastTask = null;
14952        boolean needSep = false;
14953        for (int i=activities.size()-1; i>=0; i--) {
14954            ActivityRecord r = activities.get(i);
14955            if (needSep) {
14956                pw.println();
14957            }
14958            needSep = true;
14959            synchronized (this) {
14960                if (lastTask != r.task) {
14961                    lastTask = r.task;
14962                    pw.print("TASK "); pw.print(lastTask.affinity);
14963                            pw.print(" id="); pw.println(lastTask.taskId);
14964                    if (dumpAll) {
14965                        lastTask.dump(pw, "  ");
14966                    }
14967                }
14968            }
14969            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14970        }
14971        return true;
14972    }
14973
14974    /**
14975     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14976     * there is a thread associated with the activity.
14977     */
14978    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14979            final ActivityRecord r, String[] args, boolean dumpAll) {
14980        String innerPrefix = prefix + "  ";
14981        synchronized (this) {
14982            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14983                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14984                    pw.print(" pid=");
14985                    if (r.app != null) pw.println(r.app.pid);
14986                    else pw.println("(not running)");
14987            if (dumpAll) {
14988                r.dump(pw, innerPrefix);
14989            }
14990        }
14991        if (r.app != null && r.app.thread != null) {
14992            // flush anything that is already in the PrintWriter since the thread is going
14993            // to write to the file descriptor directly
14994            pw.flush();
14995            try {
14996                TransferPipe tp = new TransferPipe();
14997                try {
14998                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14999                            r.appToken, innerPrefix, args);
15000                    tp.go(fd);
15001                } finally {
15002                    tp.kill();
15003                }
15004            } catch (IOException e) {
15005                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15006            } catch (RemoteException e) {
15007                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15008            }
15009        }
15010    }
15011
15012    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15013            int opti, boolean dumpAll, String dumpPackage) {
15014        boolean needSep = false;
15015        boolean onlyHistory = false;
15016        boolean printedAnything = false;
15017
15018        if ("history".equals(dumpPackage)) {
15019            if (opti < args.length && "-s".equals(args[opti])) {
15020                dumpAll = false;
15021            }
15022            onlyHistory = true;
15023            dumpPackage = null;
15024        }
15025
15026        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15027        if (!onlyHistory && dumpAll) {
15028            if (mRegisteredReceivers.size() > 0) {
15029                boolean printed = false;
15030                Iterator it = mRegisteredReceivers.values().iterator();
15031                while (it.hasNext()) {
15032                    ReceiverList r = (ReceiverList)it.next();
15033                    if (dumpPackage != null && (r.app == null ||
15034                            !dumpPackage.equals(r.app.info.packageName))) {
15035                        continue;
15036                    }
15037                    if (!printed) {
15038                        pw.println("  Registered Receivers:");
15039                        needSep = true;
15040                        printed = true;
15041                        printedAnything = true;
15042                    }
15043                    pw.print("  * "); pw.println(r);
15044                    r.dump(pw, "    ");
15045                }
15046            }
15047
15048            if (mReceiverResolver.dump(pw, needSep ?
15049                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15050                    "    ", dumpPackage, false, false)) {
15051                needSep = true;
15052                printedAnything = true;
15053            }
15054        }
15055
15056        for (BroadcastQueue q : mBroadcastQueues) {
15057            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15058            printedAnything |= needSep;
15059        }
15060
15061        needSep = true;
15062
15063        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15064            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15065                if (needSep) {
15066                    pw.println();
15067                }
15068                needSep = true;
15069                printedAnything = true;
15070                pw.print("  Sticky broadcasts for user ");
15071                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15072                StringBuilder sb = new StringBuilder(128);
15073                for (Map.Entry<String, ArrayList<Intent>> ent
15074                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15075                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15076                    if (dumpAll) {
15077                        pw.println(":");
15078                        ArrayList<Intent> intents = ent.getValue();
15079                        final int N = intents.size();
15080                        for (int i=0; i<N; i++) {
15081                            sb.setLength(0);
15082                            sb.append("    Intent: ");
15083                            intents.get(i).toShortString(sb, false, true, false, false);
15084                            pw.println(sb.toString());
15085                            Bundle bundle = intents.get(i).getExtras();
15086                            if (bundle != null) {
15087                                pw.print("      ");
15088                                pw.println(bundle.toString());
15089                            }
15090                        }
15091                    } else {
15092                        pw.println("");
15093                    }
15094                }
15095            }
15096        }
15097
15098        if (!onlyHistory && dumpAll) {
15099            pw.println();
15100            for (BroadcastQueue queue : mBroadcastQueues) {
15101                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15102                        + queue.mBroadcastsScheduled);
15103            }
15104            pw.println("  mHandler:");
15105            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15106            needSep = true;
15107            printedAnything = true;
15108        }
15109
15110        if (!printedAnything) {
15111            pw.println("  (nothing)");
15112        }
15113    }
15114
15115    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15116            int opti, boolean dumpAll, String dumpPackage) {
15117        if (mCurBroadcastStats == null) {
15118            return;
15119        }
15120
15121        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15122        final long now = SystemClock.elapsedRealtime();
15123        if (mLastBroadcastStats != null) {
15124            pw.print("  Last stats (from ");
15125            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15126            pw.print(" to ");
15127            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15128            pw.print(", ");
15129            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15130                    - mLastBroadcastStats.mStartUptime, pw);
15131            pw.println(" uptime):");
15132            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15133                pw.println("    (nothing)");
15134            }
15135            pw.println();
15136        }
15137        pw.print("  Current stats (from ");
15138        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15139        pw.print(" to now, ");
15140        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15141                - mCurBroadcastStats.mStartUptime, pw);
15142        pw.println(" uptime):");
15143        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15144            pw.println("    (nothing)");
15145        }
15146    }
15147
15148    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15149            int opti, boolean fullCheckin, String dumpPackage) {
15150        if (mCurBroadcastStats == null) {
15151            return;
15152        }
15153
15154        if (mLastBroadcastStats != null) {
15155            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15156            if (fullCheckin) {
15157                mLastBroadcastStats = null;
15158                return;
15159            }
15160        }
15161        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15162        if (fullCheckin) {
15163            mCurBroadcastStats = null;
15164        }
15165    }
15166
15167    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15168            int opti, boolean dumpAll, String dumpPackage) {
15169        boolean needSep;
15170        boolean printedAnything = false;
15171
15172        ItemMatcher matcher = new ItemMatcher();
15173        matcher.build(args, opti);
15174
15175        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15176
15177        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15178        printedAnything |= needSep;
15179
15180        if (mLaunchingProviders.size() > 0) {
15181            boolean printed = false;
15182            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15183                ContentProviderRecord r = mLaunchingProviders.get(i);
15184                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15185                    continue;
15186                }
15187                if (!printed) {
15188                    if (needSep) pw.println();
15189                    needSep = true;
15190                    pw.println("  Launching content providers:");
15191                    printed = true;
15192                    printedAnything = true;
15193                }
15194                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15195                        pw.println(r);
15196            }
15197        }
15198
15199        if (!printedAnything) {
15200            pw.println("  (nothing)");
15201        }
15202    }
15203
15204    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15205            int opti, boolean dumpAll, String dumpPackage) {
15206        boolean needSep = false;
15207        boolean printedAnything = false;
15208
15209        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15210
15211        if (mGrantedUriPermissions.size() > 0) {
15212            boolean printed = false;
15213            int dumpUid = -2;
15214            if (dumpPackage != null) {
15215                try {
15216                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15217                            MATCH_UNINSTALLED_PACKAGES, 0);
15218                } catch (NameNotFoundException e) {
15219                    dumpUid = -1;
15220                }
15221            }
15222            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15223                int uid = mGrantedUriPermissions.keyAt(i);
15224                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15225                    continue;
15226                }
15227                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15228                if (!printed) {
15229                    if (needSep) pw.println();
15230                    needSep = true;
15231                    pw.println("  Granted Uri Permissions:");
15232                    printed = true;
15233                    printedAnything = true;
15234                }
15235                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15236                for (UriPermission perm : perms.values()) {
15237                    pw.print("    "); pw.println(perm);
15238                    if (dumpAll) {
15239                        perm.dump(pw, "      ");
15240                    }
15241                }
15242            }
15243        }
15244
15245        if (!printedAnything) {
15246            pw.println("  (nothing)");
15247        }
15248    }
15249
15250    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15251            int opti, boolean dumpAll, String dumpPackage) {
15252        boolean printed = false;
15253
15254        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15255
15256        if (mIntentSenderRecords.size() > 0) {
15257            Iterator<WeakReference<PendingIntentRecord>> it
15258                    = mIntentSenderRecords.values().iterator();
15259            while (it.hasNext()) {
15260                WeakReference<PendingIntentRecord> ref = it.next();
15261                PendingIntentRecord rec = ref != null ? ref.get(): null;
15262                if (dumpPackage != null && (rec == null
15263                        || !dumpPackage.equals(rec.key.packageName))) {
15264                    continue;
15265                }
15266                printed = true;
15267                if (rec != null) {
15268                    pw.print("  * "); pw.println(rec);
15269                    if (dumpAll) {
15270                        rec.dump(pw, "    ");
15271                    }
15272                } else {
15273                    pw.print("  * "); pw.println(ref);
15274                }
15275            }
15276        }
15277
15278        if (!printed) {
15279            pw.println("  (nothing)");
15280        }
15281    }
15282
15283    private static final int dumpProcessList(PrintWriter pw,
15284            ActivityManagerService service, List list,
15285            String prefix, String normalLabel, String persistentLabel,
15286            String dumpPackage) {
15287        int numPers = 0;
15288        final int N = list.size()-1;
15289        for (int i=N; i>=0; i--) {
15290            ProcessRecord r = (ProcessRecord)list.get(i);
15291            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15292                continue;
15293            }
15294            pw.println(String.format("%s%s #%2d: %s",
15295                    prefix, (r.persistent ? persistentLabel : normalLabel),
15296                    i, r.toString()));
15297            if (r.persistent) {
15298                numPers++;
15299            }
15300        }
15301        return numPers;
15302    }
15303
15304    private static final boolean dumpProcessOomList(PrintWriter pw,
15305            ActivityManagerService service, List<ProcessRecord> origList,
15306            String prefix, String normalLabel, String persistentLabel,
15307            boolean inclDetails, String dumpPackage) {
15308
15309        ArrayList<Pair<ProcessRecord, Integer>> list
15310                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15311        for (int i=0; i<origList.size(); i++) {
15312            ProcessRecord r = origList.get(i);
15313            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15314                continue;
15315            }
15316            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15317        }
15318
15319        if (list.size() <= 0) {
15320            return false;
15321        }
15322
15323        Comparator<Pair<ProcessRecord, Integer>> comparator
15324                = new Comparator<Pair<ProcessRecord, Integer>>() {
15325            @Override
15326            public int compare(Pair<ProcessRecord, Integer> object1,
15327                    Pair<ProcessRecord, Integer> object2) {
15328                if (object1.first.setAdj != object2.first.setAdj) {
15329                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15330                }
15331                if (object1.first.setProcState != object2.first.setProcState) {
15332                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15333                }
15334                if (object1.second.intValue() != object2.second.intValue()) {
15335                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15336                }
15337                return 0;
15338            }
15339        };
15340
15341        Collections.sort(list, comparator);
15342
15343        final long curRealtime = SystemClock.elapsedRealtime();
15344        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15345        final long curUptime = SystemClock.uptimeMillis();
15346        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15347
15348        for (int i=list.size()-1; i>=0; i--) {
15349            ProcessRecord r = list.get(i).first;
15350            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15351            char schedGroup;
15352            switch (r.setSchedGroup) {
15353                case ProcessList.SCHED_GROUP_BACKGROUND:
15354                    schedGroup = 'B';
15355                    break;
15356                case ProcessList.SCHED_GROUP_DEFAULT:
15357                    schedGroup = 'F';
15358                    break;
15359                case ProcessList.SCHED_GROUP_TOP_APP:
15360                    schedGroup = 'T';
15361                    break;
15362                default:
15363                    schedGroup = '?';
15364                    break;
15365            }
15366            char foreground;
15367            if (r.foregroundActivities) {
15368                foreground = 'A';
15369            } else if (r.foregroundServices) {
15370                foreground = 'S';
15371            } else {
15372                foreground = ' ';
15373            }
15374            String procState = ProcessList.makeProcStateString(r.curProcState);
15375            pw.print(prefix);
15376            pw.print(r.persistent ? persistentLabel : normalLabel);
15377            pw.print(" #");
15378            int num = (origList.size()-1)-list.get(i).second;
15379            if (num < 10) pw.print(' ');
15380            pw.print(num);
15381            pw.print(": ");
15382            pw.print(oomAdj);
15383            pw.print(' ');
15384            pw.print(schedGroup);
15385            pw.print('/');
15386            pw.print(foreground);
15387            pw.print('/');
15388            pw.print(procState);
15389            pw.print(" trm:");
15390            if (r.trimMemoryLevel < 10) pw.print(' ');
15391            pw.print(r.trimMemoryLevel);
15392            pw.print(' ');
15393            pw.print(r.toShortString());
15394            pw.print(" (");
15395            pw.print(r.adjType);
15396            pw.println(')');
15397            if (r.adjSource != null || r.adjTarget != null) {
15398                pw.print(prefix);
15399                pw.print("    ");
15400                if (r.adjTarget instanceof ComponentName) {
15401                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15402                } else if (r.adjTarget != null) {
15403                    pw.print(r.adjTarget.toString());
15404                } else {
15405                    pw.print("{null}");
15406                }
15407                pw.print("<=");
15408                if (r.adjSource instanceof ProcessRecord) {
15409                    pw.print("Proc{");
15410                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15411                    pw.println("}");
15412                } else if (r.adjSource != null) {
15413                    pw.println(r.adjSource.toString());
15414                } else {
15415                    pw.println("{null}");
15416                }
15417            }
15418            if (inclDetails) {
15419                pw.print(prefix);
15420                pw.print("    ");
15421                pw.print("oom: max="); pw.print(r.maxAdj);
15422                pw.print(" curRaw="); pw.print(r.curRawAdj);
15423                pw.print(" setRaw="); pw.print(r.setRawAdj);
15424                pw.print(" cur="); pw.print(r.curAdj);
15425                pw.print(" set="); pw.println(r.setAdj);
15426                pw.print(prefix);
15427                pw.print("    ");
15428                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15429                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15430                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15431                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15432                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15433                pw.println();
15434                pw.print(prefix);
15435                pw.print("    ");
15436                pw.print("cached="); pw.print(r.cached);
15437                pw.print(" empty="); pw.print(r.empty);
15438                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15439
15440                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15441                    if (r.lastWakeTime != 0) {
15442                        long wtime;
15443                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15444                        synchronized (stats) {
15445                            wtime = stats.getProcessWakeTime(r.info.uid,
15446                                    r.pid, curRealtime);
15447                        }
15448                        long timeUsed = wtime - r.lastWakeTime;
15449                        pw.print(prefix);
15450                        pw.print("    ");
15451                        pw.print("keep awake over ");
15452                        TimeUtils.formatDuration(realtimeSince, pw);
15453                        pw.print(" used ");
15454                        TimeUtils.formatDuration(timeUsed, pw);
15455                        pw.print(" (");
15456                        pw.print((timeUsed*100)/realtimeSince);
15457                        pw.println("%)");
15458                    }
15459                    if (r.lastCpuTime != 0) {
15460                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15461                        pw.print(prefix);
15462                        pw.print("    ");
15463                        pw.print("run cpu over ");
15464                        TimeUtils.formatDuration(uptimeSince, pw);
15465                        pw.print(" used ");
15466                        TimeUtils.formatDuration(timeUsed, pw);
15467                        pw.print(" (");
15468                        pw.print((timeUsed*100)/uptimeSince);
15469                        pw.println("%)");
15470                    }
15471                }
15472            }
15473        }
15474        return true;
15475    }
15476
15477    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15478            String[] args) {
15479        ArrayList<ProcessRecord> procs;
15480        synchronized (this) {
15481            if (args != null && args.length > start
15482                    && args[start].charAt(0) != '-') {
15483                procs = new ArrayList<ProcessRecord>();
15484                int pid = -1;
15485                try {
15486                    pid = Integer.parseInt(args[start]);
15487                } catch (NumberFormatException e) {
15488                }
15489                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15490                    ProcessRecord proc = mLruProcesses.get(i);
15491                    if (proc.pid == pid) {
15492                        procs.add(proc);
15493                    } else if (allPkgs && proc.pkgList != null
15494                            && proc.pkgList.containsKey(args[start])) {
15495                        procs.add(proc);
15496                    } else if (proc.processName.equals(args[start])) {
15497                        procs.add(proc);
15498                    }
15499                }
15500                if (procs.size() <= 0) {
15501                    return null;
15502                }
15503            } else {
15504                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15505            }
15506        }
15507        return procs;
15508    }
15509
15510    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15511            PrintWriter pw, String[] args) {
15512        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15513        if (procs == null) {
15514            pw.println("No process found for: " + args[0]);
15515            return;
15516        }
15517
15518        long uptime = SystemClock.uptimeMillis();
15519        long realtime = SystemClock.elapsedRealtime();
15520        pw.println("Applications Graphics Acceleration Info:");
15521        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15522
15523        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15524            ProcessRecord r = procs.get(i);
15525            if (r.thread != null) {
15526                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15527                pw.flush();
15528                try {
15529                    TransferPipe tp = new TransferPipe();
15530                    try {
15531                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15532                        tp.go(fd);
15533                    } finally {
15534                        tp.kill();
15535                    }
15536                } catch (IOException e) {
15537                    pw.println("Failure while dumping the app: " + r);
15538                    pw.flush();
15539                } catch (RemoteException e) {
15540                    pw.println("Got a RemoteException while dumping the app " + r);
15541                    pw.flush();
15542                }
15543            }
15544        }
15545    }
15546
15547    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15548        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15549        if (procs == null) {
15550            pw.println("No process found for: " + args[0]);
15551            return;
15552        }
15553
15554        pw.println("Applications Database Info:");
15555
15556        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15557            ProcessRecord r = procs.get(i);
15558            if (r.thread != null) {
15559                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15560                pw.flush();
15561                try {
15562                    TransferPipe tp = new TransferPipe();
15563                    try {
15564                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15565                        tp.go(fd);
15566                    } finally {
15567                        tp.kill();
15568                    }
15569                } catch (IOException e) {
15570                    pw.println("Failure while dumping the app: " + r);
15571                    pw.flush();
15572                } catch (RemoteException e) {
15573                    pw.println("Got a RemoteException while dumping the app " + r);
15574                    pw.flush();
15575                }
15576            }
15577        }
15578    }
15579
15580    final static class MemItem {
15581        final boolean isProc;
15582        final String label;
15583        final String shortLabel;
15584        final long pss;
15585        final long swapPss;
15586        final int id;
15587        final boolean hasActivities;
15588        ArrayList<MemItem> subitems;
15589
15590        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15591                boolean _hasActivities) {
15592            isProc = true;
15593            label = _label;
15594            shortLabel = _shortLabel;
15595            pss = _pss;
15596            swapPss = _swapPss;
15597            id = _id;
15598            hasActivities = _hasActivities;
15599        }
15600
15601        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15602            isProc = false;
15603            label = _label;
15604            shortLabel = _shortLabel;
15605            pss = _pss;
15606            swapPss = _swapPss;
15607            id = _id;
15608            hasActivities = false;
15609        }
15610    }
15611
15612    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15613            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15614        if (sort && !isCompact) {
15615            Collections.sort(items, new Comparator<MemItem>() {
15616                @Override
15617                public int compare(MemItem lhs, MemItem rhs) {
15618                    if (lhs.pss < rhs.pss) {
15619                        return 1;
15620                    } else if (lhs.pss > rhs.pss) {
15621                        return -1;
15622                    }
15623                    return 0;
15624                }
15625            });
15626        }
15627
15628        for (int i=0; i<items.size(); i++) {
15629            MemItem mi = items.get(i);
15630            if (!isCompact) {
15631                if (dumpSwapPss) {
15632                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15633                            mi.label, stringifyKBSize(mi.swapPss));
15634                } else {
15635                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15636                }
15637            } else if (mi.isProc) {
15638                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15639                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15640                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15641                pw.println(mi.hasActivities ? ",a" : ",e");
15642            } else {
15643                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15644                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15645            }
15646            if (mi.subitems != null) {
15647                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15648                        true, isCompact, dumpSwapPss);
15649            }
15650        }
15651    }
15652
15653    // These are in KB.
15654    static final long[] DUMP_MEM_BUCKETS = new long[] {
15655        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15656        120*1024, 160*1024, 200*1024,
15657        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15658        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15659    };
15660
15661    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15662            boolean stackLike) {
15663        int start = label.lastIndexOf('.');
15664        if (start >= 0) start++;
15665        else start = 0;
15666        int end = label.length();
15667        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15668            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15669                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15670                out.append(bucket);
15671                out.append(stackLike ? "MB." : "MB ");
15672                out.append(label, start, end);
15673                return;
15674            }
15675        }
15676        out.append(memKB/1024);
15677        out.append(stackLike ? "MB." : "MB ");
15678        out.append(label, start, end);
15679    }
15680
15681    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15682            ProcessList.NATIVE_ADJ,
15683            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15684            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15685            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15686            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15687            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15688            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15689    };
15690    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15691            "Native",
15692            "System", "Persistent", "Persistent Service", "Foreground",
15693            "Visible", "Perceptible",
15694            "Heavy Weight", "Backup",
15695            "A Services", "Home",
15696            "Previous", "B Services", "Cached"
15697    };
15698    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15699            "native",
15700            "sys", "pers", "persvc", "fore",
15701            "vis", "percept",
15702            "heavy", "backup",
15703            "servicea", "home",
15704            "prev", "serviceb", "cached"
15705    };
15706
15707    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15708            long realtime, boolean isCheckinRequest, boolean isCompact) {
15709        if (isCompact) {
15710            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15711        }
15712        if (isCheckinRequest || isCompact) {
15713            // short checkin version
15714            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15715        } else {
15716            pw.println("Applications Memory Usage (in Kilobytes):");
15717            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15718        }
15719    }
15720
15721    private static final int KSM_SHARED = 0;
15722    private static final int KSM_SHARING = 1;
15723    private static final int KSM_UNSHARED = 2;
15724    private static final int KSM_VOLATILE = 3;
15725
15726    private final long[] getKsmInfo() {
15727        long[] longOut = new long[4];
15728        final int[] SINGLE_LONG_FORMAT = new int[] {
15729            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15730        };
15731        long[] longTmp = new long[1];
15732        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15733                SINGLE_LONG_FORMAT, null, longTmp, null);
15734        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15735        longTmp[0] = 0;
15736        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15737                SINGLE_LONG_FORMAT, null, longTmp, null);
15738        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15739        longTmp[0] = 0;
15740        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15741                SINGLE_LONG_FORMAT, null, longTmp, null);
15742        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15743        longTmp[0] = 0;
15744        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15745                SINGLE_LONG_FORMAT, null, longTmp, null);
15746        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15747        return longOut;
15748    }
15749
15750    private static String stringifySize(long size, int order) {
15751        Locale locale = Locale.US;
15752        switch (order) {
15753            case 1:
15754                return String.format(locale, "%,13d", size);
15755            case 1024:
15756                return String.format(locale, "%,9dK", size / 1024);
15757            case 1024 * 1024:
15758                return String.format(locale, "%,5dM", size / 1024 / 1024);
15759            case 1024 * 1024 * 1024:
15760                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15761            default:
15762                throw new IllegalArgumentException("Invalid size order");
15763        }
15764    }
15765
15766    private static String stringifyKBSize(long size) {
15767        return stringifySize(size * 1024, 1024);
15768    }
15769
15770    // Update this version number in case you change the 'compact' format
15771    private static final int MEMINFO_COMPACT_VERSION = 1;
15772
15773    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15774            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15775        boolean dumpDetails = false;
15776        boolean dumpFullDetails = false;
15777        boolean dumpDalvik = false;
15778        boolean dumpSummaryOnly = false;
15779        boolean dumpUnreachable = false;
15780        boolean oomOnly = false;
15781        boolean isCompact = false;
15782        boolean localOnly = false;
15783        boolean packages = false;
15784        boolean isCheckinRequest = false;
15785        boolean dumpSwapPss = false;
15786
15787        int opti = 0;
15788        while (opti < args.length) {
15789            String opt = args[opti];
15790            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15791                break;
15792            }
15793            opti++;
15794            if ("-a".equals(opt)) {
15795                dumpDetails = true;
15796                dumpFullDetails = true;
15797                dumpDalvik = true;
15798                dumpSwapPss = true;
15799            } else if ("-d".equals(opt)) {
15800                dumpDalvik = true;
15801            } else if ("-c".equals(opt)) {
15802                isCompact = true;
15803            } else if ("-s".equals(opt)) {
15804                dumpDetails = true;
15805                dumpSummaryOnly = true;
15806            } else if ("-S".equals(opt)) {
15807                dumpSwapPss = true;
15808            } else if ("--unreachable".equals(opt)) {
15809                dumpUnreachable = true;
15810            } else if ("--oom".equals(opt)) {
15811                oomOnly = true;
15812            } else if ("--local".equals(opt)) {
15813                localOnly = true;
15814            } else if ("--package".equals(opt)) {
15815                packages = true;
15816            } else if ("--checkin".equals(opt)) {
15817                isCheckinRequest = true;
15818
15819            } else if ("-h".equals(opt)) {
15820                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15821                pw.println("  -a: include all available information for each process.");
15822                pw.println("  -d: include dalvik details.");
15823                pw.println("  -c: dump in a compact machine-parseable representation.");
15824                pw.println("  -s: dump only summary of application memory usage.");
15825                pw.println("  -S: dump also SwapPss.");
15826                pw.println("  --oom: only show processes organized by oom adj.");
15827                pw.println("  --local: only collect details locally, don't call process.");
15828                pw.println("  --package: interpret process arg as package, dumping all");
15829                pw.println("             processes that have loaded that package.");
15830                pw.println("  --checkin: dump data for a checkin");
15831                pw.println("If [process] is specified it can be the name or ");
15832                pw.println("pid of a specific process to dump.");
15833                return;
15834            } else {
15835                pw.println("Unknown argument: " + opt + "; use -h for help");
15836            }
15837        }
15838
15839        long uptime = SystemClock.uptimeMillis();
15840        long realtime = SystemClock.elapsedRealtime();
15841        final long[] tmpLong = new long[1];
15842
15843        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15844        if (procs == null) {
15845            // No Java processes.  Maybe they want to print a native process.
15846            if (args != null && args.length > opti
15847                    && args[opti].charAt(0) != '-') {
15848                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15849                        = new ArrayList<ProcessCpuTracker.Stats>();
15850                updateCpuStatsNow();
15851                int findPid = -1;
15852                try {
15853                    findPid = Integer.parseInt(args[opti]);
15854                } catch (NumberFormatException e) {
15855                }
15856                synchronized (mProcessCpuTracker) {
15857                    final int N = mProcessCpuTracker.countStats();
15858                    for (int i=0; i<N; i++) {
15859                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15860                        if (st.pid == findPid || (st.baseName != null
15861                                && st.baseName.equals(args[opti]))) {
15862                            nativeProcs.add(st);
15863                        }
15864                    }
15865                }
15866                if (nativeProcs.size() > 0) {
15867                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15868                            isCompact);
15869                    Debug.MemoryInfo mi = null;
15870                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15871                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15872                        final int pid = r.pid;
15873                        if (!isCheckinRequest && dumpDetails) {
15874                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15875                        }
15876                        if (mi == null) {
15877                            mi = new Debug.MemoryInfo();
15878                        }
15879                        if (dumpDetails || (!brief && !oomOnly)) {
15880                            Debug.getMemoryInfo(pid, mi);
15881                        } else {
15882                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15883                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15884                        }
15885                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15886                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15887                        if (isCheckinRequest) {
15888                            pw.println();
15889                        }
15890                    }
15891                    return;
15892                }
15893            }
15894            pw.println("No process found for: " + args[opti]);
15895            return;
15896        }
15897
15898        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15899            dumpDetails = true;
15900        }
15901
15902        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15903
15904        String[] innerArgs = new String[args.length-opti];
15905        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15906
15907        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15908        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15909        long nativePss = 0;
15910        long nativeSwapPss = 0;
15911        long dalvikPss = 0;
15912        long dalvikSwapPss = 0;
15913        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15914                EmptyArray.LONG;
15915        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15916                EmptyArray.LONG;
15917        long otherPss = 0;
15918        long otherSwapPss = 0;
15919        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15920        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15921
15922        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15923        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15924        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15925                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15926
15927        long totalPss = 0;
15928        long totalSwapPss = 0;
15929        long cachedPss = 0;
15930        long cachedSwapPss = 0;
15931        boolean hasSwapPss = false;
15932
15933        Debug.MemoryInfo mi = null;
15934        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15935            final ProcessRecord r = procs.get(i);
15936            final IApplicationThread thread;
15937            final int pid;
15938            final int oomAdj;
15939            final boolean hasActivities;
15940            synchronized (this) {
15941                thread = r.thread;
15942                pid = r.pid;
15943                oomAdj = r.getSetAdjWithServices();
15944                hasActivities = r.activities.size() > 0;
15945            }
15946            if (thread != null) {
15947                if (!isCheckinRequest && dumpDetails) {
15948                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15949                }
15950                if (mi == null) {
15951                    mi = new Debug.MemoryInfo();
15952                }
15953                if (dumpDetails || (!brief && !oomOnly)) {
15954                    Debug.getMemoryInfo(pid, mi);
15955                    hasSwapPss = mi.hasSwappedOutPss;
15956                } else {
15957                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15958                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15959                }
15960                if (dumpDetails) {
15961                    if (localOnly) {
15962                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15963                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15964                        if (isCheckinRequest) {
15965                            pw.println();
15966                        }
15967                    } else {
15968                        try {
15969                            pw.flush();
15970                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15971                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15972                        } catch (RemoteException e) {
15973                            if (!isCheckinRequest) {
15974                                pw.println("Got RemoteException!");
15975                                pw.flush();
15976                            }
15977                        }
15978                    }
15979                }
15980
15981                final long myTotalPss = mi.getTotalPss();
15982                final long myTotalUss = mi.getTotalUss();
15983                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15984
15985                synchronized (this) {
15986                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15987                        // Record this for posterity if the process has been stable.
15988                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15989                    }
15990                }
15991
15992                if (!isCheckinRequest && mi != null) {
15993                    totalPss += myTotalPss;
15994                    totalSwapPss += myTotalSwapPss;
15995                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15996                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15997                            myTotalSwapPss, pid, hasActivities);
15998                    procMems.add(pssItem);
15999                    procMemsMap.put(pid, pssItem);
16000
16001                    nativePss += mi.nativePss;
16002                    nativeSwapPss += mi.nativeSwappedOutPss;
16003                    dalvikPss += mi.dalvikPss;
16004                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16005                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16006                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16007                        dalvikSubitemSwapPss[j] +=
16008                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16009                    }
16010                    otherPss += mi.otherPss;
16011                    otherSwapPss += mi.otherSwappedOutPss;
16012                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16013                        long mem = mi.getOtherPss(j);
16014                        miscPss[j] += mem;
16015                        otherPss -= mem;
16016                        mem = mi.getOtherSwappedOutPss(j);
16017                        miscSwapPss[j] += mem;
16018                        otherSwapPss -= mem;
16019                    }
16020
16021                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16022                        cachedPss += myTotalPss;
16023                        cachedSwapPss += myTotalSwapPss;
16024                    }
16025
16026                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16027                        if (oomIndex == (oomPss.length - 1)
16028                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16029                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16030                            oomPss[oomIndex] += myTotalPss;
16031                            oomSwapPss[oomIndex] += myTotalSwapPss;
16032                            if (oomProcs[oomIndex] == null) {
16033                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16034                            }
16035                            oomProcs[oomIndex].add(pssItem);
16036                            break;
16037                        }
16038                    }
16039                }
16040            }
16041        }
16042
16043        long nativeProcTotalPss = 0;
16044
16045        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16046            // If we are showing aggregations, also look for native processes to
16047            // include so that our aggregations are more accurate.
16048            updateCpuStatsNow();
16049            mi = null;
16050            synchronized (mProcessCpuTracker) {
16051                final int N = mProcessCpuTracker.countStats();
16052                for (int i=0; i<N; i++) {
16053                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16054                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16055                        if (mi == null) {
16056                            mi = new Debug.MemoryInfo();
16057                        }
16058                        if (!brief && !oomOnly) {
16059                            Debug.getMemoryInfo(st.pid, mi);
16060                        } else {
16061                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16062                            mi.nativePrivateDirty = (int)tmpLong[0];
16063                        }
16064
16065                        final long myTotalPss = mi.getTotalPss();
16066                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16067                        totalPss += myTotalPss;
16068                        nativeProcTotalPss += myTotalPss;
16069
16070                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16071                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16072                        procMems.add(pssItem);
16073
16074                        nativePss += mi.nativePss;
16075                        nativeSwapPss += mi.nativeSwappedOutPss;
16076                        dalvikPss += mi.dalvikPss;
16077                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16078                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16079                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16080                            dalvikSubitemSwapPss[j] +=
16081                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16082                        }
16083                        otherPss += mi.otherPss;
16084                        otherSwapPss += mi.otherSwappedOutPss;
16085                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16086                            long mem = mi.getOtherPss(j);
16087                            miscPss[j] += mem;
16088                            otherPss -= mem;
16089                            mem = mi.getOtherSwappedOutPss(j);
16090                            miscSwapPss[j] += mem;
16091                            otherSwapPss -= mem;
16092                        }
16093                        oomPss[0] += myTotalPss;
16094                        oomSwapPss[0] += myTotalSwapPss;
16095                        if (oomProcs[0] == null) {
16096                            oomProcs[0] = new ArrayList<MemItem>();
16097                        }
16098                        oomProcs[0].add(pssItem);
16099                    }
16100                }
16101            }
16102
16103            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16104
16105            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16106            final MemItem dalvikItem =
16107                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16108            if (dalvikSubitemPss.length > 0) {
16109                dalvikItem.subitems = new ArrayList<MemItem>();
16110                for (int j=0; j<dalvikSubitemPss.length; j++) {
16111                    final String name = Debug.MemoryInfo.getOtherLabel(
16112                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16113                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16114                                    dalvikSubitemSwapPss[j], j));
16115                }
16116            }
16117            catMems.add(dalvikItem);
16118            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16119            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16120                String label = Debug.MemoryInfo.getOtherLabel(j);
16121                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16122            }
16123
16124            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16125            for (int j=0; j<oomPss.length; j++) {
16126                if (oomPss[j] != 0) {
16127                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16128                            : DUMP_MEM_OOM_LABEL[j];
16129                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16130                            DUMP_MEM_OOM_ADJ[j]);
16131                    item.subitems = oomProcs[j];
16132                    oomMems.add(item);
16133                }
16134            }
16135
16136            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16137            if (!brief && !oomOnly && !isCompact) {
16138                pw.println();
16139                pw.println("Total PSS by process:");
16140                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16141                pw.println();
16142            }
16143            if (!isCompact) {
16144                pw.println("Total PSS by OOM adjustment:");
16145            }
16146            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16147            if (!brief && !oomOnly) {
16148                PrintWriter out = categoryPw != null ? categoryPw : pw;
16149                if (!isCompact) {
16150                    out.println();
16151                    out.println("Total PSS by category:");
16152                }
16153                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16154            }
16155            if (!isCompact) {
16156                pw.println();
16157            }
16158            MemInfoReader memInfo = new MemInfoReader();
16159            memInfo.readMemInfo();
16160            if (nativeProcTotalPss > 0) {
16161                synchronized (this) {
16162                    final long cachedKb = memInfo.getCachedSizeKb();
16163                    final long freeKb = memInfo.getFreeSizeKb();
16164                    final long zramKb = memInfo.getZramTotalSizeKb();
16165                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16166                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16167                            kernelKb*1024, nativeProcTotalPss*1024);
16168                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16169                            nativeProcTotalPss);
16170                }
16171            }
16172            if (!brief) {
16173                if (!isCompact) {
16174                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16175                    pw.print(" (status ");
16176                    switch (mLastMemoryLevel) {
16177                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16178                            pw.println("normal)");
16179                            break;
16180                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16181                            pw.println("moderate)");
16182                            break;
16183                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16184                            pw.println("low)");
16185                            break;
16186                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16187                            pw.println("critical)");
16188                            break;
16189                        default:
16190                            pw.print(mLastMemoryLevel);
16191                            pw.println(")");
16192                            break;
16193                    }
16194                    pw.print(" Free RAM: ");
16195                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16196                            + memInfo.getFreeSizeKb()));
16197                    pw.print(" (");
16198                    pw.print(stringifyKBSize(cachedPss));
16199                    pw.print(" cached pss + ");
16200                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16201                    pw.print(" cached kernel + ");
16202                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16203                    pw.println(" free)");
16204                } else {
16205                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16206                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16207                            + memInfo.getFreeSizeKb()); pw.print(",");
16208                    pw.println(totalPss - cachedPss);
16209                }
16210            }
16211            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16212                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16213                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16214            if (!isCompact) {
16215                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16216                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16217                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16218                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16219                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16220            } else {
16221                pw.print("lostram,"); pw.println(lostRAM);
16222            }
16223            if (!brief) {
16224                if (memInfo.getZramTotalSizeKb() != 0) {
16225                    if (!isCompact) {
16226                        pw.print("     ZRAM: ");
16227                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16228                                pw.print(" physical used for ");
16229                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16230                                        - memInfo.getSwapFreeSizeKb()));
16231                                pw.print(" in swap (");
16232                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16233                                pw.println(" total swap)");
16234                    } else {
16235                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16236                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16237                                pw.println(memInfo.getSwapFreeSizeKb());
16238                    }
16239                }
16240                final long[] ksm = getKsmInfo();
16241                if (!isCompact) {
16242                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16243                            || ksm[KSM_VOLATILE] != 0) {
16244                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16245                                pw.print(" saved from shared ");
16246                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16247                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16248                                pw.print(" unshared; ");
16249                                pw.print(stringifyKBSize(
16250                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16251                    }
16252                    pw.print("   Tuning: ");
16253                    pw.print(ActivityManager.staticGetMemoryClass());
16254                    pw.print(" (large ");
16255                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16256                    pw.print("), oom ");
16257                    pw.print(stringifySize(
16258                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16259                    pw.print(", restore limit ");
16260                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16261                    if (ActivityManager.isLowRamDeviceStatic()) {
16262                        pw.print(" (low-ram)");
16263                    }
16264                    if (ActivityManager.isHighEndGfx()) {
16265                        pw.print(" (high-end-gfx)");
16266                    }
16267                    pw.println();
16268                } else {
16269                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16270                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16271                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16272                    pw.print("tuning,");
16273                    pw.print(ActivityManager.staticGetMemoryClass());
16274                    pw.print(',');
16275                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16276                    pw.print(',');
16277                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16278                    if (ActivityManager.isLowRamDeviceStatic()) {
16279                        pw.print(",low-ram");
16280                    }
16281                    if (ActivityManager.isHighEndGfx()) {
16282                        pw.print(",high-end-gfx");
16283                    }
16284                    pw.println();
16285                }
16286            }
16287        }
16288    }
16289
16290    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16291            long memtrack, String name) {
16292        sb.append("  ");
16293        sb.append(ProcessList.makeOomAdjString(oomAdj));
16294        sb.append(' ');
16295        sb.append(ProcessList.makeProcStateString(procState));
16296        sb.append(' ');
16297        ProcessList.appendRamKb(sb, pss);
16298        sb.append(": ");
16299        sb.append(name);
16300        if (memtrack > 0) {
16301            sb.append(" (");
16302            sb.append(stringifyKBSize(memtrack));
16303            sb.append(" memtrack)");
16304        }
16305    }
16306
16307    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16308        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16309        sb.append(" (pid ");
16310        sb.append(mi.pid);
16311        sb.append(") ");
16312        sb.append(mi.adjType);
16313        sb.append('\n');
16314        if (mi.adjReason != null) {
16315            sb.append("                      ");
16316            sb.append(mi.adjReason);
16317            sb.append('\n');
16318        }
16319    }
16320
16321    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16322        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16323        for (int i=0, N=memInfos.size(); i<N; i++) {
16324            ProcessMemInfo mi = memInfos.get(i);
16325            infoMap.put(mi.pid, mi);
16326        }
16327        updateCpuStatsNow();
16328        long[] memtrackTmp = new long[1];
16329        synchronized (mProcessCpuTracker) {
16330            final int N = mProcessCpuTracker.countStats();
16331            for (int i=0; i<N; i++) {
16332                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16333                if (st.vsize > 0) {
16334                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16335                    if (pss > 0) {
16336                        if (infoMap.indexOfKey(st.pid) < 0) {
16337                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16338                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16339                            mi.pss = pss;
16340                            mi.memtrack = memtrackTmp[0];
16341                            memInfos.add(mi);
16342                        }
16343                    }
16344                }
16345            }
16346        }
16347
16348        long totalPss = 0;
16349        long totalMemtrack = 0;
16350        for (int i=0, N=memInfos.size(); i<N; i++) {
16351            ProcessMemInfo mi = memInfos.get(i);
16352            if (mi.pss == 0) {
16353                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16354                mi.memtrack = memtrackTmp[0];
16355            }
16356            totalPss += mi.pss;
16357            totalMemtrack += mi.memtrack;
16358        }
16359        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16360            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16361                if (lhs.oomAdj != rhs.oomAdj) {
16362                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16363                }
16364                if (lhs.pss != rhs.pss) {
16365                    return lhs.pss < rhs.pss ? 1 : -1;
16366                }
16367                return 0;
16368            }
16369        });
16370
16371        StringBuilder tag = new StringBuilder(128);
16372        StringBuilder stack = new StringBuilder(128);
16373        tag.append("Low on memory -- ");
16374        appendMemBucket(tag, totalPss, "total", false);
16375        appendMemBucket(stack, totalPss, "total", true);
16376
16377        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16378        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16379        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16380
16381        boolean firstLine = true;
16382        int lastOomAdj = Integer.MIN_VALUE;
16383        long extraNativeRam = 0;
16384        long extraNativeMemtrack = 0;
16385        long cachedPss = 0;
16386        for (int i=0, N=memInfos.size(); i<N; i++) {
16387            ProcessMemInfo mi = memInfos.get(i);
16388
16389            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16390                cachedPss += mi.pss;
16391            }
16392
16393            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16394                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16395                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16396                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16397                if (lastOomAdj != mi.oomAdj) {
16398                    lastOomAdj = mi.oomAdj;
16399                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16400                        tag.append(" / ");
16401                    }
16402                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16403                        if (firstLine) {
16404                            stack.append(":");
16405                            firstLine = false;
16406                        }
16407                        stack.append("\n\t at ");
16408                    } else {
16409                        stack.append("$");
16410                    }
16411                } else {
16412                    tag.append(" ");
16413                    stack.append("$");
16414                }
16415                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16416                    appendMemBucket(tag, mi.pss, mi.name, false);
16417                }
16418                appendMemBucket(stack, mi.pss, mi.name, true);
16419                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16420                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16421                    stack.append("(");
16422                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16423                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16424                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16425                            stack.append(":");
16426                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16427                        }
16428                    }
16429                    stack.append(")");
16430                }
16431            }
16432
16433            appendMemInfo(fullNativeBuilder, mi);
16434            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16435                // The short form only has native processes that are >= 512K.
16436                if (mi.pss >= 512) {
16437                    appendMemInfo(shortNativeBuilder, mi);
16438                } else {
16439                    extraNativeRam += mi.pss;
16440                    extraNativeMemtrack += mi.memtrack;
16441                }
16442            } else {
16443                // Short form has all other details, but if we have collected RAM
16444                // from smaller native processes let's dump a summary of that.
16445                if (extraNativeRam > 0) {
16446                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16447                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16448                    shortNativeBuilder.append('\n');
16449                    extraNativeRam = 0;
16450                }
16451                appendMemInfo(fullJavaBuilder, mi);
16452            }
16453        }
16454
16455        fullJavaBuilder.append("           ");
16456        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16457        fullJavaBuilder.append(": TOTAL");
16458        if (totalMemtrack > 0) {
16459            fullJavaBuilder.append(" (");
16460            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16461            fullJavaBuilder.append(" memtrack)");
16462        } else {
16463        }
16464        fullJavaBuilder.append("\n");
16465
16466        MemInfoReader memInfo = new MemInfoReader();
16467        memInfo.readMemInfo();
16468        final long[] infos = memInfo.getRawInfo();
16469
16470        StringBuilder memInfoBuilder = new StringBuilder(1024);
16471        Debug.getMemInfo(infos);
16472        memInfoBuilder.append("  MemInfo: ");
16473        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16474        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16475        memInfoBuilder.append(stringifyKBSize(
16476                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16477        memInfoBuilder.append(stringifyKBSize(
16478                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16479        memInfoBuilder.append(stringifyKBSize(
16480                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16481        memInfoBuilder.append("           ");
16482        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16483        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16484        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16485        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16486        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16487            memInfoBuilder.append("  ZRAM: ");
16488            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16489            memInfoBuilder.append(" RAM, ");
16490            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16491            memInfoBuilder.append(" swap total, ");
16492            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16493            memInfoBuilder.append(" swap free\n");
16494        }
16495        final long[] ksm = getKsmInfo();
16496        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16497                || ksm[KSM_VOLATILE] != 0) {
16498            memInfoBuilder.append("  KSM: ");
16499            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16500            memInfoBuilder.append(" saved from shared ");
16501            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16502            memInfoBuilder.append("\n       ");
16503            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16504            memInfoBuilder.append(" unshared; ");
16505            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16506            memInfoBuilder.append(" volatile\n");
16507        }
16508        memInfoBuilder.append("  Free RAM: ");
16509        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16510                + memInfo.getFreeSizeKb()));
16511        memInfoBuilder.append("\n");
16512        memInfoBuilder.append("  Used RAM: ");
16513        memInfoBuilder.append(stringifyKBSize(
16514                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16515        memInfoBuilder.append("\n");
16516        memInfoBuilder.append("  Lost RAM: ");
16517        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16518                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16519                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16520        memInfoBuilder.append("\n");
16521        Slog.i(TAG, "Low on memory:");
16522        Slog.i(TAG, shortNativeBuilder.toString());
16523        Slog.i(TAG, fullJavaBuilder.toString());
16524        Slog.i(TAG, memInfoBuilder.toString());
16525
16526        StringBuilder dropBuilder = new StringBuilder(1024);
16527        /*
16528        StringWriter oomSw = new StringWriter();
16529        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16530        StringWriter catSw = new StringWriter();
16531        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16532        String[] emptyArgs = new String[] { };
16533        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16534        oomPw.flush();
16535        String oomString = oomSw.toString();
16536        */
16537        dropBuilder.append("Low on memory:");
16538        dropBuilder.append(stack);
16539        dropBuilder.append('\n');
16540        dropBuilder.append(fullNativeBuilder);
16541        dropBuilder.append(fullJavaBuilder);
16542        dropBuilder.append('\n');
16543        dropBuilder.append(memInfoBuilder);
16544        dropBuilder.append('\n');
16545        /*
16546        dropBuilder.append(oomString);
16547        dropBuilder.append('\n');
16548        */
16549        StringWriter catSw = new StringWriter();
16550        synchronized (ActivityManagerService.this) {
16551            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16552            String[] emptyArgs = new String[] { };
16553            catPw.println();
16554            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16555            catPw.println();
16556            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16557                    false, null).dumpLocked();
16558            catPw.println();
16559            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16560            catPw.flush();
16561        }
16562        dropBuilder.append(catSw.toString());
16563        addErrorToDropBox("lowmem", null, "system_server", null,
16564                null, tag.toString(), dropBuilder.toString(), null, null);
16565        //Slog.i(TAG, "Sent to dropbox:");
16566        //Slog.i(TAG, dropBuilder.toString());
16567        synchronized (ActivityManagerService.this) {
16568            long now = SystemClock.uptimeMillis();
16569            if (mLastMemUsageReportTime < now) {
16570                mLastMemUsageReportTime = now;
16571            }
16572        }
16573    }
16574
16575    /**
16576     * Searches array of arguments for the specified string
16577     * @param args array of argument strings
16578     * @param value value to search for
16579     * @return true if the value is contained in the array
16580     */
16581    private static boolean scanArgs(String[] args, String value) {
16582        if (args != null) {
16583            for (String arg : args) {
16584                if (value.equals(arg)) {
16585                    return true;
16586                }
16587            }
16588        }
16589        return false;
16590    }
16591
16592    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16593            ContentProviderRecord cpr, boolean always) {
16594        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16595
16596        if (!inLaunching || always) {
16597            synchronized (cpr) {
16598                cpr.launchingApp = null;
16599                cpr.notifyAll();
16600            }
16601            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16602            String names[] = cpr.info.authority.split(";");
16603            for (int j = 0; j < names.length; j++) {
16604                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16605            }
16606        }
16607
16608        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16609            ContentProviderConnection conn = cpr.connections.get(i);
16610            if (conn.waiting) {
16611                // If this connection is waiting for the provider, then we don't
16612                // need to mess with its process unless we are always removing
16613                // or for some reason the provider is not currently launching.
16614                if (inLaunching && !always) {
16615                    continue;
16616                }
16617            }
16618            ProcessRecord capp = conn.client;
16619            conn.dead = true;
16620            if (conn.stableCount > 0) {
16621                if (!capp.persistent && capp.thread != null
16622                        && capp.pid != 0
16623                        && capp.pid != MY_PID) {
16624                    capp.kill("depends on provider "
16625                            + cpr.name.flattenToShortString()
16626                            + " in dying proc " + (proc != null ? proc.processName : "??")
16627                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16628                }
16629            } else if (capp.thread != null && conn.provider.provider != null) {
16630                try {
16631                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16632                } catch (RemoteException e) {
16633                }
16634                // In the protocol here, we don't expect the client to correctly
16635                // clean up this connection, we'll just remove it.
16636                cpr.connections.remove(i);
16637                if (conn.client.conProviders.remove(conn)) {
16638                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16639                }
16640            }
16641        }
16642
16643        if (inLaunching && always) {
16644            mLaunchingProviders.remove(cpr);
16645        }
16646        return inLaunching;
16647    }
16648
16649    /**
16650     * Main code for cleaning up a process when it has gone away.  This is
16651     * called both as a result of the process dying, or directly when stopping
16652     * a process when running in single process mode.
16653     *
16654     * @return Returns true if the given process has been restarted, so the
16655     * app that was passed in must remain on the process lists.
16656     */
16657    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16658            boolean restarting, boolean allowRestart, int index) {
16659        if (index >= 0) {
16660            removeLruProcessLocked(app);
16661            ProcessList.remove(app.pid);
16662        }
16663
16664        mProcessesToGc.remove(app);
16665        mPendingPssProcesses.remove(app);
16666
16667        // Dismiss any open dialogs.
16668        if (app.crashDialog != null && !app.forceCrashReport) {
16669            app.crashDialog.dismiss();
16670            app.crashDialog = null;
16671        }
16672        if (app.anrDialog != null) {
16673            app.anrDialog.dismiss();
16674            app.anrDialog = null;
16675        }
16676        if (app.waitDialog != null) {
16677            app.waitDialog.dismiss();
16678            app.waitDialog = null;
16679        }
16680
16681        app.crashing = false;
16682        app.notResponding = false;
16683
16684        app.resetPackageList(mProcessStats);
16685        app.unlinkDeathRecipient();
16686        app.makeInactive(mProcessStats);
16687        app.waitingToKill = null;
16688        app.forcingToForeground = null;
16689        updateProcessForegroundLocked(app, false, false);
16690        app.foregroundActivities = false;
16691        app.hasShownUi = false;
16692        app.treatLikeActivity = false;
16693        app.hasAboveClient = false;
16694        app.hasClientActivities = false;
16695
16696        mServices.killServicesLocked(app, allowRestart);
16697
16698        boolean restart = false;
16699
16700        // Remove published content providers.
16701        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16702            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16703            final boolean always = app.bad || !allowRestart;
16704            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16705            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16706                // We left the provider in the launching list, need to
16707                // restart it.
16708                restart = true;
16709            }
16710
16711            cpr.provider = null;
16712            cpr.proc = null;
16713        }
16714        app.pubProviders.clear();
16715
16716        // Take care of any launching providers waiting for this process.
16717        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16718            restart = true;
16719        }
16720
16721        // Unregister from connected content providers.
16722        if (!app.conProviders.isEmpty()) {
16723            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16724                ContentProviderConnection conn = app.conProviders.get(i);
16725                conn.provider.connections.remove(conn);
16726                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16727                        conn.provider.name);
16728            }
16729            app.conProviders.clear();
16730        }
16731
16732        // At this point there may be remaining entries in mLaunchingProviders
16733        // where we were the only one waiting, so they are no longer of use.
16734        // Look for these and clean up if found.
16735        // XXX Commented out for now.  Trying to figure out a way to reproduce
16736        // the actual situation to identify what is actually going on.
16737        if (false) {
16738            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16739                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16740                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16741                    synchronized (cpr) {
16742                        cpr.launchingApp = null;
16743                        cpr.notifyAll();
16744                    }
16745                }
16746            }
16747        }
16748
16749        skipCurrentReceiverLocked(app);
16750
16751        // Unregister any receivers.
16752        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16753            removeReceiverLocked(app.receivers.valueAt(i));
16754        }
16755        app.receivers.clear();
16756
16757        // If the app is undergoing backup, tell the backup manager about it
16758        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16759            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16760                    + mBackupTarget.appInfo + " died during backup");
16761            try {
16762                IBackupManager bm = IBackupManager.Stub.asInterface(
16763                        ServiceManager.getService(Context.BACKUP_SERVICE));
16764                bm.agentDisconnected(app.info.packageName);
16765            } catch (RemoteException e) {
16766                // can't happen; backup manager is local
16767            }
16768        }
16769
16770        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16771            ProcessChangeItem item = mPendingProcessChanges.get(i);
16772            if (item.pid == app.pid) {
16773                mPendingProcessChanges.remove(i);
16774                mAvailProcessChanges.add(item);
16775            }
16776        }
16777        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16778                null).sendToTarget();
16779
16780        // If the caller is restarting this app, then leave it in its
16781        // current lists and let the caller take care of it.
16782        if (restarting) {
16783            return false;
16784        }
16785
16786        if (!app.persistent || app.isolated) {
16787            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16788                    "Removing non-persistent process during cleanup: " + app);
16789            removeProcessNameLocked(app.processName, app.uid);
16790            if (mHeavyWeightProcess == app) {
16791                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16792                        mHeavyWeightProcess.userId, 0));
16793                mHeavyWeightProcess = null;
16794            }
16795        } else if (!app.removed) {
16796            // This app is persistent, so we need to keep its record around.
16797            // If it is not already on the pending app list, add it there
16798            // and start a new process for it.
16799            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16800                mPersistentStartingProcesses.add(app);
16801                restart = true;
16802            }
16803        }
16804        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16805                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16806        mProcessesOnHold.remove(app);
16807
16808        if (app == mHomeProcess) {
16809            mHomeProcess = null;
16810        }
16811        if (app == mPreviousProcess) {
16812            mPreviousProcess = null;
16813        }
16814
16815        if (restart && !app.isolated) {
16816            // We have components that still need to be running in the
16817            // process, so re-launch it.
16818            if (index < 0) {
16819                ProcessList.remove(app.pid);
16820            }
16821            addProcessNameLocked(app);
16822            startProcessLocked(app, "restart", app.processName);
16823            return true;
16824        } else if (app.pid > 0 && app.pid != MY_PID) {
16825            // Goodbye!
16826            boolean removed;
16827            synchronized (mPidsSelfLocked) {
16828                mPidsSelfLocked.remove(app.pid);
16829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16830            }
16831            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16832            if (app.isolated) {
16833                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16834            }
16835            app.setPid(0);
16836        }
16837        return false;
16838    }
16839
16840    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16841        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16842            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16843            if (cpr.launchingApp == app) {
16844                return true;
16845            }
16846        }
16847        return false;
16848    }
16849
16850    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16851        // Look through the content providers we are waiting to have launched,
16852        // and if any run in this process then either schedule a restart of
16853        // the process or kill the client waiting for it if this process has
16854        // gone bad.
16855        boolean restart = false;
16856        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16857            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16858            if (cpr.launchingApp == app) {
16859                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16860                    restart = true;
16861                } else {
16862                    removeDyingProviderLocked(app, cpr, true);
16863                }
16864            }
16865        }
16866        return restart;
16867    }
16868
16869    // =========================================================
16870    // SERVICES
16871    // =========================================================
16872
16873    @Override
16874    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16875            int flags) {
16876        enforceNotIsolatedCaller("getServices");
16877        synchronized (this) {
16878            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16879        }
16880    }
16881
16882    @Override
16883    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16884        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16885        synchronized (this) {
16886            return mServices.getRunningServiceControlPanelLocked(name);
16887        }
16888    }
16889
16890    @Override
16891    public ComponentName startService(IApplicationThread caller, Intent service,
16892            String resolvedType, String callingPackage, int userId)
16893            throws TransactionTooLargeException {
16894        enforceNotIsolatedCaller("startService");
16895        // Refuse possible leaked file descriptors
16896        if (service != null && service.hasFileDescriptors() == true) {
16897            throw new IllegalArgumentException("File descriptors passed in Intent");
16898        }
16899
16900        if (callingPackage == null) {
16901            throw new IllegalArgumentException("callingPackage cannot be null");
16902        }
16903
16904        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16905                "startService: " + service + " type=" + resolvedType);
16906        synchronized(this) {
16907            final int callingPid = Binder.getCallingPid();
16908            final int callingUid = Binder.getCallingUid();
16909            final long origId = Binder.clearCallingIdentity();
16910            ComponentName res = mServices.startServiceLocked(caller, service,
16911                    resolvedType, callingPid, callingUid, callingPackage, userId);
16912            Binder.restoreCallingIdentity(origId);
16913            return res;
16914        }
16915    }
16916
16917    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16918            String callingPackage, int userId)
16919            throws TransactionTooLargeException {
16920        synchronized(this) {
16921            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16922                    "startServiceInPackage: " + service + " type=" + resolvedType);
16923            final long origId = Binder.clearCallingIdentity();
16924            ComponentName res = mServices.startServiceLocked(null, service,
16925                    resolvedType, -1, uid, callingPackage, userId);
16926            Binder.restoreCallingIdentity(origId);
16927            return res;
16928        }
16929    }
16930
16931    @Override
16932    public int stopService(IApplicationThread caller, Intent service,
16933            String resolvedType, int userId) {
16934        enforceNotIsolatedCaller("stopService");
16935        // Refuse possible leaked file descriptors
16936        if (service != null && service.hasFileDescriptors() == true) {
16937            throw new IllegalArgumentException("File descriptors passed in Intent");
16938        }
16939
16940        synchronized(this) {
16941            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16942        }
16943    }
16944
16945    @Override
16946    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16947        enforceNotIsolatedCaller("peekService");
16948        // Refuse possible leaked file descriptors
16949        if (service != null && service.hasFileDescriptors() == true) {
16950            throw new IllegalArgumentException("File descriptors passed in Intent");
16951        }
16952
16953        if (callingPackage == null) {
16954            throw new IllegalArgumentException("callingPackage cannot be null");
16955        }
16956
16957        synchronized(this) {
16958            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16959        }
16960    }
16961
16962    @Override
16963    public boolean stopServiceToken(ComponentName className, IBinder token,
16964            int startId) {
16965        synchronized(this) {
16966            return mServices.stopServiceTokenLocked(className, token, startId);
16967        }
16968    }
16969
16970    @Override
16971    public void setServiceForeground(ComponentName className, IBinder token,
16972            int id, Notification notification, int flags) {
16973        synchronized(this) {
16974            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16975        }
16976    }
16977
16978    @Override
16979    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16980            boolean requireFull, String name, String callerPackage) {
16981        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16982                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16983    }
16984
16985    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16986            String className, int flags) {
16987        boolean result = false;
16988        // For apps that don't have pre-defined UIDs, check for permission
16989        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16990            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16991                if (ActivityManager.checkUidPermission(
16992                        INTERACT_ACROSS_USERS,
16993                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16994                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16995                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16996                            + " requests FLAG_SINGLE_USER, but app does not hold "
16997                            + INTERACT_ACROSS_USERS;
16998                    Slog.w(TAG, msg);
16999                    throw new SecurityException(msg);
17000                }
17001                // Permission passed
17002                result = true;
17003            }
17004        } else if ("system".equals(componentProcessName)) {
17005            result = true;
17006        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17007            // Phone app and persistent apps are allowed to export singleuser providers.
17008            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17009                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17010        }
17011        if (DEBUG_MU) Slog.v(TAG_MU,
17012                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17013                + Integer.toHexString(flags) + ") = " + result);
17014        return result;
17015    }
17016
17017    /**
17018     * Checks to see if the caller is in the same app as the singleton
17019     * component, or the component is in a special app. It allows special apps
17020     * to export singleton components but prevents exporting singleton
17021     * components for regular apps.
17022     */
17023    boolean isValidSingletonCall(int callingUid, int componentUid) {
17024        int componentAppId = UserHandle.getAppId(componentUid);
17025        return UserHandle.isSameApp(callingUid, componentUid)
17026                || componentAppId == Process.SYSTEM_UID
17027                || componentAppId == Process.PHONE_UID
17028                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17029                        == PackageManager.PERMISSION_GRANTED;
17030    }
17031
17032    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17033            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17034            int userId) throws TransactionTooLargeException {
17035        enforceNotIsolatedCaller("bindService");
17036
17037        // Refuse possible leaked file descriptors
17038        if (service != null && service.hasFileDescriptors() == true) {
17039            throw new IllegalArgumentException("File descriptors passed in Intent");
17040        }
17041
17042        if (callingPackage == null) {
17043            throw new IllegalArgumentException("callingPackage cannot be null");
17044        }
17045
17046        synchronized(this) {
17047            return mServices.bindServiceLocked(caller, token, service,
17048                    resolvedType, connection, flags, callingPackage, userId);
17049        }
17050    }
17051
17052    public boolean unbindService(IServiceConnection connection) {
17053        synchronized (this) {
17054            return mServices.unbindServiceLocked(connection);
17055        }
17056    }
17057
17058    public void publishService(IBinder token, Intent intent, IBinder service) {
17059        // Refuse possible leaked file descriptors
17060        if (intent != null && intent.hasFileDescriptors() == true) {
17061            throw new IllegalArgumentException("File descriptors passed in Intent");
17062        }
17063
17064        synchronized(this) {
17065            if (!(token instanceof ServiceRecord)) {
17066                throw new IllegalArgumentException("Invalid service token");
17067            }
17068            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17069        }
17070    }
17071
17072    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17073        // Refuse possible leaked file descriptors
17074        if (intent != null && intent.hasFileDescriptors() == true) {
17075            throw new IllegalArgumentException("File descriptors passed in Intent");
17076        }
17077
17078        synchronized(this) {
17079            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17080        }
17081    }
17082
17083    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17084        synchronized(this) {
17085            if (!(token instanceof ServiceRecord)) {
17086                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17087                throw new IllegalArgumentException("Invalid service token");
17088            }
17089            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17090        }
17091    }
17092
17093    // =========================================================
17094    // BACKUP AND RESTORE
17095    // =========================================================
17096
17097    // Cause the target app to be launched if necessary and its backup agent
17098    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17099    // activity manager to announce its creation.
17100    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17101        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17102        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17103
17104        IPackageManager pm = AppGlobals.getPackageManager();
17105        ApplicationInfo app = null;
17106        try {
17107            app = pm.getApplicationInfo(packageName, 0, userId);
17108        } catch (RemoteException e) {
17109            // can't happen; package manager is process-local
17110        }
17111        if (app == null) {
17112            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17113            return false;
17114        }
17115
17116        synchronized(this) {
17117            // !!! TODO: currently no check here that we're already bound
17118            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17119            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17120            synchronized (stats) {
17121                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17122            }
17123
17124            // Backup agent is now in use, its package can't be stopped.
17125            try {
17126                AppGlobals.getPackageManager().setPackageStoppedState(
17127                        app.packageName, false, UserHandle.getUserId(app.uid));
17128            } catch (RemoteException e) {
17129            } catch (IllegalArgumentException e) {
17130                Slog.w(TAG, "Failed trying to unstop package "
17131                        + app.packageName + ": " + e);
17132            }
17133
17134            BackupRecord r = new BackupRecord(ss, app, backupMode);
17135            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17136                    ? new ComponentName(app.packageName, app.backupAgentName)
17137                    : new ComponentName("android", "FullBackupAgent");
17138            // startProcessLocked() returns existing proc's record if it's already running
17139            ProcessRecord proc = startProcessLocked(app.processName, app,
17140                    false, 0, "backup", hostingName, false, false, false);
17141            if (proc == null) {
17142                Slog.e(TAG, "Unable to start backup agent process " + r);
17143                return false;
17144            }
17145
17146            // If the app is a regular app (uid >= 10000) and not the system server or phone
17147            // process, etc, then mark it as being in full backup so that certain calls to the
17148            // process can be blocked. This is not reset to false anywhere because we kill the
17149            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17150            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17151                proc.inFullBackup = true;
17152            }
17153            r.app = proc;
17154            mBackupTarget = r;
17155            mBackupAppName = app.packageName;
17156
17157            // Try not to kill the process during backup
17158            updateOomAdjLocked(proc);
17159
17160            // If the process is already attached, schedule the creation of the backup agent now.
17161            // If it is not yet live, this will be done when it attaches to the framework.
17162            if (proc.thread != null) {
17163                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17164                try {
17165                    proc.thread.scheduleCreateBackupAgent(app,
17166                            compatibilityInfoForPackageLocked(app), backupMode);
17167                } catch (RemoteException e) {
17168                    // Will time out on the backup manager side
17169                }
17170            } else {
17171                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17172            }
17173            // Invariants: at this point, the target app process exists and the application
17174            // is either already running or in the process of coming up.  mBackupTarget and
17175            // mBackupAppName describe the app, so that when it binds back to the AM we
17176            // know that it's scheduled for a backup-agent operation.
17177        }
17178
17179        return true;
17180    }
17181
17182    @Override
17183    public void clearPendingBackup() {
17184        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17185        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17186
17187        synchronized (this) {
17188            mBackupTarget = null;
17189            mBackupAppName = null;
17190        }
17191    }
17192
17193    // A backup agent has just come up
17194    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17195        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17196                + " = " + agent);
17197
17198        synchronized(this) {
17199            if (!agentPackageName.equals(mBackupAppName)) {
17200                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17201                return;
17202            }
17203        }
17204
17205        long oldIdent = Binder.clearCallingIdentity();
17206        try {
17207            IBackupManager bm = IBackupManager.Stub.asInterface(
17208                    ServiceManager.getService(Context.BACKUP_SERVICE));
17209            bm.agentConnected(agentPackageName, agent);
17210        } catch (RemoteException e) {
17211            // can't happen; the backup manager service is local
17212        } catch (Exception e) {
17213            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17214            e.printStackTrace();
17215        } finally {
17216            Binder.restoreCallingIdentity(oldIdent);
17217        }
17218    }
17219
17220    // done with this agent
17221    public void unbindBackupAgent(ApplicationInfo appInfo) {
17222        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17223        if (appInfo == null) {
17224            Slog.w(TAG, "unbind backup agent for null app");
17225            return;
17226        }
17227
17228        synchronized(this) {
17229            try {
17230                if (mBackupAppName == null) {
17231                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17232                    return;
17233                }
17234
17235                if (!mBackupAppName.equals(appInfo.packageName)) {
17236                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17237                    return;
17238                }
17239
17240                // Not backing this app up any more; reset its OOM adjustment
17241                final ProcessRecord proc = mBackupTarget.app;
17242                updateOomAdjLocked(proc);
17243
17244                // If the app crashed during backup, 'thread' will be null here
17245                if (proc.thread != null) {
17246                    try {
17247                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17248                                compatibilityInfoForPackageLocked(appInfo));
17249                    } catch (Exception e) {
17250                        Slog.e(TAG, "Exception when unbinding backup agent:");
17251                        e.printStackTrace();
17252                    }
17253                }
17254            } finally {
17255                mBackupTarget = null;
17256                mBackupAppName = null;
17257            }
17258        }
17259    }
17260    // =========================================================
17261    // BROADCASTS
17262    // =========================================================
17263
17264    boolean isPendingBroadcastProcessLocked(int pid) {
17265        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17266                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17267    }
17268
17269    void skipPendingBroadcastLocked(int pid) {
17270            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17271            for (BroadcastQueue queue : mBroadcastQueues) {
17272                queue.skipPendingBroadcastLocked(pid);
17273            }
17274    }
17275
17276    // The app just attached; send any pending broadcasts that it should receive
17277    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17278        boolean didSomething = false;
17279        for (BroadcastQueue queue : mBroadcastQueues) {
17280            didSomething |= queue.sendPendingBroadcastsLocked(app);
17281        }
17282        return didSomething;
17283    }
17284
17285    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17286            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17287        enforceNotIsolatedCaller("registerReceiver");
17288        ArrayList<Intent> stickyIntents = null;
17289        ProcessRecord callerApp = null;
17290        int callingUid;
17291        int callingPid;
17292        synchronized(this) {
17293            if (caller != null) {
17294                callerApp = getRecordForAppLocked(caller);
17295                if (callerApp == null) {
17296                    throw new SecurityException(
17297                            "Unable to find app for caller " + caller
17298                            + " (pid=" + Binder.getCallingPid()
17299                            + ") when registering receiver " + receiver);
17300                }
17301                if (callerApp.info.uid != Process.SYSTEM_UID &&
17302                        !callerApp.pkgList.containsKey(callerPackage) &&
17303                        !"android".equals(callerPackage)) {
17304                    throw new SecurityException("Given caller package " + callerPackage
17305                            + " is not running in process " + callerApp);
17306                }
17307                callingUid = callerApp.info.uid;
17308                callingPid = callerApp.pid;
17309            } else {
17310                callerPackage = null;
17311                callingUid = Binder.getCallingUid();
17312                callingPid = Binder.getCallingPid();
17313            }
17314
17315            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17316                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17317
17318            Iterator<String> actions = filter.actionsIterator();
17319            if (actions == null) {
17320                ArrayList<String> noAction = new ArrayList<String>(1);
17321                noAction.add(null);
17322                actions = noAction.iterator();
17323            }
17324
17325            // Collect stickies of users
17326            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17327            while (actions.hasNext()) {
17328                String action = actions.next();
17329                for (int id : userIds) {
17330                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17331                    if (stickies != null) {
17332                        ArrayList<Intent> intents = stickies.get(action);
17333                        if (intents != null) {
17334                            if (stickyIntents == null) {
17335                                stickyIntents = new ArrayList<Intent>();
17336                            }
17337                            stickyIntents.addAll(intents);
17338                        }
17339                    }
17340                }
17341            }
17342        }
17343
17344        ArrayList<Intent> allSticky = null;
17345        if (stickyIntents != null) {
17346            final ContentResolver resolver = mContext.getContentResolver();
17347            // Look for any matching sticky broadcasts...
17348            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17349                Intent intent = stickyIntents.get(i);
17350                // If intent has scheme "content", it will need to acccess
17351                // provider that needs to lock mProviderMap in ActivityThread
17352                // and also it may need to wait application response, so we
17353                // cannot lock ActivityManagerService here.
17354                if (filter.match(resolver, intent, true, TAG) >= 0) {
17355                    if (allSticky == null) {
17356                        allSticky = new ArrayList<Intent>();
17357                    }
17358                    allSticky.add(intent);
17359                }
17360            }
17361        }
17362
17363        // The first sticky in the list is returned directly back to the client.
17364        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17365        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17366        if (receiver == null) {
17367            return sticky;
17368        }
17369
17370        synchronized (this) {
17371            if (callerApp != null && (callerApp.thread == null
17372                    || callerApp.thread.asBinder() != caller.asBinder())) {
17373                // Original caller already died
17374                return null;
17375            }
17376            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17377            if (rl == null) {
17378                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17379                        userId, receiver);
17380                if (rl.app != null) {
17381                    rl.app.receivers.add(rl);
17382                } else {
17383                    try {
17384                        receiver.asBinder().linkToDeath(rl, 0);
17385                    } catch (RemoteException e) {
17386                        return sticky;
17387                    }
17388                    rl.linkedToDeath = true;
17389                }
17390                mRegisteredReceivers.put(receiver.asBinder(), rl);
17391            } else if (rl.uid != callingUid) {
17392                throw new IllegalArgumentException(
17393                        "Receiver requested to register for uid " + callingUid
17394                        + " was previously registered for uid " + rl.uid);
17395            } else if (rl.pid != callingPid) {
17396                throw new IllegalArgumentException(
17397                        "Receiver requested to register for pid " + callingPid
17398                        + " was previously registered for pid " + rl.pid);
17399            } else if (rl.userId != userId) {
17400                throw new IllegalArgumentException(
17401                        "Receiver requested to register for user " + userId
17402                        + " was previously registered for user " + rl.userId);
17403            }
17404            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17405                    permission, callingUid, userId);
17406            rl.add(bf);
17407            if (!bf.debugCheck()) {
17408                Slog.w(TAG, "==> For Dynamic broadcast");
17409            }
17410            mReceiverResolver.addFilter(bf);
17411
17412            // Enqueue broadcasts for all existing stickies that match
17413            // this filter.
17414            if (allSticky != null) {
17415                ArrayList receivers = new ArrayList();
17416                receivers.add(bf);
17417
17418                final int stickyCount = allSticky.size();
17419                for (int i = 0; i < stickyCount; i++) {
17420                    Intent intent = allSticky.get(i);
17421                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17422                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17423                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17424                            null, 0, null, null, false, true, true, -1);
17425                    queue.enqueueParallelBroadcastLocked(r);
17426                    queue.scheduleBroadcastsLocked();
17427                }
17428            }
17429
17430            return sticky;
17431        }
17432    }
17433
17434    public void unregisterReceiver(IIntentReceiver receiver) {
17435        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17436
17437        final long origId = Binder.clearCallingIdentity();
17438        try {
17439            boolean doTrim = false;
17440
17441            synchronized(this) {
17442                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17443                if (rl != null) {
17444                    final BroadcastRecord r = rl.curBroadcast;
17445                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17446                        final boolean doNext = r.queue.finishReceiverLocked(
17447                                r, r.resultCode, r.resultData, r.resultExtras,
17448                                r.resultAbort, false);
17449                        if (doNext) {
17450                            doTrim = true;
17451                            r.queue.processNextBroadcast(false);
17452                        }
17453                    }
17454
17455                    if (rl.app != null) {
17456                        rl.app.receivers.remove(rl);
17457                    }
17458                    removeReceiverLocked(rl);
17459                    if (rl.linkedToDeath) {
17460                        rl.linkedToDeath = false;
17461                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17462                    }
17463                }
17464            }
17465
17466            // If we actually concluded any broadcasts, we might now be able
17467            // to trim the recipients' apps from our working set
17468            if (doTrim) {
17469                trimApplications();
17470                return;
17471            }
17472
17473        } finally {
17474            Binder.restoreCallingIdentity(origId);
17475        }
17476    }
17477
17478    void removeReceiverLocked(ReceiverList rl) {
17479        mRegisteredReceivers.remove(rl.receiver.asBinder());
17480        for (int i = rl.size() - 1; i >= 0; i--) {
17481            mReceiverResolver.removeFilter(rl.get(i));
17482        }
17483    }
17484
17485    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17486        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17487            ProcessRecord r = mLruProcesses.get(i);
17488            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17489                try {
17490                    r.thread.dispatchPackageBroadcast(cmd, packages);
17491                } catch (RemoteException ex) {
17492                }
17493            }
17494        }
17495    }
17496
17497    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17498            int callingUid, int[] users) {
17499        // TODO: come back and remove this assumption to triage all broadcasts
17500        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17501
17502        List<ResolveInfo> receivers = null;
17503        try {
17504            HashSet<ComponentName> singleUserReceivers = null;
17505            boolean scannedFirstReceivers = false;
17506            for (int user : users) {
17507                // Skip users that have Shell restrictions, with exception of always permitted
17508                // Shell broadcasts
17509                if (callingUid == Process.SHELL_UID
17510                        && mUserController.hasUserRestriction(
17511                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17512                        && !isPermittedShellBroadcast(intent)) {
17513                    continue;
17514                }
17515                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17516                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17517                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17518                    // If this is not the system user, we need to check for
17519                    // any receivers that should be filtered out.
17520                    for (int i=0; i<newReceivers.size(); i++) {
17521                        ResolveInfo ri = newReceivers.get(i);
17522                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17523                            newReceivers.remove(i);
17524                            i--;
17525                        }
17526                    }
17527                }
17528                if (newReceivers != null && newReceivers.size() == 0) {
17529                    newReceivers = null;
17530                }
17531                if (receivers == null) {
17532                    receivers = newReceivers;
17533                } else if (newReceivers != null) {
17534                    // We need to concatenate the additional receivers
17535                    // found with what we have do far.  This would be easy,
17536                    // but we also need to de-dup any receivers that are
17537                    // singleUser.
17538                    if (!scannedFirstReceivers) {
17539                        // Collect any single user receivers we had already retrieved.
17540                        scannedFirstReceivers = true;
17541                        for (int i=0; i<receivers.size(); i++) {
17542                            ResolveInfo ri = receivers.get(i);
17543                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17544                                ComponentName cn = new ComponentName(
17545                                        ri.activityInfo.packageName, ri.activityInfo.name);
17546                                if (singleUserReceivers == null) {
17547                                    singleUserReceivers = new HashSet<ComponentName>();
17548                                }
17549                                singleUserReceivers.add(cn);
17550                            }
17551                        }
17552                    }
17553                    // Add the new results to the existing results, tracking
17554                    // and de-dupping single user receivers.
17555                    for (int i=0; i<newReceivers.size(); i++) {
17556                        ResolveInfo ri = newReceivers.get(i);
17557                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17558                            ComponentName cn = new ComponentName(
17559                                    ri.activityInfo.packageName, ri.activityInfo.name);
17560                            if (singleUserReceivers == null) {
17561                                singleUserReceivers = new HashSet<ComponentName>();
17562                            }
17563                            if (!singleUserReceivers.contains(cn)) {
17564                                singleUserReceivers.add(cn);
17565                                receivers.add(ri);
17566                            }
17567                        } else {
17568                            receivers.add(ri);
17569                        }
17570                    }
17571                }
17572            }
17573        } catch (RemoteException ex) {
17574            // pm is in same process, this will never happen.
17575        }
17576        return receivers;
17577    }
17578
17579    private boolean isPermittedShellBroadcast(Intent intent) {
17580        // remote bugreport should always be allowed to be taken
17581        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17582    }
17583
17584    final int broadcastIntentLocked(ProcessRecord callerApp,
17585            String callerPackage, Intent intent, String resolvedType,
17586            IIntentReceiver resultTo, int resultCode, String resultData,
17587            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17588            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17589        intent = new Intent(intent);
17590
17591        // By default broadcasts do not go to stopped apps.
17592        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17593
17594        // If we have not finished booting, don't allow this to launch new processes.
17595        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17596            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17597        }
17598
17599        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17600                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17601                + " ordered=" + ordered + " userid=" + userId);
17602        if ((resultTo != null) && !ordered) {
17603            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17604        }
17605
17606        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17607                ALLOW_NON_FULL, "broadcast", callerPackage);
17608
17609        // Make sure that the user who is receiving this broadcast is running.
17610        // If not, we will just skip it. Make an exception for shutdown broadcasts
17611        // and upgrade steps.
17612
17613        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17614            if ((callingUid != Process.SYSTEM_UID
17615                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17616                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17617                Slog.w(TAG, "Skipping broadcast of " + intent
17618                        + ": user " + userId + " is stopped");
17619                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17620            }
17621        }
17622
17623        BroadcastOptions brOptions = null;
17624        if (bOptions != null) {
17625            brOptions = new BroadcastOptions(bOptions);
17626            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17627                // See if the caller is allowed to do this.  Note we are checking against
17628                // the actual real caller (not whoever provided the operation as say a
17629                // PendingIntent), because that who is actually supplied the arguments.
17630                if (checkComponentPermission(
17631                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17632                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17633                        != PackageManager.PERMISSION_GRANTED) {
17634                    String msg = "Permission Denial: " + intent.getAction()
17635                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17636                            + ", uid=" + callingUid + ")"
17637                            + " requires "
17638                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17639                    Slog.w(TAG, msg);
17640                    throw new SecurityException(msg);
17641                }
17642            }
17643        }
17644
17645        // Verify that protected broadcasts are only being sent by system code,
17646        // and that system code is only sending protected broadcasts.
17647        final String action = intent.getAction();
17648        final boolean isProtectedBroadcast;
17649        try {
17650            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17651        } catch (RemoteException e) {
17652            Slog.w(TAG, "Remote exception", e);
17653            return ActivityManager.BROADCAST_SUCCESS;
17654        }
17655
17656        final boolean isCallerSystem;
17657        switch (UserHandle.getAppId(callingUid)) {
17658            case Process.ROOT_UID:
17659            case Process.SYSTEM_UID:
17660            case Process.PHONE_UID:
17661            case Process.BLUETOOTH_UID:
17662            case Process.NFC_UID:
17663                isCallerSystem = true;
17664                break;
17665            default:
17666                isCallerSystem = (callerApp != null) && callerApp.persistent;
17667                break;
17668        }
17669
17670        if (isCallerSystem) {
17671            if (isProtectedBroadcast
17672                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17673                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17674                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17675                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17676                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17677                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17678                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17679                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17680                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17681                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17682                // Broadcast is either protected, or it's a public action that
17683                // we've relaxed, so it's fine for system internals to send.
17684            } else {
17685                // The vast majority of broadcasts sent from system internals
17686                // should be protected to avoid security holes, so yell loudly
17687                // to ensure we examine these cases.
17688                if (callerApp != null) {
17689                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17690                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17691                            new Throwable());
17692                } else {
17693                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17694                            + " from system uid " + UserHandle.formatUid(callingUid)
17695                            + " pkg " + callerPackage,
17696                            new Throwable());
17697                }
17698            }
17699
17700        } else {
17701            if (isProtectedBroadcast) {
17702                String msg = "Permission Denial: not allowed to send broadcast "
17703                        + action + " from pid="
17704                        + callingPid + ", uid=" + callingUid;
17705                Slog.w(TAG, msg);
17706                throw new SecurityException(msg);
17707
17708            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17709                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17710                // Special case for compatibility: we don't want apps to send this,
17711                // but historically it has not been protected and apps may be using it
17712                // to poke their own app widget.  So, instead of making it protected,
17713                // just limit it to the caller.
17714                if (callerPackage == null) {
17715                    String msg = "Permission Denial: not allowed to send broadcast "
17716                            + action + " from unknown caller.";
17717                    Slog.w(TAG, msg);
17718                    throw new SecurityException(msg);
17719                } else if (intent.getComponent() != null) {
17720                    // They are good enough to send to an explicit component...  verify
17721                    // it is being sent to the calling app.
17722                    if (!intent.getComponent().getPackageName().equals(
17723                            callerPackage)) {
17724                        String msg = "Permission Denial: not allowed to send broadcast "
17725                                + action + " to "
17726                                + intent.getComponent().getPackageName() + " from "
17727                                + callerPackage;
17728                        Slog.w(TAG, msg);
17729                        throw new SecurityException(msg);
17730                    }
17731                } else {
17732                    // Limit broadcast to their own package.
17733                    intent.setPackage(callerPackage);
17734                }
17735            }
17736        }
17737
17738        if (action != null) {
17739            switch (action) {
17740                case Intent.ACTION_UID_REMOVED:
17741                case Intent.ACTION_PACKAGE_REMOVED:
17742                case Intent.ACTION_PACKAGE_CHANGED:
17743                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17744                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17745                case Intent.ACTION_PACKAGES_SUSPENDED:
17746                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17747                    // Handle special intents: if this broadcast is from the package
17748                    // manager about a package being removed, we need to remove all of
17749                    // its activities from the history stack.
17750                    if (checkComponentPermission(
17751                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17752                            callingPid, callingUid, -1, true)
17753                            != PackageManager.PERMISSION_GRANTED) {
17754                        String msg = "Permission Denial: " + intent.getAction()
17755                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17756                                + ", uid=" + callingUid + ")"
17757                                + " requires "
17758                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17759                        Slog.w(TAG, msg);
17760                        throw new SecurityException(msg);
17761                    }
17762                    switch (action) {
17763                        case Intent.ACTION_UID_REMOVED:
17764                            final Bundle intentExtras = intent.getExtras();
17765                            final int uid = intentExtras != null
17766                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17767                            if (uid >= 0) {
17768                                mBatteryStatsService.removeUid(uid);
17769                                mAppOpsService.uidRemoved(uid);
17770                            }
17771                            break;
17772                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17773                            // If resources are unavailable just force stop all those packages
17774                            // and flush the attribute cache as well.
17775                            String list[] =
17776                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17777                            if (list != null && list.length > 0) {
17778                                for (int i = 0; i < list.length; i++) {
17779                                    forceStopPackageLocked(list[i], -1, false, true, true,
17780                                            false, false, userId, "storage unmount");
17781                                }
17782                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17783                                sendPackageBroadcastLocked(
17784                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17785                                        userId);
17786                            }
17787                            break;
17788                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17789                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17790                            break;
17791                        case Intent.ACTION_PACKAGE_REMOVED:
17792                        case Intent.ACTION_PACKAGE_CHANGED:
17793                            Uri data = intent.getData();
17794                            String ssp;
17795                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17796                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17797                                final boolean replacing =
17798                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17799                                final boolean killProcess =
17800                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17801                                final boolean fullUninstall = removed && !replacing;
17802                                if (removed) {
17803                                    if (killProcess) {
17804                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17805                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17806                                                false, true, true, false, fullUninstall, userId,
17807                                                removed ? "pkg removed" : "pkg changed");
17808                                    }
17809                                    final int cmd = killProcess
17810                                            ? IApplicationThread.PACKAGE_REMOVED
17811                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17812                                    sendPackageBroadcastLocked(cmd,
17813                                            new String[] {ssp}, userId);
17814                                    if (fullUninstall) {
17815                                        mAppOpsService.packageRemoved(
17816                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17817
17818                                        // Remove all permissions granted from/to this package
17819                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17820
17821                                        removeTasksByPackageNameLocked(ssp, userId);
17822
17823                                        // Hide the "unsupported display" dialog if necessary.
17824                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17825                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17826                                            mUnsupportedDisplaySizeDialog.dismiss();
17827                                            mUnsupportedDisplaySizeDialog = null;
17828                                        }
17829                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17830                                        mBatteryStatsService.notePackageUninstalled(ssp);
17831                                    }
17832                                } else {
17833                                    if (killProcess) {
17834                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17835                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17836                                                userId, ProcessList.INVALID_ADJ,
17837                                                false, true, true, false, "change " + ssp);
17838                                    }
17839                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17840                                            intent.getStringArrayExtra(
17841                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17842                                }
17843                            }
17844                            break;
17845                        case Intent.ACTION_PACKAGES_SUSPENDED:
17846                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17847                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17848                                    intent.getAction());
17849                            final String[] packageNames = intent.getStringArrayExtra(
17850                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17851                            final int userHandle = intent.getIntExtra(
17852                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17853
17854                            synchronized(ActivityManagerService.this) {
17855                                mRecentTasks.onPackagesSuspendedChanged(
17856                                        packageNames, suspended, userHandle);
17857                            }
17858                            break;
17859                    }
17860                    break;
17861                case Intent.ACTION_PACKAGE_REPLACED:
17862                {
17863                    final Uri data = intent.getData();
17864                    final String ssp;
17865                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17866                        final ApplicationInfo aInfo =
17867                                getPackageManagerInternalLocked().getApplicationInfo(
17868                                        ssp,
17869                                        userId);
17870                        if (aInfo == null) {
17871                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17872                                    + " ssp=" + ssp + " data=" + data);
17873                            return ActivityManager.BROADCAST_SUCCESS;
17874                        }
17875                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17876                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17877                                new String[] {ssp}, userId);
17878                    }
17879                    break;
17880                }
17881                case Intent.ACTION_PACKAGE_ADDED:
17882                {
17883                    // Special case for adding a package: by default turn on compatibility mode.
17884                    Uri data = intent.getData();
17885                    String ssp;
17886                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17887                        final boolean replacing =
17888                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17889                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17890
17891                        try {
17892                            ApplicationInfo ai = AppGlobals.getPackageManager().
17893                                    getApplicationInfo(ssp, 0, 0);
17894                            mBatteryStatsService.notePackageInstalled(ssp,
17895                                    ai != null ? ai.versionCode : 0);
17896                        } catch (RemoteException e) {
17897                        }
17898                    }
17899                    break;
17900                }
17901                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17902                {
17903                    Uri data = intent.getData();
17904                    String ssp;
17905                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17906                        // Hide the "unsupported display" dialog if necessary.
17907                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17908                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17909                            mUnsupportedDisplaySizeDialog.dismiss();
17910                            mUnsupportedDisplaySizeDialog = null;
17911                        }
17912                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17913                    }
17914                    break;
17915                }
17916                case Intent.ACTION_TIMEZONE_CHANGED:
17917                    // If this is the time zone changed action, queue up a message that will reset
17918                    // the timezone of all currently running processes. This message will get
17919                    // queued up before the broadcast happens.
17920                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17921                    break;
17922                case Intent.ACTION_TIME_CHANGED:
17923                    // If the user set the time, let all running processes know.
17924                    final int is24Hour =
17925                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17926                                    : 0;
17927                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17928                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17929                    synchronized (stats) {
17930                        stats.noteCurrentTimeChangedLocked();
17931                    }
17932                    break;
17933                case Intent.ACTION_CLEAR_DNS_CACHE:
17934                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17935                    break;
17936                case Proxy.PROXY_CHANGE_ACTION:
17937                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17938                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17939                    break;
17940                case android.hardware.Camera.ACTION_NEW_PICTURE:
17941                case android.hardware.Camera.ACTION_NEW_VIDEO:
17942                    // These broadcasts are no longer allowed by the system, since they can
17943                    // cause significant thrashing at a crictical point (using the camera).
17944                    // Apps should use JobScehduler to monitor for media provider changes.
17945                    Slog.w(TAG, action + " no longer allowed; dropping from "
17946                            + UserHandle.formatUid(callingUid));
17947                    if (resultTo != null) {
17948                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17949                        try {
17950                            queue.performReceiveLocked(callerApp, resultTo, intent,
17951                                    Activity.RESULT_CANCELED, null, null,
17952                                    false, false, userId);
17953                        } catch (RemoteException e) {
17954                            Slog.w(TAG, "Failure ["
17955                                    + queue.mQueueName + "] sending broadcast result of "
17956                                    + intent, e);
17957
17958                        }
17959                    }
17960                    // Lie; we don't want to crash the app.
17961                    return ActivityManager.BROADCAST_SUCCESS;
17962            }
17963        }
17964
17965        // Add to the sticky list if requested.
17966        if (sticky) {
17967            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17968                    callingPid, callingUid)
17969                    != PackageManager.PERMISSION_GRANTED) {
17970                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17971                        + callingPid + ", uid=" + callingUid
17972                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17973                Slog.w(TAG, msg);
17974                throw new SecurityException(msg);
17975            }
17976            if (requiredPermissions != null && requiredPermissions.length > 0) {
17977                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17978                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17979                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17980            }
17981            if (intent.getComponent() != null) {
17982                throw new SecurityException(
17983                        "Sticky broadcasts can't target a specific component");
17984            }
17985            // We use userId directly here, since the "all" target is maintained
17986            // as a separate set of sticky broadcasts.
17987            if (userId != UserHandle.USER_ALL) {
17988                // But first, if this is not a broadcast to all users, then
17989                // make sure it doesn't conflict with an existing broadcast to
17990                // all users.
17991                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17992                        UserHandle.USER_ALL);
17993                if (stickies != null) {
17994                    ArrayList<Intent> list = stickies.get(intent.getAction());
17995                    if (list != null) {
17996                        int N = list.size();
17997                        int i;
17998                        for (i=0; i<N; i++) {
17999                            if (intent.filterEquals(list.get(i))) {
18000                                throw new IllegalArgumentException(
18001                                        "Sticky broadcast " + intent + " for user "
18002                                        + userId + " conflicts with existing global broadcast");
18003                            }
18004                        }
18005                    }
18006                }
18007            }
18008            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18009            if (stickies == null) {
18010                stickies = new ArrayMap<>();
18011                mStickyBroadcasts.put(userId, stickies);
18012            }
18013            ArrayList<Intent> list = stickies.get(intent.getAction());
18014            if (list == null) {
18015                list = new ArrayList<>();
18016                stickies.put(intent.getAction(), list);
18017            }
18018            final int stickiesCount = list.size();
18019            int i;
18020            for (i = 0; i < stickiesCount; i++) {
18021                if (intent.filterEquals(list.get(i))) {
18022                    // This sticky already exists, replace it.
18023                    list.set(i, new Intent(intent));
18024                    break;
18025                }
18026            }
18027            if (i >= stickiesCount) {
18028                list.add(new Intent(intent));
18029            }
18030        }
18031
18032        int[] users;
18033        if (userId == UserHandle.USER_ALL) {
18034            // Caller wants broadcast to go to all started users.
18035            users = mUserController.getStartedUserArrayLocked();
18036        } else {
18037            // Caller wants broadcast to go to one specific user.
18038            users = new int[] {userId};
18039        }
18040
18041        // Figure out who all will receive this broadcast.
18042        List receivers = null;
18043        List<BroadcastFilter> registeredReceivers = null;
18044        // Need to resolve the intent to interested receivers...
18045        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18046                 == 0) {
18047            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18048        }
18049        if (intent.getComponent() == null) {
18050            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18051                // Query one target user at a time, excluding shell-restricted users
18052                for (int i = 0; i < users.length; i++) {
18053                    if (mUserController.hasUserRestriction(
18054                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18055                        continue;
18056                    }
18057                    List<BroadcastFilter> registeredReceiversForUser =
18058                            mReceiverResolver.queryIntent(intent,
18059                                    resolvedType, false, users[i]);
18060                    if (registeredReceivers == null) {
18061                        registeredReceivers = registeredReceiversForUser;
18062                    } else if (registeredReceiversForUser != null) {
18063                        registeredReceivers.addAll(registeredReceiversForUser);
18064                    }
18065                }
18066            } else {
18067                registeredReceivers = mReceiverResolver.queryIntent(intent,
18068                        resolvedType, false, userId);
18069            }
18070        }
18071
18072        final boolean replacePending =
18073                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18074
18075        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18076                + " replacePending=" + replacePending);
18077
18078        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18079        if (!ordered && NR > 0) {
18080            // If we are not serializing this broadcast, then send the
18081            // registered receivers separately so they don't wait for the
18082            // components to be launched.
18083            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18084            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18085                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18086                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18087                    resultExtras, ordered, sticky, false, userId);
18088            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18089            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18090            if (!replaced) {
18091                queue.enqueueParallelBroadcastLocked(r);
18092                queue.scheduleBroadcastsLocked();
18093            }
18094            registeredReceivers = null;
18095            NR = 0;
18096        }
18097
18098        // Merge into one list.
18099        int ir = 0;
18100        if (receivers != null) {
18101            // A special case for PACKAGE_ADDED: do not allow the package
18102            // being added to see this broadcast.  This prevents them from
18103            // using this as a back door to get run as soon as they are
18104            // installed.  Maybe in the future we want to have a special install
18105            // broadcast or such for apps, but we'd like to deliberately make
18106            // this decision.
18107            String skipPackages[] = null;
18108            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18109                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18110                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18111                Uri data = intent.getData();
18112                if (data != null) {
18113                    String pkgName = data.getSchemeSpecificPart();
18114                    if (pkgName != null) {
18115                        skipPackages = new String[] { pkgName };
18116                    }
18117                }
18118            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18119                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18120            }
18121            if (skipPackages != null && (skipPackages.length > 0)) {
18122                for (String skipPackage : skipPackages) {
18123                    if (skipPackage != null) {
18124                        int NT = receivers.size();
18125                        for (int it=0; it<NT; it++) {
18126                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18127                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18128                                receivers.remove(it);
18129                                it--;
18130                                NT--;
18131                            }
18132                        }
18133                    }
18134                }
18135            }
18136
18137            int NT = receivers != null ? receivers.size() : 0;
18138            int it = 0;
18139            ResolveInfo curt = null;
18140            BroadcastFilter curr = null;
18141            while (it < NT && ir < NR) {
18142                if (curt == null) {
18143                    curt = (ResolveInfo)receivers.get(it);
18144                }
18145                if (curr == null) {
18146                    curr = registeredReceivers.get(ir);
18147                }
18148                if (curr.getPriority() >= curt.priority) {
18149                    // Insert this broadcast record into the final list.
18150                    receivers.add(it, curr);
18151                    ir++;
18152                    curr = null;
18153                    it++;
18154                    NT++;
18155                } else {
18156                    // Skip to the next ResolveInfo in the final list.
18157                    it++;
18158                    curt = null;
18159                }
18160            }
18161        }
18162        while (ir < NR) {
18163            if (receivers == null) {
18164                receivers = new ArrayList();
18165            }
18166            receivers.add(registeredReceivers.get(ir));
18167            ir++;
18168        }
18169
18170        if ((receivers != null && receivers.size() > 0)
18171                || resultTo != null) {
18172            BroadcastQueue queue = broadcastQueueForIntent(intent);
18173            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18174                    callerPackage, callingPid, callingUid, resolvedType,
18175                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18176                    resultData, resultExtras, ordered, sticky, false, userId);
18177
18178            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18179                    + ": prev had " + queue.mOrderedBroadcasts.size());
18180            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18181                    "Enqueueing broadcast " + r.intent.getAction());
18182
18183            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18184            if (!replaced) {
18185                queue.enqueueOrderedBroadcastLocked(r);
18186                queue.scheduleBroadcastsLocked();
18187            }
18188        } else {
18189            // There was nobody interested in the broadcast, but we still want to record
18190            // that it happened.
18191            if (intent.getComponent() == null && intent.getPackage() == null
18192                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18193                // This was an implicit broadcast... let's record it for posterity.
18194                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18195            }
18196        }
18197
18198        return ActivityManager.BROADCAST_SUCCESS;
18199    }
18200
18201    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18202            int skipCount, long dispatchTime) {
18203        final long now = SystemClock.elapsedRealtime();
18204        if (mCurBroadcastStats == null ||
18205                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18206            mLastBroadcastStats = mCurBroadcastStats;
18207            if (mLastBroadcastStats != null) {
18208                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18209                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18210            }
18211            mCurBroadcastStats = new BroadcastStats();
18212        }
18213        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18214    }
18215
18216    final Intent verifyBroadcastLocked(Intent intent) {
18217        // Refuse possible leaked file descriptors
18218        if (intent != null && intent.hasFileDescriptors() == true) {
18219            throw new IllegalArgumentException("File descriptors passed in Intent");
18220        }
18221
18222        int flags = intent.getFlags();
18223
18224        if (!mProcessesReady) {
18225            // if the caller really truly claims to know what they're doing, go
18226            // ahead and allow the broadcast without launching any receivers
18227            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18228                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18229            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18230                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18231                        + " before boot completion");
18232                throw new IllegalStateException("Cannot broadcast before boot completed");
18233            }
18234        }
18235
18236        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18237            throw new IllegalArgumentException(
18238                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18239        }
18240
18241        return intent;
18242    }
18243
18244    public final int broadcastIntent(IApplicationThread caller,
18245            Intent intent, String resolvedType, IIntentReceiver resultTo,
18246            int resultCode, String resultData, Bundle resultExtras,
18247            String[] requiredPermissions, int appOp, Bundle bOptions,
18248            boolean serialized, boolean sticky, int userId) {
18249        enforceNotIsolatedCaller("broadcastIntent");
18250        synchronized(this) {
18251            intent = verifyBroadcastLocked(intent);
18252
18253            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18254            final int callingPid = Binder.getCallingPid();
18255            final int callingUid = Binder.getCallingUid();
18256            final long origId = Binder.clearCallingIdentity();
18257            int res = broadcastIntentLocked(callerApp,
18258                    callerApp != null ? callerApp.info.packageName : null,
18259                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18260                    requiredPermissions, appOp, bOptions, serialized, sticky,
18261                    callingPid, callingUid, userId);
18262            Binder.restoreCallingIdentity(origId);
18263            return res;
18264        }
18265    }
18266
18267
18268    int broadcastIntentInPackage(String packageName, int uid,
18269            Intent intent, String resolvedType, IIntentReceiver resultTo,
18270            int resultCode, String resultData, Bundle resultExtras,
18271            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18272            int userId) {
18273        synchronized(this) {
18274            intent = verifyBroadcastLocked(intent);
18275
18276            final long origId = Binder.clearCallingIdentity();
18277            String[] requiredPermissions = requiredPermission == null ? null
18278                    : new String[] {requiredPermission};
18279            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18280                    resultTo, resultCode, resultData, resultExtras,
18281                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18282                    sticky, -1, uid, userId);
18283            Binder.restoreCallingIdentity(origId);
18284            return res;
18285        }
18286    }
18287
18288    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18289        // Refuse possible leaked file descriptors
18290        if (intent != null && intent.hasFileDescriptors() == true) {
18291            throw new IllegalArgumentException("File descriptors passed in Intent");
18292        }
18293
18294        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18295                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18296
18297        synchronized(this) {
18298            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18299                    != PackageManager.PERMISSION_GRANTED) {
18300                String msg = "Permission Denial: unbroadcastIntent() from pid="
18301                        + Binder.getCallingPid()
18302                        + ", uid=" + Binder.getCallingUid()
18303                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18304                Slog.w(TAG, msg);
18305                throw new SecurityException(msg);
18306            }
18307            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18308            if (stickies != null) {
18309                ArrayList<Intent> list = stickies.get(intent.getAction());
18310                if (list != null) {
18311                    int N = list.size();
18312                    int i;
18313                    for (i=0; i<N; i++) {
18314                        if (intent.filterEquals(list.get(i))) {
18315                            list.remove(i);
18316                            break;
18317                        }
18318                    }
18319                    if (list.size() <= 0) {
18320                        stickies.remove(intent.getAction());
18321                    }
18322                }
18323                if (stickies.size() <= 0) {
18324                    mStickyBroadcasts.remove(userId);
18325                }
18326            }
18327        }
18328    }
18329
18330    void backgroundServicesFinishedLocked(int userId) {
18331        for (BroadcastQueue queue : mBroadcastQueues) {
18332            queue.backgroundServicesFinishedLocked(userId);
18333        }
18334    }
18335
18336    public void finishReceiver(IBinder who, int resultCode, String resultData,
18337            Bundle resultExtras, boolean resultAbort, int flags) {
18338        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18339
18340        // Refuse possible leaked file descriptors
18341        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18342            throw new IllegalArgumentException("File descriptors passed in Bundle");
18343        }
18344
18345        final long origId = Binder.clearCallingIdentity();
18346        try {
18347            boolean doNext = false;
18348            BroadcastRecord r;
18349
18350            synchronized(this) {
18351                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18352                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18353                r = queue.getMatchingOrderedReceiver(who);
18354                if (r != null) {
18355                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18356                        resultData, resultExtras, resultAbort, true);
18357                }
18358            }
18359
18360            if (doNext) {
18361                r.queue.processNextBroadcast(false);
18362            }
18363            trimApplications();
18364        } finally {
18365            Binder.restoreCallingIdentity(origId);
18366        }
18367    }
18368
18369    // =========================================================
18370    // INSTRUMENTATION
18371    // =========================================================
18372
18373    public boolean startInstrumentation(ComponentName className,
18374            String profileFile, int flags, Bundle arguments,
18375            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18376            int userId, String abiOverride) {
18377        enforceNotIsolatedCaller("startInstrumentation");
18378        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18379                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18380        // Refuse possible leaked file descriptors
18381        if (arguments != null && arguments.hasFileDescriptors()) {
18382            throw new IllegalArgumentException("File descriptors passed in Bundle");
18383        }
18384
18385        synchronized(this) {
18386            InstrumentationInfo ii = null;
18387            ApplicationInfo ai = null;
18388            try {
18389                ii = mContext.getPackageManager().getInstrumentationInfo(
18390                    className, STOCK_PM_FLAGS);
18391                ai = AppGlobals.getPackageManager().getApplicationInfo(
18392                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18393            } catch (PackageManager.NameNotFoundException e) {
18394            } catch (RemoteException e) {
18395            }
18396            if (ii == null) {
18397                reportStartInstrumentationFailureLocked(watcher, className,
18398                        "Unable to find instrumentation info for: " + className);
18399                return false;
18400            }
18401            if (ai == null) {
18402                reportStartInstrumentationFailureLocked(watcher, className,
18403                        "Unable to find instrumentation target package: " + ii.targetPackage);
18404                return false;
18405            }
18406            if (!ai.hasCode()) {
18407                reportStartInstrumentationFailureLocked(watcher, className,
18408                        "Instrumentation target has no code: " + ii.targetPackage);
18409                return false;
18410            }
18411
18412            int match = mContext.getPackageManager().checkSignatures(
18413                    ii.targetPackage, ii.packageName);
18414            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18415                String msg = "Permission Denial: starting instrumentation "
18416                        + className + " from pid="
18417                        + Binder.getCallingPid()
18418                        + ", uid=" + Binder.getCallingPid()
18419                        + " not allowed because package " + ii.packageName
18420                        + " does not have a signature matching the target "
18421                        + ii.targetPackage;
18422                reportStartInstrumentationFailureLocked(watcher, className, msg);
18423                throw new SecurityException(msg);
18424            }
18425
18426            final long origId = Binder.clearCallingIdentity();
18427            // Instrumentation can kill and relaunch even persistent processes
18428            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18429                    "start instr");
18430            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18431            app.instrumentationClass = className;
18432            app.instrumentationInfo = ai;
18433            app.instrumentationProfileFile = profileFile;
18434            app.instrumentationArguments = arguments;
18435            app.instrumentationWatcher = watcher;
18436            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18437            app.instrumentationResultClass = className;
18438            Binder.restoreCallingIdentity(origId);
18439        }
18440
18441        return true;
18442    }
18443
18444    /**
18445     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18446     * error to the logs, but if somebody is watching, send the report there too.  This enables
18447     * the "am" command to report errors with more information.
18448     *
18449     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18450     * @param cn The component name of the instrumentation.
18451     * @param report The error report.
18452     */
18453    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18454            ComponentName cn, String report) {
18455        Slog.w(TAG, report);
18456        if (watcher != null) {
18457            Bundle results = new Bundle();
18458            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18459            results.putString("Error", report);
18460            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18461        }
18462    }
18463
18464    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18465        if (app.instrumentationWatcher != null) {
18466            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18467                    app.instrumentationClass, resultCode, results);
18468        }
18469
18470        // Can't call out of the system process with a lock held, so post a message.
18471        if (app.instrumentationUiAutomationConnection != null) {
18472            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18473                    app.instrumentationUiAutomationConnection).sendToTarget();
18474        }
18475
18476        app.instrumentationWatcher = null;
18477        app.instrumentationUiAutomationConnection = null;
18478        app.instrumentationClass = null;
18479        app.instrumentationInfo = null;
18480        app.instrumentationProfileFile = null;
18481        app.instrumentationArguments = null;
18482
18483        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18484                "finished inst");
18485    }
18486
18487    public void finishInstrumentation(IApplicationThread target,
18488            int resultCode, Bundle results) {
18489        int userId = UserHandle.getCallingUserId();
18490        // Refuse possible leaked file descriptors
18491        if (results != null && results.hasFileDescriptors()) {
18492            throw new IllegalArgumentException("File descriptors passed in Intent");
18493        }
18494
18495        synchronized(this) {
18496            ProcessRecord app = getRecordForAppLocked(target);
18497            if (app == null) {
18498                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18499                return;
18500            }
18501            final long origId = Binder.clearCallingIdentity();
18502            finishInstrumentationLocked(app, resultCode, results);
18503            Binder.restoreCallingIdentity(origId);
18504        }
18505    }
18506
18507    // =========================================================
18508    // CONFIGURATION
18509    // =========================================================
18510
18511    public ConfigurationInfo getDeviceConfigurationInfo() {
18512        ConfigurationInfo config = new ConfigurationInfo();
18513        synchronized (this) {
18514            config.reqTouchScreen = mConfiguration.touchscreen;
18515            config.reqKeyboardType = mConfiguration.keyboard;
18516            config.reqNavigation = mConfiguration.navigation;
18517            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18518                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18519                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18520            }
18521            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18522                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18523                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18524            }
18525            config.reqGlEsVersion = GL_ES_VERSION;
18526        }
18527        return config;
18528    }
18529
18530    ActivityStack getFocusedStack() {
18531        return mStackSupervisor.getFocusedStack();
18532    }
18533
18534    @Override
18535    public int getFocusedStackId() throws RemoteException {
18536        ActivityStack focusedStack = getFocusedStack();
18537        if (focusedStack != null) {
18538            return focusedStack.getStackId();
18539        }
18540        return -1;
18541    }
18542
18543    public Configuration getConfiguration() {
18544        Configuration ci;
18545        synchronized(this) {
18546            ci = new Configuration(mConfiguration);
18547            ci.userSetLocale = false;
18548        }
18549        return ci;
18550    }
18551
18552    @Override
18553    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18554        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18555        synchronized (this) {
18556            mSuppressResizeConfigChanges = suppress;
18557        }
18558    }
18559
18560    @Override
18561    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18562        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18563        if (fromStackId == HOME_STACK_ID) {
18564            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18565        }
18566        synchronized (this) {
18567            final long origId = Binder.clearCallingIdentity();
18568            try {
18569                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18570            } finally {
18571                Binder.restoreCallingIdentity(origId);
18572            }
18573        }
18574    }
18575
18576    @Override
18577    public void updatePersistentConfiguration(Configuration values) {
18578        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18579                "updateConfiguration()");
18580        enforceWriteSettingsPermission("updateConfiguration()");
18581        if (values == null) {
18582            throw new NullPointerException("Configuration must not be null");
18583        }
18584
18585        int userId = UserHandle.getCallingUserId();
18586
18587        synchronized(this) {
18588            final long origId = Binder.clearCallingIdentity();
18589            updateConfigurationLocked(values, null, false, true, userId);
18590            Binder.restoreCallingIdentity(origId);
18591        }
18592    }
18593
18594    private void updateFontScaleIfNeeded() {
18595        final int currentUserId;
18596        synchronized(this) {
18597            currentUserId = mUserController.getCurrentUserIdLocked();
18598        }
18599        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18600                FONT_SCALE, 1.0f, currentUserId);
18601        if (mConfiguration.fontScale != scaleFactor) {
18602            final Configuration configuration = mWindowManager.computeNewConfiguration();
18603            configuration.fontScale = scaleFactor;
18604            updatePersistentConfiguration(configuration);
18605        }
18606    }
18607
18608    private void enforceWriteSettingsPermission(String func) {
18609        int uid = Binder.getCallingUid();
18610        if (uid == Process.ROOT_UID) {
18611            return;
18612        }
18613
18614        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18615                Settings.getPackageNameForUid(mContext, uid), false)) {
18616            return;
18617        }
18618
18619        String msg = "Permission Denial: " + func + " from pid="
18620                + Binder.getCallingPid()
18621                + ", uid=" + uid
18622                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18623        Slog.w(TAG, msg);
18624        throw new SecurityException(msg);
18625    }
18626
18627    public void updateConfiguration(Configuration values) {
18628        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18629                "updateConfiguration()");
18630
18631        synchronized(this) {
18632            if (values == null && mWindowManager != null) {
18633                // sentinel: fetch the current configuration from the window manager
18634                values = mWindowManager.computeNewConfiguration();
18635            }
18636
18637            if (mWindowManager != null) {
18638                mProcessList.applyDisplaySize(mWindowManager);
18639            }
18640
18641            final long origId = Binder.clearCallingIdentity();
18642            if (values != null) {
18643                Settings.System.clearConfiguration(values);
18644            }
18645            updateConfigurationLocked(values, null, false);
18646            Binder.restoreCallingIdentity(origId);
18647        }
18648    }
18649
18650    void updateUserConfigurationLocked() {
18651        Configuration configuration = new Configuration(mConfiguration);
18652        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18653                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18654        updateConfigurationLocked(configuration, null, false);
18655    }
18656
18657    boolean updateConfigurationLocked(Configuration values,
18658            ActivityRecord starting, boolean initLocale) {
18659        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18660        return updateConfigurationLocked(values, starting, initLocale, false,
18661                UserHandle.USER_NULL);
18662    }
18663
18664    // To cache the list of supported system locales
18665    private String[] mSupportedSystemLocales = null;
18666
18667    /**
18668     * Do either or both things: (1) change the current configuration, and (2)
18669     * make sure the given activity is running with the (now) current
18670     * configuration.  Returns true if the activity has been left running, or
18671     * false if <var>starting</var> is being destroyed to match the new
18672     * configuration.
18673     *
18674     * @param userId is only used when persistent parameter is set to true to persist configuration
18675     *               for that particular user
18676     */
18677    private boolean updateConfigurationLocked(Configuration values,
18678            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18679        int changes = 0;
18680
18681        if (mWindowManager != null) {
18682            mWindowManager.deferSurfaceLayout();
18683        }
18684        if (values != null) {
18685            Configuration newConfig = new Configuration(mConfiguration);
18686            changes = newConfig.updateFrom(values);
18687            if (changes != 0) {
18688                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18689                        "Updating configuration to: " + values);
18690
18691                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18692
18693                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18694                    final LocaleList locales = values.getLocales();
18695                    int bestLocaleIndex = 0;
18696                    if (locales.size() > 1) {
18697                        if (mSupportedSystemLocales == null) {
18698                            mSupportedSystemLocales =
18699                                    Resources.getSystem().getAssets().getLocales();
18700                        }
18701                        bestLocaleIndex = Math.max(0,
18702                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18703                    }
18704                    SystemProperties.set("persist.sys.locale",
18705                            locales.get(bestLocaleIndex).toLanguageTag());
18706                    LocaleList.setDefault(locales, bestLocaleIndex);
18707                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18708                            locales.get(bestLocaleIndex)));
18709                }
18710
18711                mConfigurationSeq++;
18712                if (mConfigurationSeq <= 0) {
18713                    mConfigurationSeq = 1;
18714                }
18715                newConfig.seq = mConfigurationSeq;
18716                mConfiguration = newConfig;
18717                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18718                mUsageStatsService.reportConfigurationChange(newConfig,
18719                        mUserController.getCurrentUserIdLocked());
18720                //mUsageStatsService.noteStartConfig(newConfig);
18721
18722                final Configuration configCopy = new Configuration(mConfiguration);
18723
18724                // TODO: If our config changes, should we auto dismiss any currently
18725                // showing dialogs?
18726                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18727
18728                AttributeCache ac = AttributeCache.instance();
18729                if (ac != null) {
18730                    ac.updateConfiguration(configCopy);
18731                }
18732
18733                // Make sure all resources in our process are updated
18734                // right now, so that anyone who is going to retrieve
18735                // resource values after we return will be sure to get
18736                // the new ones.  This is especially important during
18737                // boot, where the first config change needs to guarantee
18738                // all resources have that config before following boot
18739                // code is executed.
18740                mSystemThread.applyConfigurationToResources(configCopy);
18741
18742                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18743                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18744                    msg.obj = new Configuration(configCopy);
18745                    msg.arg1 = userId;
18746                    mHandler.sendMessage(msg);
18747                }
18748
18749                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18750                if (isDensityChange) {
18751                    // Reset the unsupported display size dialog.
18752                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18753
18754                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18755                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18756                }
18757
18758                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18759                    ProcessRecord app = mLruProcesses.get(i);
18760                    try {
18761                        if (app.thread != null) {
18762                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18763                                    + app.processName + " new config " + mConfiguration);
18764                            app.thread.scheduleConfigurationChanged(configCopy);
18765                        }
18766                    } catch (Exception e) {
18767                    }
18768                }
18769                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18770                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18771                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18772                        | Intent.FLAG_RECEIVER_FOREGROUND);
18773                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18774                        null, AppOpsManager.OP_NONE, null, false, false,
18775                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18776                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18777                    // Tell the shortcut manager that the system locale changed.  It needs to know
18778                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18779                    // we "push" from here, rather than having the service listen to the broadcast.
18780                    final ShortcutServiceInternal shortcutService =
18781                            LocalServices.getService(ShortcutServiceInternal.class);
18782                    if (shortcutService != null) {
18783                        shortcutService.onSystemLocaleChangedNoLock();
18784                    }
18785
18786                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18787                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18788                    if (!mProcessesReady) {
18789                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18790                    }
18791                    broadcastIntentLocked(null, null, intent,
18792                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18793                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18794                }
18795            }
18796            // Update the configuration with WM first and check if any of the stacks need to be
18797            // resized due to the configuration change. If so, resize the stacks now and do any
18798            // relaunches if necessary. This way we don't need to relaunch again below in
18799            // ensureActivityConfigurationLocked().
18800            if (mWindowManager != null) {
18801                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18802                if (resizedStacks != null) {
18803                    for (int stackId : resizedStacks) {
18804                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18805                        mStackSupervisor.resizeStackLocked(
18806                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18807                    }
18808                }
18809            }
18810        }
18811
18812        boolean kept = true;
18813        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18814        // mainStack is null during startup.
18815        if (mainStack != null) {
18816            if (changes != 0 && starting == null) {
18817                // If the configuration changed, and the caller is not already
18818                // in the process of starting an activity, then find the top
18819                // activity to check if its configuration needs to change.
18820                starting = mainStack.topRunningActivityLocked();
18821            }
18822
18823            if (starting != null) {
18824                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18825                // And we need to make sure at this point that all other activities
18826                // are made visible with the correct configuration.
18827                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18828                        !PRESERVE_WINDOWS);
18829            }
18830        }
18831        if (mWindowManager != null) {
18832            mWindowManager.continueSurfaceLayout();
18833        }
18834        return kept;
18835    }
18836
18837    /**
18838     * Decide based on the configuration whether we should shouw the ANR,
18839     * crash, etc dialogs.  The idea is that if there is no affordnace to
18840     * press the on-screen buttons, we shouldn't show the dialog.
18841     *
18842     * A thought: SystemUI might also want to get told about this, the Power
18843     * dialog / global actions also might want different behaviors.
18844     */
18845    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18846        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18847                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18848                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18849        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18850                                    == Configuration.UI_MODE_TYPE_CAR);
18851        return inputMethodExists && uiIsNotCarType && !inVrMode;
18852    }
18853
18854    @Override
18855    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18856        synchronized (this) {
18857            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18858            if (srec != null) {
18859                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18860            }
18861        }
18862        return false;
18863    }
18864
18865    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18866            Intent resultData) {
18867
18868        synchronized (this) {
18869            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18870            if (r != null) {
18871                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18872            }
18873            return false;
18874        }
18875    }
18876
18877    public int getLaunchedFromUid(IBinder activityToken) {
18878        ActivityRecord srec;
18879        synchronized (this) {
18880            srec = ActivityRecord.forTokenLocked(activityToken);
18881        }
18882        if (srec == null) {
18883            return -1;
18884        }
18885        return srec.launchedFromUid;
18886    }
18887
18888    public String getLaunchedFromPackage(IBinder activityToken) {
18889        ActivityRecord srec;
18890        synchronized (this) {
18891            srec = ActivityRecord.forTokenLocked(activityToken);
18892        }
18893        if (srec == null) {
18894            return null;
18895        }
18896        return srec.launchedFromPackage;
18897    }
18898
18899    // =========================================================
18900    // LIFETIME MANAGEMENT
18901    // =========================================================
18902
18903    // Returns which broadcast queue the app is the current [or imminent] receiver
18904    // on, or 'null' if the app is not an active broadcast recipient.
18905    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18906        BroadcastRecord r = app.curReceiver;
18907        if (r != null) {
18908            return r.queue;
18909        }
18910
18911        // It's not the current receiver, but it might be starting up to become one
18912        synchronized (this) {
18913            for (BroadcastQueue queue : mBroadcastQueues) {
18914                r = queue.mPendingBroadcast;
18915                if (r != null && r.curApp == app) {
18916                    // found it; report which queue it's in
18917                    return queue;
18918                }
18919            }
18920        }
18921
18922        return null;
18923    }
18924
18925    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18926            int targetUid, ComponentName targetComponent, String targetProcess) {
18927        if (!mTrackingAssociations) {
18928            return null;
18929        }
18930        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18931                = mAssociations.get(targetUid);
18932        if (components == null) {
18933            components = new ArrayMap<>();
18934            mAssociations.put(targetUid, components);
18935        }
18936        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18937        if (sourceUids == null) {
18938            sourceUids = new SparseArray<>();
18939            components.put(targetComponent, sourceUids);
18940        }
18941        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18942        if (sourceProcesses == null) {
18943            sourceProcesses = new ArrayMap<>();
18944            sourceUids.put(sourceUid, sourceProcesses);
18945        }
18946        Association ass = sourceProcesses.get(sourceProcess);
18947        if (ass == null) {
18948            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18949                    targetProcess);
18950            sourceProcesses.put(sourceProcess, ass);
18951        }
18952        ass.mCount++;
18953        ass.mNesting++;
18954        if (ass.mNesting == 1) {
18955            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18956            ass.mLastState = sourceState;
18957        }
18958        return ass;
18959    }
18960
18961    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18962            ComponentName targetComponent) {
18963        if (!mTrackingAssociations) {
18964            return;
18965        }
18966        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18967                = mAssociations.get(targetUid);
18968        if (components == null) {
18969            return;
18970        }
18971        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18972        if (sourceUids == null) {
18973            return;
18974        }
18975        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18976        if (sourceProcesses == null) {
18977            return;
18978        }
18979        Association ass = sourceProcesses.get(sourceProcess);
18980        if (ass == null || ass.mNesting <= 0) {
18981            return;
18982        }
18983        ass.mNesting--;
18984        if (ass.mNesting == 0) {
18985            long uptime = SystemClock.uptimeMillis();
18986            ass.mTime += uptime - ass.mStartTime;
18987            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18988                    += uptime - ass.mLastStateUptime;
18989            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18990        }
18991    }
18992
18993    private void noteUidProcessState(final int uid, final int state) {
18994        mBatteryStatsService.noteUidProcessState(uid, state);
18995        if (mTrackingAssociations) {
18996            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18997                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18998                        = mAssociations.valueAt(i1);
18999                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19000                    SparseArray<ArrayMap<String, Association>> sourceUids
19001                            = targetComponents.valueAt(i2);
19002                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19003                    if (sourceProcesses != null) {
19004                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19005                            Association ass = sourceProcesses.valueAt(i4);
19006                            if (ass.mNesting >= 1) {
19007                                // currently associated
19008                                long uptime = SystemClock.uptimeMillis();
19009                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19010                                        += uptime - ass.mLastStateUptime;
19011                                ass.mLastState = state;
19012                                ass.mLastStateUptime = uptime;
19013                            }
19014                        }
19015                    }
19016                }
19017            }
19018        }
19019    }
19020
19021    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19022            boolean doingAll, long now) {
19023        if (mAdjSeq == app.adjSeq) {
19024            // This adjustment has already been computed.
19025            return app.curRawAdj;
19026        }
19027
19028        if (app.thread == null) {
19029            app.adjSeq = mAdjSeq;
19030            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19031            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19032            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19033        }
19034
19035        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19036        app.adjSource = null;
19037        app.adjTarget = null;
19038        app.empty = false;
19039        app.cached = false;
19040
19041        final int activitiesSize = app.activities.size();
19042
19043        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19044            // The max adjustment doesn't allow this app to be anything
19045            // below foreground, so it is not worth doing work for it.
19046            app.adjType = "fixed";
19047            app.adjSeq = mAdjSeq;
19048            app.curRawAdj = app.maxAdj;
19049            app.foregroundActivities = false;
19050            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19051            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19052            // System processes can do UI, and when they do we want to have
19053            // them trim their memory after the user leaves the UI.  To
19054            // facilitate this, here we need to determine whether or not it
19055            // is currently showing UI.
19056            app.systemNoUi = true;
19057            if (app == TOP_APP) {
19058                app.systemNoUi = false;
19059                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19060                app.adjType = "pers-top-activity";
19061            } else if (activitiesSize > 0) {
19062                for (int j = 0; j < activitiesSize; j++) {
19063                    final ActivityRecord r = app.activities.get(j);
19064                    if (r.visible) {
19065                        app.systemNoUi = false;
19066                    }
19067                }
19068            }
19069            if (!app.systemNoUi) {
19070                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19071            }
19072            return (app.curAdj=app.maxAdj);
19073        }
19074
19075        app.systemNoUi = false;
19076
19077        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19078
19079        // Determine the importance of the process, starting with most
19080        // important to least, and assign an appropriate OOM adjustment.
19081        int adj;
19082        int schedGroup;
19083        int procState;
19084        boolean foregroundActivities = false;
19085        BroadcastQueue queue;
19086        if (app == TOP_APP) {
19087            // The last app on the list is the foreground app.
19088            adj = ProcessList.FOREGROUND_APP_ADJ;
19089            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19090            app.adjType = "top-activity";
19091            foregroundActivities = true;
19092            procState = PROCESS_STATE_CUR_TOP;
19093        } else if (app.instrumentationClass != null) {
19094            // Don't want to kill running instrumentation.
19095            adj = ProcessList.FOREGROUND_APP_ADJ;
19096            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19097            app.adjType = "instrumentation";
19098            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19099        } else if ((queue = isReceivingBroadcast(app)) != null) {
19100            // An app that is currently receiving a broadcast also
19101            // counts as being in the foreground for OOM killer purposes.
19102            // It's placed in a sched group based on the nature of the
19103            // broadcast as reflected by which queue it's active in.
19104            adj = ProcessList.FOREGROUND_APP_ADJ;
19105            schedGroup = (queue == mFgBroadcastQueue)
19106                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19107            app.adjType = "broadcast";
19108            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19109        } else if (app.executingServices.size() > 0) {
19110            // An app that is currently executing a service callback also
19111            // counts as being in the foreground.
19112            adj = ProcessList.FOREGROUND_APP_ADJ;
19113            schedGroup = app.execServicesFg ?
19114                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19115            app.adjType = "exec-service";
19116            procState = ActivityManager.PROCESS_STATE_SERVICE;
19117            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19118        } else {
19119            // As far as we know the process is empty.  We may change our mind later.
19120            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19121            // At this point we don't actually know the adjustment.  Use the cached adj
19122            // value that the caller wants us to.
19123            adj = cachedAdj;
19124            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19125            app.cached = true;
19126            app.empty = true;
19127            app.adjType = "cch-empty";
19128        }
19129
19130        // Examine all activities if not already foreground.
19131        if (!foregroundActivities && activitiesSize > 0) {
19132            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19133            for (int j = 0; j < activitiesSize; j++) {
19134                final ActivityRecord r = app.activities.get(j);
19135                if (r.app != app) {
19136                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19137                            + " instead of expected " + app);
19138                    if (r.app == null || (r.app.uid == app.uid)) {
19139                        // Only fix things up when they look sane
19140                        r.app = app;
19141                    } else {
19142                        continue;
19143                    }
19144                }
19145                if (r.visible) {
19146                    // App has a visible activity; only upgrade adjustment.
19147                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19148                        adj = ProcessList.VISIBLE_APP_ADJ;
19149                        app.adjType = "visible";
19150                    }
19151                    if (procState > PROCESS_STATE_CUR_TOP) {
19152                        procState = PROCESS_STATE_CUR_TOP;
19153                    }
19154                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19155                    app.cached = false;
19156                    app.empty = false;
19157                    foregroundActivities = true;
19158                    if (r.task != null && minLayer > 0) {
19159                        final int layer = r.task.mLayerRank;
19160                        if (layer >= 0 && minLayer > layer) {
19161                            minLayer = layer;
19162                        }
19163                    }
19164                    break;
19165                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19166                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19167                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19168                        app.adjType = "pausing";
19169                    }
19170                    if (procState > PROCESS_STATE_CUR_TOP) {
19171                        procState = PROCESS_STATE_CUR_TOP;
19172                    }
19173                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19174                    app.cached = false;
19175                    app.empty = false;
19176                    foregroundActivities = true;
19177                } else if (r.state == ActivityState.STOPPING) {
19178                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19179                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19180                        app.adjType = "stopping";
19181                    }
19182                    // For the process state, we will at this point consider the
19183                    // process to be cached.  It will be cached either as an activity
19184                    // or empty depending on whether the activity is finishing.  We do
19185                    // this so that we can treat the process as cached for purposes of
19186                    // memory trimming (determing current memory level, trim command to
19187                    // send to process) since there can be an arbitrary number of stopping
19188                    // processes and they should soon all go into the cached state.
19189                    if (!r.finishing) {
19190                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19191                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19192                        }
19193                    }
19194                    app.cached = false;
19195                    app.empty = false;
19196                    foregroundActivities = true;
19197                } else {
19198                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19199                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19200                        app.adjType = "cch-act";
19201                    }
19202                }
19203            }
19204            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19205                adj += minLayer;
19206            }
19207        }
19208
19209        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19210                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19211            if (app.foregroundServices) {
19212                // The user is aware of this app, so make it visible.
19213                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19214                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19215                app.cached = false;
19216                app.adjType = "fg-service";
19217                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19218            } else if (app.forcingToForeground != null) {
19219                // The user is aware of this app, so make it visible.
19220                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19221                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19222                app.cached = false;
19223                app.adjType = "force-fg";
19224                app.adjSource = app.forcingToForeground;
19225                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19226            }
19227        }
19228
19229        if (app == mHeavyWeightProcess) {
19230            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19231                // We don't want to kill the current heavy-weight process.
19232                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19233                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19234                app.cached = false;
19235                app.adjType = "heavy";
19236            }
19237            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19238                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19239            }
19240        }
19241
19242        if (app == mHomeProcess) {
19243            if (adj > ProcessList.HOME_APP_ADJ) {
19244                // This process is hosting what we currently consider to be the
19245                // home app, so we don't want to let it go into the background.
19246                adj = ProcessList.HOME_APP_ADJ;
19247                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19248                app.cached = false;
19249                app.adjType = "home";
19250            }
19251            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19252                procState = ActivityManager.PROCESS_STATE_HOME;
19253            }
19254        }
19255
19256        if (app == mPreviousProcess && app.activities.size() > 0) {
19257            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19258                // This was the previous process that showed UI to the user.
19259                // We want to try to keep it around more aggressively, to give
19260                // a good experience around switching between two apps.
19261                adj = ProcessList.PREVIOUS_APP_ADJ;
19262                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19263                app.cached = false;
19264                app.adjType = "previous";
19265            }
19266            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19267                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19268            }
19269        }
19270
19271        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19272                + " reason=" + app.adjType);
19273
19274        // By default, we use the computed adjustment.  It may be changed if
19275        // there are applications dependent on our services or providers, but
19276        // this gives us a baseline and makes sure we don't get into an
19277        // infinite recursion.
19278        app.adjSeq = mAdjSeq;
19279        app.curRawAdj = adj;
19280        app.hasStartedServices = false;
19281
19282        if (mBackupTarget != null && app == mBackupTarget.app) {
19283            // If possible we want to avoid killing apps while they're being backed up
19284            if (adj > ProcessList.BACKUP_APP_ADJ) {
19285                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19286                adj = ProcessList.BACKUP_APP_ADJ;
19287                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19288                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19289                }
19290                app.adjType = "backup";
19291                app.cached = false;
19292            }
19293            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19294                procState = ActivityManager.PROCESS_STATE_BACKUP;
19295            }
19296        }
19297
19298        boolean mayBeTop = false;
19299
19300        for (int is = app.services.size()-1;
19301                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19302                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19303                        || procState > ActivityManager.PROCESS_STATE_TOP);
19304                is--) {
19305            ServiceRecord s = app.services.valueAt(is);
19306            if (s.startRequested) {
19307                app.hasStartedServices = true;
19308                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19309                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19310                }
19311                if (app.hasShownUi && app != mHomeProcess) {
19312                    // If this process has shown some UI, let it immediately
19313                    // go to the LRU list because it may be pretty heavy with
19314                    // UI stuff.  We'll tag it with a label just to help
19315                    // debug and understand what is going on.
19316                    if (adj > ProcessList.SERVICE_ADJ) {
19317                        app.adjType = "cch-started-ui-services";
19318                    }
19319                } else {
19320                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19321                        // This service has seen some activity within
19322                        // recent memory, so we will keep its process ahead
19323                        // of the background processes.
19324                        if (adj > ProcessList.SERVICE_ADJ) {
19325                            adj = ProcessList.SERVICE_ADJ;
19326                            app.adjType = "started-services";
19327                            app.cached = false;
19328                        }
19329                    }
19330                    // If we have let the service slide into the background
19331                    // state, still have some text describing what it is doing
19332                    // even though the service no longer has an impact.
19333                    if (adj > ProcessList.SERVICE_ADJ) {
19334                        app.adjType = "cch-started-services";
19335                    }
19336                }
19337            }
19338
19339            for (int conni = s.connections.size()-1;
19340                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19341                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19342                            || procState > ActivityManager.PROCESS_STATE_TOP);
19343                    conni--) {
19344                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19345                for (int i = 0;
19346                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19347                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19348                                || procState > ActivityManager.PROCESS_STATE_TOP);
19349                        i++) {
19350                    // XXX should compute this based on the max of
19351                    // all connected clients.
19352                    ConnectionRecord cr = clist.get(i);
19353                    if (cr.binding.client == app) {
19354                        // Binding to ourself is not interesting.
19355                        continue;
19356                    }
19357
19358                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19359                        ProcessRecord client = cr.binding.client;
19360                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19361                                TOP_APP, doingAll, now);
19362                        int clientProcState = client.curProcState;
19363                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19364                            // If the other app is cached for any reason, for purposes here
19365                            // we are going to consider it empty.  The specific cached state
19366                            // doesn't propagate except under certain conditions.
19367                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19368                        }
19369                        String adjType = null;
19370                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19371                            // Not doing bind OOM management, so treat
19372                            // this guy more like a started service.
19373                            if (app.hasShownUi && app != mHomeProcess) {
19374                                // If this process has shown some UI, let it immediately
19375                                // go to the LRU list because it may be pretty heavy with
19376                                // UI stuff.  We'll tag it with a label just to help
19377                                // debug and understand what is going on.
19378                                if (adj > clientAdj) {
19379                                    adjType = "cch-bound-ui-services";
19380                                }
19381                                app.cached = false;
19382                                clientAdj = adj;
19383                                clientProcState = procState;
19384                            } else {
19385                                if (now >= (s.lastActivity
19386                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19387                                    // This service has not seen activity within
19388                                    // recent memory, so allow it to drop to the
19389                                    // LRU list if there is no other reason to keep
19390                                    // it around.  We'll also tag it with a label just
19391                                    // to help debug and undertand what is going on.
19392                                    if (adj > clientAdj) {
19393                                        adjType = "cch-bound-services";
19394                                    }
19395                                    clientAdj = adj;
19396                                }
19397                            }
19398                        }
19399                        if (adj > clientAdj) {
19400                            // If this process has recently shown UI, and
19401                            // the process that is binding to it is less
19402                            // important than being visible, then we don't
19403                            // care about the binding as much as we care
19404                            // about letting this process get into the LRU
19405                            // list to be killed and restarted if needed for
19406                            // memory.
19407                            if (app.hasShownUi && app != mHomeProcess
19408                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19409                                adjType = "cch-bound-ui-services";
19410                            } else {
19411                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19412                                        |Context.BIND_IMPORTANT)) != 0) {
19413                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19414                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19415                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19416                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19417                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19418                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19419                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19420                                    adj = clientAdj;
19421                                } else {
19422                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19423                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19424                                    }
19425                                }
19426                                if (!client.cached) {
19427                                    app.cached = false;
19428                                }
19429                                adjType = "service";
19430                            }
19431                        }
19432                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19433                            // This will treat important bound services identically to
19434                            // the top app, which may behave differently than generic
19435                            // foreground work.
19436                            if (client.curSchedGroup > schedGroup) {
19437                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19438                                    schedGroup = client.curSchedGroup;
19439                                } else {
19440                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19441                                }
19442                            }
19443                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19444                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19445                                    // Special handling of clients who are in the top state.
19446                                    // We *may* want to consider this process to be in the
19447                                    // top state as well, but only if there is not another
19448                                    // reason for it to be running.  Being on the top is a
19449                                    // special state, meaning you are specifically running
19450                                    // for the current top app.  If the process is already
19451                                    // running in the background for some other reason, it
19452                                    // is more important to continue considering it to be
19453                                    // in the background state.
19454                                    mayBeTop = true;
19455                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19456                                } else {
19457                                    // Special handling for above-top states (persistent
19458                                    // processes).  These should not bring the current process
19459                                    // into the top state, since they are not on top.  Instead
19460                                    // give them the best state after that.
19461                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19462                                        clientProcState =
19463                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19464                                    } else if (mWakefulness
19465                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19466                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19467                                                    != 0) {
19468                                        clientProcState =
19469                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19470                                    } else {
19471                                        clientProcState =
19472                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19473                                    }
19474                                }
19475                            }
19476                        } else {
19477                            if (clientProcState <
19478                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19479                                clientProcState =
19480                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19481                            }
19482                        }
19483                        if (procState > clientProcState) {
19484                            procState = clientProcState;
19485                        }
19486                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19487                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19488                            app.pendingUiClean = true;
19489                        }
19490                        if (adjType != null) {
19491                            app.adjType = adjType;
19492                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19493                                    .REASON_SERVICE_IN_USE;
19494                            app.adjSource = cr.binding.client;
19495                            app.adjSourceProcState = clientProcState;
19496                            app.adjTarget = s.name;
19497                        }
19498                    }
19499                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19500                        app.treatLikeActivity = true;
19501                    }
19502                    final ActivityRecord a = cr.activity;
19503                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19504                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19505                            (a.visible || a.state == ActivityState.RESUMED ||
19506                             a.state == ActivityState.PAUSING)) {
19507                            adj = ProcessList.FOREGROUND_APP_ADJ;
19508                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19509                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19510                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19511                                } else {
19512                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19513                                }
19514                            }
19515                            app.cached = false;
19516                            app.adjType = "service";
19517                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19518                                    .REASON_SERVICE_IN_USE;
19519                            app.adjSource = a;
19520                            app.adjSourceProcState = procState;
19521                            app.adjTarget = s.name;
19522                        }
19523                    }
19524                }
19525            }
19526        }
19527
19528        for (int provi = app.pubProviders.size()-1;
19529                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19530                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19531                        || procState > ActivityManager.PROCESS_STATE_TOP);
19532                provi--) {
19533            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19534            for (int i = cpr.connections.size()-1;
19535                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19536                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19537                            || procState > ActivityManager.PROCESS_STATE_TOP);
19538                    i--) {
19539                ContentProviderConnection conn = cpr.connections.get(i);
19540                ProcessRecord client = conn.client;
19541                if (client == app) {
19542                    // Being our own client is not interesting.
19543                    continue;
19544                }
19545                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19546                int clientProcState = client.curProcState;
19547                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19548                    // If the other app is cached for any reason, for purposes here
19549                    // we are going to consider it empty.
19550                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19551                }
19552                if (adj > clientAdj) {
19553                    if (app.hasShownUi && app != mHomeProcess
19554                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19555                        app.adjType = "cch-ui-provider";
19556                    } else {
19557                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19558                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19559                        app.adjType = "provider";
19560                    }
19561                    app.cached &= client.cached;
19562                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19563                            .REASON_PROVIDER_IN_USE;
19564                    app.adjSource = client;
19565                    app.adjSourceProcState = clientProcState;
19566                    app.adjTarget = cpr.name;
19567                }
19568                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19569                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19570                        // Special handling of clients who are in the top state.
19571                        // We *may* want to consider this process to be in the
19572                        // top state as well, but only if there is not another
19573                        // reason for it to be running.  Being on the top is a
19574                        // special state, meaning you are specifically running
19575                        // for the current top app.  If the process is already
19576                        // running in the background for some other reason, it
19577                        // is more important to continue considering it to be
19578                        // in the background state.
19579                        mayBeTop = true;
19580                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19581                    } else {
19582                        // Special handling for above-top states (persistent
19583                        // processes).  These should not bring the current process
19584                        // into the top state, since they are not on top.  Instead
19585                        // give them the best state after that.
19586                        clientProcState =
19587                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19588                    }
19589                }
19590                if (procState > clientProcState) {
19591                    procState = clientProcState;
19592                }
19593                if (client.curSchedGroup > schedGroup) {
19594                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19595                }
19596            }
19597            // If the provider has external (non-framework) process
19598            // dependencies, ensure that its adjustment is at least
19599            // FOREGROUND_APP_ADJ.
19600            if (cpr.hasExternalProcessHandles()) {
19601                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19602                    adj = ProcessList.FOREGROUND_APP_ADJ;
19603                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19604                    app.cached = false;
19605                    app.adjType = "provider";
19606                    app.adjTarget = cpr.name;
19607                }
19608                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19609                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19610                }
19611            }
19612        }
19613
19614        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19615            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19616                adj = ProcessList.PREVIOUS_APP_ADJ;
19617                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19618                app.cached = false;
19619                app.adjType = "provider";
19620            }
19621            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19622                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19623            }
19624        }
19625
19626        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19627            // A client of one of our services or providers is in the top state.  We
19628            // *may* want to be in the top state, but not if we are already running in
19629            // the background for some other reason.  For the decision here, we are going
19630            // to pick out a few specific states that we want to remain in when a client
19631            // is top (states that tend to be longer-term) and otherwise allow it to go
19632            // to the top state.
19633            switch (procState) {
19634                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19635                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19636                case ActivityManager.PROCESS_STATE_SERVICE:
19637                    // These all are longer-term states, so pull them up to the top
19638                    // of the background states, but not all the way to the top state.
19639                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19640                    break;
19641                default:
19642                    // Otherwise, top is a better choice, so take it.
19643                    procState = ActivityManager.PROCESS_STATE_TOP;
19644                    break;
19645            }
19646        }
19647
19648        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19649            if (app.hasClientActivities) {
19650                // This is a cached process, but with client activities.  Mark it so.
19651                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19652                app.adjType = "cch-client-act";
19653            } else if (app.treatLikeActivity) {
19654                // This is a cached process, but somebody wants us to treat it like it has
19655                // an activity, okay!
19656                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19657                app.adjType = "cch-as-act";
19658            }
19659        }
19660
19661        if (adj == ProcessList.SERVICE_ADJ) {
19662            if (doingAll) {
19663                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19664                mNewNumServiceProcs++;
19665                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19666                if (!app.serviceb) {
19667                    // This service isn't far enough down on the LRU list to
19668                    // normally be a B service, but if we are low on RAM and it
19669                    // is large we want to force it down since we would prefer to
19670                    // keep launcher over it.
19671                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19672                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19673                        app.serviceHighRam = true;
19674                        app.serviceb = true;
19675                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19676                    } else {
19677                        mNewNumAServiceProcs++;
19678                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19679                    }
19680                } else {
19681                    app.serviceHighRam = false;
19682                }
19683            }
19684            if (app.serviceb) {
19685                adj = ProcessList.SERVICE_B_ADJ;
19686            }
19687        }
19688
19689        app.curRawAdj = adj;
19690
19691        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19692        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19693        if (adj > app.maxAdj) {
19694            adj = app.maxAdj;
19695            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19696                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19697            }
19698        }
19699
19700        // Do final modification to adj.  Everything we do between here and applying
19701        // the final setAdj must be done in this function, because we will also use
19702        // it when computing the final cached adj later.  Note that we don't need to
19703        // worry about this for max adj above, since max adj will always be used to
19704        // keep it out of the cached vaues.
19705        app.curAdj = app.modifyRawOomAdj(adj);
19706        app.curSchedGroup = schedGroup;
19707        app.curProcState = procState;
19708        app.foregroundActivities = foregroundActivities;
19709
19710        return app.curRawAdj;
19711    }
19712
19713    /**
19714     * Record new PSS sample for a process.
19715     */
19716    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19717            long now) {
19718        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19719                swapPss * 1024);
19720        proc.lastPssTime = now;
19721        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19722        if (DEBUG_PSS) Slog.d(TAG_PSS,
19723                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19724                + " state=" + ProcessList.makeProcStateString(procState));
19725        if (proc.initialIdlePss == 0) {
19726            proc.initialIdlePss = pss;
19727        }
19728        proc.lastPss = pss;
19729        proc.lastSwapPss = swapPss;
19730        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19731            proc.lastCachedPss = pss;
19732            proc.lastCachedSwapPss = swapPss;
19733        }
19734
19735        final SparseArray<Pair<Long, String>> watchUids
19736                = mMemWatchProcesses.getMap().get(proc.processName);
19737        Long check = null;
19738        if (watchUids != null) {
19739            Pair<Long, String> val = watchUids.get(proc.uid);
19740            if (val == null) {
19741                val = watchUids.get(0);
19742            }
19743            if (val != null) {
19744                check = val.first;
19745            }
19746        }
19747        if (check != null) {
19748            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19749                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19750                if (!isDebuggable) {
19751                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19752                        isDebuggable = true;
19753                    }
19754                }
19755                if (isDebuggable) {
19756                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19757                    final ProcessRecord myProc = proc;
19758                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19759                    mMemWatchDumpProcName = proc.processName;
19760                    mMemWatchDumpFile = heapdumpFile.toString();
19761                    mMemWatchDumpPid = proc.pid;
19762                    mMemWatchDumpUid = proc.uid;
19763                    BackgroundThread.getHandler().post(new Runnable() {
19764                        @Override
19765                        public void run() {
19766                            revokeUriPermission(ActivityThread.currentActivityThread()
19767                                            .getApplicationThread(),
19768                                    DumpHeapActivity.JAVA_URI,
19769                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19770                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19771                                    UserHandle.myUserId());
19772                            ParcelFileDescriptor fd = null;
19773                            try {
19774                                heapdumpFile.delete();
19775                                fd = ParcelFileDescriptor.open(heapdumpFile,
19776                                        ParcelFileDescriptor.MODE_CREATE |
19777                                                ParcelFileDescriptor.MODE_TRUNCATE |
19778                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19779                                                ParcelFileDescriptor.MODE_APPEND);
19780                                IApplicationThread thread = myProc.thread;
19781                                if (thread != null) {
19782                                    try {
19783                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19784                                                "Requesting dump heap from "
19785                                                + myProc + " to " + heapdumpFile);
19786                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19787                                    } catch (RemoteException e) {
19788                                    }
19789                                }
19790                            } catch (FileNotFoundException e) {
19791                                e.printStackTrace();
19792                            } finally {
19793                                if (fd != null) {
19794                                    try {
19795                                        fd.close();
19796                                    } catch (IOException e) {
19797                                    }
19798                                }
19799                            }
19800                        }
19801                    });
19802                } else {
19803                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19804                            + ", but debugging not enabled");
19805                }
19806            }
19807        }
19808    }
19809
19810    /**
19811     * Schedule PSS collection of a process.
19812     */
19813    void requestPssLocked(ProcessRecord proc, int procState) {
19814        if (mPendingPssProcesses.contains(proc)) {
19815            return;
19816        }
19817        if (mPendingPssProcesses.size() == 0) {
19818            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19819        }
19820        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19821        proc.pssProcState = procState;
19822        mPendingPssProcesses.add(proc);
19823    }
19824
19825    /**
19826     * Schedule PSS collection of all processes.
19827     */
19828    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19829        if (!always) {
19830            if (now < (mLastFullPssTime +
19831                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19832                return;
19833            }
19834        }
19835        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19836        mLastFullPssTime = now;
19837        mFullPssPending = true;
19838        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19839        mPendingPssProcesses.clear();
19840        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19841            ProcessRecord app = mLruProcesses.get(i);
19842            if (app.thread == null
19843                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19844                continue;
19845            }
19846            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19847                app.pssProcState = app.setProcState;
19848                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19849                        mTestPssMode, isSleepingLocked(), now);
19850                mPendingPssProcesses.add(app);
19851            }
19852        }
19853        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19854    }
19855
19856    public void setTestPssMode(boolean enabled) {
19857        synchronized (this) {
19858            mTestPssMode = enabled;
19859            if (enabled) {
19860                // Whenever we enable the mode, we want to take a snapshot all of current
19861                // process mem use.
19862                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19863            }
19864        }
19865    }
19866
19867    /**
19868     * Ask a given process to GC right now.
19869     */
19870    final void performAppGcLocked(ProcessRecord app) {
19871        try {
19872            app.lastRequestedGc = SystemClock.uptimeMillis();
19873            if (app.thread != null) {
19874                if (app.reportLowMemory) {
19875                    app.reportLowMemory = false;
19876                    app.thread.scheduleLowMemory();
19877                } else {
19878                    app.thread.processInBackground();
19879                }
19880            }
19881        } catch (Exception e) {
19882            // whatever.
19883        }
19884    }
19885
19886    /**
19887     * Returns true if things are idle enough to perform GCs.
19888     */
19889    private final boolean canGcNowLocked() {
19890        boolean processingBroadcasts = false;
19891        for (BroadcastQueue q : mBroadcastQueues) {
19892            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19893                processingBroadcasts = true;
19894            }
19895        }
19896        return !processingBroadcasts
19897                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19898    }
19899
19900    /**
19901     * Perform GCs on all processes that are waiting for it, but only
19902     * if things are idle.
19903     */
19904    final void performAppGcsLocked() {
19905        final int N = mProcessesToGc.size();
19906        if (N <= 0) {
19907            return;
19908        }
19909        if (canGcNowLocked()) {
19910            while (mProcessesToGc.size() > 0) {
19911                ProcessRecord proc = mProcessesToGc.remove(0);
19912                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19913                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19914                            <= SystemClock.uptimeMillis()) {
19915                        // To avoid spamming the system, we will GC processes one
19916                        // at a time, waiting a few seconds between each.
19917                        performAppGcLocked(proc);
19918                        scheduleAppGcsLocked();
19919                        return;
19920                    } else {
19921                        // It hasn't been long enough since we last GCed this
19922                        // process...  put it in the list to wait for its time.
19923                        addProcessToGcListLocked(proc);
19924                        break;
19925                    }
19926                }
19927            }
19928
19929            scheduleAppGcsLocked();
19930        }
19931    }
19932
19933    /**
19934     * If all looks good, perform GCs on all processes waiting for them.
19935     */
19936    final void performAppGcsIfAppropriateLocked() {
19937        if (canGcNowLocked()) {
19938            performAppGcsLocked();
19939            return;
19940        }
19941        // Still not idle, wait some more.
19942        scheduleAppGcsLocked();
19943    }
19944
19945    /**
19946     * Schedule the execution of all pending app GCs.
19947     */
19948    final void scheduleAppGcsLocked() {
19949        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19950
19951        if (mProcessesToGc.size() > 0) {
19952            // Schedule a GC for the time to the next process.
19953            ProcessRecord proc = mProcessesToGc.get(0);
19954            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19955
19956            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19957            long now = SystemClock.uptimeMillis();
19958            if (when < (now+GC_TIMEOUT)) {
19959                when = now + GC_TIMEOUT;
19960            }
19961            mHandler.sendMessageAtTime(msg, when);
19962        }
19963    }
19964
19965    /**
19966     * Add a process to the array of processes waiting to be GCed.  Keeps the
19967     * list in sorted order by the last GC time.  The process can't already be
19968     * on the list.
19969     */
19970    final void addProcessToGcListLocked(ProcessRecord proc) {
19971        boolean added = false;
19972        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19973            if (mProcessesToGc.get(i).lastRequestedGc <
19974                    proc.lastRequestedGc) {
19975                added = true;
19976                mProcessesToGc.add(i+1, proc);
19977                break;
19978            }
19979        }
19980        if (!added) {
19981            mProcessesToGc.add(0, proc);
19982        }
19983    }
19984
19985    /**
19986     * Set up to ask a process to GC itself.  This will either do it
19987     * immediately, or put it on the list of processes to gc the next
19988     * time things are idle.
19989     */
19990    final void scheduleAppGcLocked(ProcessRecord app) {
19991        long now = SystemClock.uptimeMillis();
19992        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19993            return;
19994        }
19995        if (!mProcessesToGc.contains(app)) {
19996            addProcessToGcListLocked(app);
19997            scheduleAppGcsLocked();
19998        }
19999    }
20000
20001    final void checkExcessivePowerUsageLocked(boolean doKills) {
20002        updateCpuStatsNow();
20003
20004        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20005        boolean doWakeKills = doKills;
20006        boolean doCpuKills = doKills;
20007        if (mLastPowerCheckRealtime == 0) {
20008            doWakeKills = false;
20009        }
20010        if (mLastPowerCheckUptime == 0) {
20011            doCpuKills = false;
20012        }
20013        if (stats.isScreenOn()) {
20014            doWakeKills = false;
20015        }
20016        final long curRealtime = SystemClock.elapsedRealtime();
20017        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20018        final long curUptime = SystemClock.uptimeMillis();
20019        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20020        mLastPowerCheckRealtime = curRealtime;
20021        mLastPowerCheckUptime = curUptime;
20022        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20023            doWakeKills = false;
20024        }
20025        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20026            doCpuKills = false;
20027        }
20028        int i = mLruProcesses.size();
20029        while (i > 0) {
20030            i--;
20031            ProcessRecord app = mLruProcesses.get(i);
20032            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20033                long wtime;
20034                synchronized (stats) {
20035                    wtime = stats.getProcessWakeTime(app.info.uid,
20036                            app.pid, curRealtime);
20037                }
20038                long wtimeUsed = wtime - app.lastWakeTime;
20039                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20040                if (DEBUG_POWER) {
20041                    StringBuilder sb = new StringBuilder(128);
20042                    sb.append("Wake for ");
20043                    app.toShortString(sb);
20044                    sb.append(": over ");
20045                    TimeUtils.formatDuration(realtimeSince, sb);
20046                    sb.append(" used ");
20047                    TimeUtils.formatDuration(wtimeUsed, sb);
20048                    sb.append(" (");
20049                    sb.append((wtimeUsed*100)/realtimeSince);
20050                    sb.append("%)");
20051                    Slog.i(TAG_POWER, sb.toString());
20052                    sb.setLength(0);
20053                    sb.append("CPU for ");
20054                    app.toShortString(sb);
20055                    sb.append(": over ");
20056                    TimeUtils.formatDuration(uptimeSince, sb);
20057                    sb.append(" used ");
20058                    TimeUtils.formatDuration(cputimeUsed, sb);
20059                    sb.append(" (");
20060                    sb.append((cputimeUsed*100)/uptimeSince);
20061                    sb.append("%)");
20062                    Slog.i(TAG_POWER, sb.toString());
20063                }
20064                // If a process has held a wake lock for more
20065                // than 50% of the time during this period,
20066                // that sounds bad.  Kill!
20067                if (doWakeKills && realtimeSince > 0
20068                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20069                    synchronized (stats) {
20070                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20071                                realtimeSince, wtimeUsed);
20072                    }
20073                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20074                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20075                } else if (doCpuKills && uptimeSince > 0
20076                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20077                    synchronized (stats) {
20078                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20079                                uptimeSince, cputimeUsed);
20080                    }
20081                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20082                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20083                } else {
20084                    app.lastWakeTime = wtime;
20085                    app.lastCpuTime = app.curCpuTime;
20086                }
20087            }
20088        }
20089    }
20090
20091    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20092            long nowElapsed) {
20093        boolean success = true;
20094
20095        if (app.curRawAdj != app.setRawAdj) {
20096            app.setRawAdj = app.curRawAdj;
20097        }
20098
20099        int changes = 0;
20100
20101        if (app.curAdj != app.setAdj) {
20102            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20103            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20104                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20105                    + app.adjType);
20106            app.setAdj = app.curAdj;
20107            app.verifiedAdj = ProcessList.INVALID_ADJ;
20108        }
20109
20110        if (app.setSchedGroup != app.curSchedGroup) {
20111            app.setSchedGroup = app.curSchedGroup;
20112            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20113                    "Setting sched group of " + app.processName
20114                    + " to " + app.curSchedGroup);
20115            if (app.waitingToKill != null && app.curReceiver == null
20116                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20117                app.kill(app.waitingToKill, true);
20118                success = false;
20119            } else {
20120                int processGroup;
20121                switch (app.curSchedGroup) {
20122                    case ProcessList.SCHED_GROUP_BACKGROUND:
20123                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20124                        break;
20125                    case ProcessList.SCHED_GROUP_TOP_APP:
20126                        processGroup = Process.THREAD_GROUP_TOP_APP;
20127                        break;
20128                    default:
20129                        processGroup = Process.THREAD_GROUP_DEFAULT;
20130                        break;
20131                }
20132                if (true) {
20133                    long oldId = Binder.clearCallingIdentity();
20134                    try {
20135                        Process.setProcessGroup(app.pid, processGroup);
20136                    } catch (Exception e) {
20137                        Slog.w(TAG, "Failed setting process group of " + app.pid
20138                                + " to " + app.curSchedGroup);
20139                        e.printStackTrace();
20140                    } finally {
20141                        Binder.restoreCallingIdentity(oldId);
20142                    }
20143                } else {
20144                    if (app.thread != null) {
20145                        try {
20146                            app.thread.setSchedulingGroup(processGroup);
20147                        } catch (RemoteException e) {
20148                        }
20149                    }
20150                }
20151            }
20152        }
20153        if (app.repForegroundActivities != app.foregroundActivities) {
20154            app.repForegroundActivities = app.foregroundActivities;
20155            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20156        }
20157        if (app.repProcState != app.curProcState) {
20158            app.repProcState = app.curProcState;
20159            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20160            if (app.thread != null) {
20161                try {
20162                    if (false) {
20163                        //RuntimeException h = new RuntimeException("here");
20164                        Slog.i(TAG, "Sending new process state " + app.repProcState
20165                                + " to " + app /*, h*/);
20166                    }
20167                    app.thread.setProcessState(app.repProcState);
20168                } catch (RemoteException e) {
20169                }
20170            }
20171        }
20172        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20173                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20174            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20175                // Experimental code to more aggressively collect pss while
20176                // running test...  the problem is that this tends to collect
20177                // the data right when a process is transitioning between process
20178                // states, which well tend to give noisy data.
20179                long start = SystemClock.uptimeMillis();
20180                long pss = Debug.getPss(app.pid, mTmpLong, null);
20181                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20182                mPendingPssProcesses.remove(app);
20183                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20184                        + " to " + app.curProcState + ": "
20185                        + (SystemClock.uptimeMillis()-start) + "ms");
20186            }
20187            app.lastStateTime = now;
20188            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20189                    mTestPssMode, isSleepingLocked(), now);
20190            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20191                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20192                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20193                    + (app.nextPssTime-now) + ": " + app);
20194        } else {
20195            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20196                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20197                    mTestPssMode)))) {
20198                requestPssLocked(app, app.setProcState);
20199                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20200                        mTestPssMode, isSleepingLocked(), now);
20201            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20202                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20203        }
20204        if (app.setProcState != app.curProcState) {
20205            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20206                    "Proc state change of " + app.processName
20207                            + " to " + app.curProcState);
20208            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20209            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20210            if (setImportant && !curImportant) {
20211                // This app is no longer something we consider important enough to allow to
20212                // use arbitrary amounts of battery power.  Note
20213                // its current wake lock time to later know to kill it if
20214                // it is not behaving well.
20215                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20216                synchronized (stats) {
20217                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20218                            app.pid, nowElapsed);
20219                }
20220                app.lastCpuTime = app.curCpuTime;
20221
20222            }
20223            // Inform UsageStats of important process state change
20224            // Must be called before updating setProcState
20225            maybeUpdateUsageStatsLocked(app, nowElapsed);
20226
20227            app.setProcState = app.curProcState;
20228            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20229                app.notCachedSinceIdle = false;
20230            }
20231            if (!doingAll) {
20232                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20233            } else {
20234                app.procStateChanged = true;
20235            }
20236        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20237                > USAGE_STATS_INTERACTION_INTERVAL) {
20238            // For apps that sit around for a long time in the interactive state, we need
20239            // to report this at least once a day so they don't go idle.
20240            maybeUpdateUsageStatsLocked(app, nowElapsed);
20241        }
20242
20243        if (changes != 0) {
20244            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20245                    "Changes in " + app + ": " + changes);
20246            int i = mPendingProcessChanges.size()-1;
20247            ProcessChangeItem item = null;
20248            while (i >= 0) {
20249                item = mPendingProcessChanges.get(i);
20250                if (item.pid == app.pid) {
20251                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20252                            "Re-using existing item: " + item);
20253                    break;
20254                }
20255                i--;
20256            }
20257            if (i < 0) {
20258                // No existing item in pending changes; need a new one.
20259                final int NA = mAvailProcessChanges.size();
20260                if (NA > 0) {
20261                    item = mAvailProcessChanges.remove(NA-1);
20262                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20263                            "Retrieving available item: " + item);
20264                } else {
20265                    item = new ProcessChangeItem();
20266                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20267                            "Allocating new item: " + item);
20268                }
20269                item.changes = 0;
20270                item.pid = app.pid;
20271                item.uid = app.info.uid;
20272                if (mPendingProcessChanges.size() == 0) {
20273                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20274                            "*** Enqueueing dispatch processes changed!");
20275                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20276                }
20277                mPendingProcessChanges.add(item);
20278            }
20279            item.changes |= changes;
20280            item.processState = app.repProcState;
20281            item.foregroundActivities = app.repForegroundActivities;
20282            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20283                    "Item " + Integer.toHexString(System.identityHashCode(item))
20284                    + " " + app.toShortString() + ": changes=" + item.changes
20285                    + " procState=" + item.processState
20286                    + " foreground=" + item.foregroundActivities
20287                    + " type=" + app.adjType + " source=" + app.adjSource
20288                    + " target=" + app.adjTarget);
20289        }
20290
20291        return success;
20292    }
20293
20294    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20295        final UidRecord.ChangeItem pendingChange;
20296        if (uidRec == null || uidRec.pendingChange == null) {
20297            if (mPendingUidChanges.size() == 0) {
20298                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20299                        "*** Enqueueing dispatch uid changed!");
20300                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20301            }
20302            final int NA = mAvailUidChanges.size();
20303            if (NA > 0) {
20304                pendingChange = mAvailUidChanges.remove(NA-1);
20305                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20306                        "Retrieving available item: " + pendingChange);
20307            } else {
20308                pendingChange = new UidRecord.ChangeItem();
20309                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20310                        "Allocating new item: " + pendingChange);
20311            }
20312            if (uidRec != null) {
20313                uidRec.pendingChange = pendingChange;
20314                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20315                    // If this uid is going away, and we haven't yet reported it is gone,
20316                    // then do so now.
20317                    change = UidRecord.CHANGE_GONE_IDLE;
20318                }
20319            } else if (uid < 0) {
20320                throw new IllegalArgumentException("No UidRecord or uid");
20321            }
20322            pendingChange.uidRecord = uidRec;
20323            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20324            mPendingUidChanges.add(pendingChange);
20325        } else {
20326            pendingChange = uidRec.pendingChange;
20327            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20328                change = UidRecord.CHANGE_GONE_IDLE;
20329            }
20330        }
20331        pendingChange.change = change;
20332        pendingChange.processState = uidRec != null
20333                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20334    }
20335
20336    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20337            String authority) {
20338        if (app == null) return;
20339        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20340            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20341            if (userState == null) return;
20342            final long now = SystemClock.elapsedRealtime();
20343            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20344            if (lastReported == null || lastReported < now - 60 * 1000L) {
20345                mUsageStatsService.reportContentProviderUsage(
20346                        authority, providerPkgName, app.userId);
20347                userState.mProviderLastReportedFg.put(authority, now);
20348            }
20349        }
20350    }
20351
20352    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20353        if (DEBUG_USAGE_STATS) {
20354            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20355                    + "] state changes: old = " + app.setProcState + ", new = "
20356                    + app.curProcState);
20357        }
20358        if (mUsageStatsService == null) {
20359            return;
20360        }
20361        boolean isInteraction;
20362        // To avoid some abuse patterns, we are going to be careful about what we consider
20363        // to be an app interaction.  Being the top activity doesn't count while the display
20364        // is sleeping, nor do short foreground services.
20365        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20366            isInteraction = true;
20367            app.fgInteractionTime = 0;
20368        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20369            if (app.fgInteractionTime == 0) {
20370                app.fgInteractionTime = nowElapsed;
20371                isInteraction = false;
20372            } else {
20373                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20374            }
20375        } else {
20376            isInteraction = app.curProcState
20377                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20378            app.fgInteractionTime = 0;
20379        }
20380        if (isInteraction && (!app.reportedInteraction
20381                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20382            app.interactionEventTime = nowElapsed;
20383            String[] packages = app.getPackageList();
20384            if (packages != null) {
20385                for (int i = 0; i < packages.length; i++) {
20386                    mUsageStatsService.reportEvent(packages[i], app.userId,
20387                            UsageEvents.Event.SYSTEM_INTERACTION);
20388                }
20389            }
20390        }
20391        app.reportedInteraction = isInteraction;
20392        if (!isInteraction) {
20393            app.interactionEventTime = 0;
20394        }
20395    }
20396
20397    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20398        if (proc.thread != null) {
20399            if (proc.baseProcessTracker != null) {
20400                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20401            }
20402        }
20403    }
20404
20405    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20406            ProcessRecord TOP_APP, boolean doingAll, long now) {
20407        if (app.thread == null) {
20408            return false;
20409        }
20410
20411        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20412
20413        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20414    }
20415
20416    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20417            boolean oomAdj) {
20418        if (isForeground != proc.foregroundServices) {
20419            proc.foregroundServices = isForeground;
20420            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20421                    proc.info.uid);
20422            if (isForeground) {
20423                if (curProcs == null) {
20424                    curProcs = new ArrayList<ProcessRecord>();
20425                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20426                }
20427                if (!curProcs.contains(proc)) {
20428                    curProcs.add(proc);
20429                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20430                            proc.info.packageName, proc.info.uid);
20431                }
20432            } else {
20433                if (curProcs != null) {
20434                    if (curProcs.remove(proc)) {
20435                        mBatteryStatsService.noteEvent(
20436                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20437                                proc.info.packageName, proc.info.uid);
20438                        if (curProcs.size() <= 0) {
20439                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20440                        }
20441                    }
20442                }
20443            }
20444            if (oomAdj) {
20445                updateOomAdjLocked();
20446            }
20447        }
20448    }
20449
20450    private final ActivityRecord resumedAppLocked() {
20451        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20452        String pkg;
20453        int uid;
20454        if (act != null) {
20455            pkg = act.packageName;
20456            uid = act.info.applicationInfo.uid;
20457        } else {
20458            pkg = null;
20459            uid = -1;
20460        }
20461        // Has the UID or resumed package name changed?
20462        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20463                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20464            if (mCurResumedPackage != null) {
20465                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20466                        mCurResumedPackage, mCurResumedUid);
20467            }
20468            mCurResumedPackage = pkg;
20469            mCurResumedUid = uid;
20470            if (mCurResumedPackage != null) {
20471                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20472                        mCurResumedPackage, mCurResumedUid);
20473            }
20474        }
20475        return act;
20476    }
20477
20478    final boolean updateOomAdjLocked(ProcessRecord app) {
20479        final ActivityRecord TOP_ACT = resumedAppLocked();
20480        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20481        final boolean wasCached = app.cached;
20482
20483        mAdjSeq++;
20484
20485        // This is the desired cached adjusment we want to tell it to use.
20486        // If our app is currently cached, we know it, and that is it.  Otherwise,
20487        // we don't know it yet, and it needs to now be cached we will then
20488        // need to do a complete oom adj.
20489        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20490                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20491        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20492                SystemClock.uptimeMillis());
20493        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20494            // Changed to/from cached state, so apps after it in the LRU
20495            // list may also be changed.
20496            updateOomAdjLocked();
20497        }
20498        return success;
20499    }
20500
20501    final void updateOomAdjLocked() {
20502        final ActivityRecord TOP_ACT = resumedAppLocked();
20503        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20504        final long now = SystemClock.uptimeMillis();
20505        final long nowElapsed = SystemClock.elapsedRealtime();
20506        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20507        final int N = mLruProcesses.size();
20508
20509        if (false) {
20510            RuntimeException e = new RuntimeException();
20511            e.fillInStackTrace();
20512            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20513        }
20514
20515        // Reset state in all uid records.
20516        for (int i=mActiveUids.size()-1; i>=0; i--) {
20517            final UidRecord uidRec = mActiveUids.valueAt(i);
20518            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20519                    "Starting update of " + uidRec);
20520            uidRec.reset();
20521        }
20522
20523        mStackSupervisor.rankTaskLayersIfNeeded();
20524
20525        mAdjSeq++;
20526        mNewNumServiceProcs = 0;
20527        mNewNumAServiceProcs = 0;
20528
20529        final int emptyProcessLimit;
20530        final int cachedProcessLimit;
20531        if (mProcessLimit <= 0) {
20532            emptyProcessLimit = cachedProcessLimit = 0;
20533        } else if (mProcessLimit == 1) {
20534            emptyProcessLimit = 1;
20535            cachedProcessLimit = 0;
20536        } else {
20537            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20538            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20539        }
20540
20541        // Let's determine how many processes we have running vs.
20542        // how many slots we have for background processes; we may want
20543        // to put multiple processes in a slot of there are enough of
20544        // them.
20545        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20546                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20547        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20548        if (numEmptyProcs > cachedProcessLimit) {
20549            // If there are more empty processes than our limit on cached
20550            // processes, then use the cached process limit for the factor.
20551            // This ensures that the really old empty processes get pushed
20552            // down to the bottom, so if we are running low on memory we will
20553            // have a better chance at keeping around more cached processes
20554            // instead of a gazillion empty processes.
20555            numEmptyProcs = cachedProcessLimit;
20556        }
20557        int emptyFactor = numEmptyProcs/numSlots;
20558        if (emptyFactor < 1) emptyFactor = 1;
20559        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20560        if (cachedFactor < 1) cachedFactor = 1;
20561        int stepCached = 0;
20562        int stepEmpty = 0;
20563        int numCached = 0;
20564        int numEmpty = 0;
20565        int numTrimming = 0;
20566
20567        mNumNonCachedProcs = 0;
20568        mNumCachedHiddenProcs = 0;
20569
20570        // First update the OOM adjustment for each of the
20571        // application processes based on their current state.
20572        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20573        int nextCachedAdj = curCachedAdj+1;
20574        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20575        int nextEmptyAdj = curEmptyAdj+2;
20576        for (int i=N-1; i>=0; i--) {
20577            ProcessRecord app = mLruProcesses.get(i);
20578            if (!app.killedByAm && app.thread != null) {
20579                app.procStateChanged = false;
20580                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20581
20582                // If we haven't yet assigned the final cached adj
20583                // to the process, do that now.
20584                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20585                    switch (app.curProcState) {
20586                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20587                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20588                            // This process is a cached process holding activities...
20589                            // assign it the next cached value for that type, and then
20590                            // step that cached level.
20591                            app.curRawAdj = curCachedAdj;
20592                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20593                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20594                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20595                                    + ")");
20596                            if (curCachedAdj != nextCachedAdj) {
20597                                stepCached++;
20598                                if (stepCached >= cachedFactor) {
20599                                    stepCached = 0;
20600                                    curCachedAdj = nextCachedAdj;
20601                                    nextCachedAdj += 2;
20602                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20603                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20604                                    }
20605                                }
20606                            }
20607                            break;
20608                        default:
20609                            // For everything else, assign next empty cached process
20610                            // level and bump that up.  Note that this means that
20611                            // long-running services that have dropped down to the
20612                            // cached level will be treated as empty (since their process
20613                            // state is still as a service), which is what we want.
20614                            app.curRawAdj = curEmptyAdj;
20615                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20616                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20617                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20618                                    + ")");
20619                            if (curEmptyAdj != nextEmptyAdj) {
20620                                stepEmpty++;
20621                                if (stepEmpty >= emptyFactor) {
20622                                    stepEmpty = 0;
20623                                    curEmptyAdj = nextEmptyAdj;
20624                                    nextEmptyAdj += 2;
20625                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20626                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20627                                    }
20628                                }
20629                            }
20630                            break;
20631                    }
20632                }
20633
20634                applyOomAdjLocked(app, true, now, nowElapsed);
20635
20636                // Count the number of process types.
20637                switch (app.curProcState) {
20638                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20639                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20640                        mNumCachedHiddenProcs++;
20641                        numCached++;
20642                        if (numCached > cachedProcessLimit) {
20643                            app.kill("cached #" + numCached, true);
20644                        }
20645                        break;
20646                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20647                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20648                                && app.lastActivityTime < oldTime) {
20649                            app.kill("empty for "
20650                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20651                                    / 1000) + "s", true);
20652                        } else {
20653                            numEmpty++;
20654                            if (numEmpty > emptyProcessLimit) {
20655                                app.kill("empty #" + numEmpty, true);
20656                            }
20657                        }
20658                        break;
20659                    default:
20660                        mNumNonCachedProcs++;
20661                        break;
20662                }
20663
20664                if (app.isolated && app.services.size() <= 0) {
20665                    // If this is an isolated process, and there are no
20666                    // services running in it, then the process is no longer
20667                    // needed.  We agressively kill these because we can by
20668                    // definition not re-use the same process again, and it is
20669                    // good to avoid having whatever code was running in them
20670                    // left sitting around after no longer needed.
20671                    app.kill("isolated not needed", true);
20672                } else {
20673                    // Keeping this process, update its uid.
20674                    final UidRecord uidRec = app.uidRecord;
20675                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20676                        uidRec.curProcState = app.curProcState;
20677                    }
20678                }
20679
20680                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20681                        && !app.killedByAm) {
20682                    numTrimming++;
20683                }
20684            }
20685        }
20686
20687        mNumServiceProcs = mNewNumServiceProcs;
20688
20689        // Now determine the memory trimming level of background processes.
20690        // Unfortunately we need to start at the back of the list to do this
20691        // properly.  We only do this if the number of background apps we
20692        // are managing to keep around is less than half the maximum we desire;
20693        // if we are keeping a good number around, we'll let them use whatever
20694        // memory they want.
20695        final int numCachedAndEmpty = numCached + numEmpty;
20696        int memFactor;
20697        if (numCached <= ProcessList.TRIM_CACHED_APPS
20698                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20699            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20700                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20701            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20702                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20703            } else {
20704                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20705            }
20706        } else {
20707            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20708        }
20709        // We always allow the memory level to go up (better).  We only allow it to go
20710        // down if we are in a state where that is allowed, *and* the total number of processes
20711        // has gone down since last time.
20712        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20713                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20714                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20715        if (memFactor > mLastMemoryLevel) {
20716            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20717                memFactor = mLastMemoryLevel;
20718                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20719            }
20720        }
20721        if (memFactor != mLastMemoryLevel) {
20722            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20723        }
20724        mLastMemoryLevel = memFactor;
20725        mLastNumProcesses = mLruProcesses.size();
20726        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20727        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20728        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20729            if (mLowRamStartTime == 0) {
20730                mLowRamStartTime = now;
20731            }
20732            int step = 0;
20733            int fgTrimLevel;
20734            switch (memFactor) {
20735                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20736                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20737                    break;
20738                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20739                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20740                    break;
20741                default:
20742                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20743                    break;
20744            }
20745            int factor = numTrimming/3;
20746            int minFactor = 2;
20747            if (mHomeProcess != null) minFactor++;
20748            if (mPreviousProcess != null) minFactor++;
20749            if (factor < minFactor) factor = minFactor;
20750            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20751            for (int i=N-1; i>=0; i--) {
20752                ProcessRecord app = mLruProcesses.get(i);
20753                if (allChanged || app.procStateChanged) {
20754                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20755                    app.procStateChanged = false;
20756                }
20757                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20758                        && !app.killedByAm) {
20759                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20760                        try {
20761                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20762                                    "Trimming memory of " + app.processName + " to " + curLevel);
20763                            app.thread.scheduleTrimMemory(curLevel);
20764                        } catch (RemoteException e) {
20765                        }
20766                        if (false) {
20767                            // For now we won't do this; our memory trimming seems
20768                            // to be good enough at this point that destroying
20769                            // activities causes more harm than good.
20770                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20771                                    && app != mHomeProcess && app != mPreviousProcess) {
20772                                // Need to do this on its own message because the stack may not
20773                                // be in a consistent state at this point.
20774                                // For these apps we will also finish their activities
20775                                // to help them free memory.
20776                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20777                            }
20778                        }
20779                    }
20780                    app.trimMemoryLevel = curLevel;
20781                    step++;
20782                    if (step >= factor) {
20783                        step = 0;
20784                        switch (curLevel) {
20785                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20786                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20787                                break;
20788                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20789                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20790                                break;
20791                        }
20792                    }
20793                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20794                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20795                            && app.thread != null) {
20796                        try {
20797                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20798                                    "Trimming memory of heavy-weight " + app.processName
20799                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20800                            app.thread.scheduleTrimMemory(
20801                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20802                        } catch (RemoteException e) {
20803                        }
20804                    }
20805                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20806                } else {
20807                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20808                            || app.systemNoUi) && app.pendingUiClean) {
20809                        // If this application is now in the background and it
20810                        // had done UI, then give it the special trim level to
20811                        // have it free UI resources.
20812                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20813                        if (app.trimMemoryLevel < level && app.thread != null) {
20814                            try {
20815                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20816                                        "Trimming memory of bg-ui " + app.processName
20817                                        + " to " + level);
20818                                app.thread.scheduleTrimMemory(level);
20819                            } catch (RemoteException e) {
20820                            }
20821                        }
20822                        app.pendingUiClean = false;
20823                    }
20824                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20825                        try {
20826                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20827                                    "Trimming memory of fg " + app.processName
20828                                    + " to " + fgTrimLevel);
20829                            app.thread.scheduleTrimMemory(fgTrimLevel);
20830                        } catch (RemoteException e) {
20831                        }
20832                    }
20833                    app.trimMemoryLevel = fgTrimLevel;
20834                }
20835            }
20836        } else {
20837            if (mLowRamStartTime != 0) {
20838                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20839                mLowRamStartTime = 0;
20840            }
20841            for (int i=N-1; i>=0; i--) {
20842                ProcessRecord app = mLruProcesses.get(i);
20843                if (allChanged || app.procStateChanged) {
20844                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20845                    app.procStateChanged = false;
20846                }
20847                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20848                        || app.systemNoUi) && app.pendingUiClean) {
20849                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20850                            && app.thread != null) {
20851                        try {
20852                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20853                                    "Trimming memory of ui hidden " + app.processName
20854                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20855                            app.thread.scheduleTrimMemory(
20856                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20857                        } catch (RemoteException e) {
20858                        }
20859                    }
20860                    app.pendingUiClean = false;
20861                }
20862                app.trimMemoryLevel = 0;
20863            }
20864        }
20865
20866        if (mAlwaysFinishActivities) {
20867            // Need to do this on its own message because the stack may not
20868            // be in a consistent state at this point.
20869            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20870        }
20871
20872        if (allChanged) {
20873            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20874        }
20875
20876        // Update from any uid changes.
20877        for (int i=mActiveUids.size()-1; i>=0; i--) {
20878            final UidRecord uidRec = mActiveUids.valueAt(i);
20879            int uidChange = UidRecord.CHANGE_PROCSTATE;
20880            if (uidRec.setProcState != uidRec.curProcState) {
20881                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20882                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20883                        + " to " + uidRec.curProcState);
20884                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20885                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20886                        uidRec.lastBackgroundTime = nowElapsed;
20887                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20888                            // Note: the background settle time is in elapsed realtime, while
20889                            // the handler time base is uptime.  All this means is that we may
20890                            // stop background uids later than we had intended, but that only
20891                            // happens because the device was sleeping so we are okay anyway.
20892                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20893                        }
20894                    }
20895                } else {
20896                    if (uidRec.idle) {
20897                        uidChange = UidRecord.CHANGE_ACTIVE;
20898                        uidRec.idle = false;
20899                    }
20900                    uidRec.lastBackgroundTime = 0;
20901                }
20902                uidRec.setProcState = uidRec.curProcState;
20903                enqueueUidChangeLocked(uidRec, -1, uidChange);
20904                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20905            }
20906        }
20907
20908        if (mProcessStats.shouldWriteNowLocked(now)) {
20909            mHandler.post(new Runnable() {
20910                @Override public void run() {
20911                    synchronized (ActivityManagerService.this) {
20912                        mProcessStats.writeStateAsyncLocked();
20913                    }
20914                }
20915            });
20916        }
20917
20918        if (DEBUG_OOM_ADJ) {
20919            final long duration = SystemClock.uptimeMillis() - now;
20920            if (false) {
20921                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20922                        new RuntimeException("here").fillInStackTrace());
20923            } else {
20924                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20925            }
20926        }
20927    }
20928
20929    final void idleUids() {
20930        synchronized (this) {
20931            final long nowElapsed = SystemClock.elapsedRealtime();
20932            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20933            long nextTime = 0;
20934            for (int i=mActiveUids.size()-1; i>=0; i--) {
20935                final UidRecord uidRec = mActiveUids.valueAt(i);
20936                final long bgTime = uidRec.lastBackgroundTime;
20937                if (bgTime > 0 && !uidRec.idle) {
20938                    if (bgTime <= maxBgTime) {
20939                        uidRec.idle = true;
20940                        doStopUidLocked(uidRec.uid, uidRec);
20941                    } else {
20942                        if (nextTime == 0 || nextTime > bgTime) {
20943                            nextTime = bgTime;
20944                        }
20945                    }
20946                }
20947            }
20948            if (nextTime > 0) {
20949                mHandler.removeMessages(IDLE_UIDS_MSG);
20950                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20951                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20952            }
20953        }
20954    }
20955
20956    final void runInBackgroundDisabled(int uid) {
20957        synchronized (this) {
20958            UidRecord uidRec = mActiveUids.get(uid);
20959            if (uidRec != null) {
20960                // This uid is actually running...  should it be considered background now?
20961                if (uidRec.idle) {
20962                    doStopUidLocked(uidRec.uid, uidRec);
20963                }
20964            } else {
20965                // This uid isn't actually running...  still send a report about it being "stopped".
20966                doStopUidLocked(uid, null);
20967            }
20968        }
20969    }
20970
20971    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20972        mServices.stopInBackgroundLocked(uid);
20973        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20974    }
20975
20976    final void trimApplications() {
20977        synchronized (this) {
20978            int i;
20979
20980            // First remove any unused application processes whose package
20981            // has been removed.
20982            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20983                final ProcessRecord app = mRemovedProcesses.get(i);
20984                if (app.activities.size() == 0
20985                        && app.curReceiver == null && app.services.size() == 0) {
20986                    Slog.i(
20987                        TAG, "Exiting empty application process "
20988                        + app.toShortString() + " ("
20989                        + (app.thread != null ? app.thread.asBinder() : null)
20990                        + ")\n");
20991                    if (app.pid > 0 && app.pid != MY_PID) {
20992                        app.kill("empty", false);
20993                    } else {
20994                        try {
20995                            app.thread.scheduleExit();
20996                        } catch (Exception e) {
20997                            // Ignore exceptions.
20998                        }
20999                    }
21000                    cleanUpApplicationRecordLocked(app, false, true, -1);
21001                    mRemovedProcesses.remove(i);
21002
21003                    if (app.persistent) {
21004                        addAppLocked(app.info, false, null /* ABI override */);
21005                    }
21006                }
21007            }
21008
21009            // Now update the oom adj for all processes.
21010            updateOomAdjLocked();
21011        }
21012    }
21013
21014    /** This method sends the specified signal to each of the persistent apps */
21015    public void signalPersistentProcesses(int sig) throws RemoteException {
21016        if (sig != Process.SIGNAL_USR1) {
21017            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21018        }
21019
21020        synchronized (this) {
21021            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21022                    != PackageManager.PERMISSION_GRANTED) {
21023                throw new SecurityException("Requires permission "
21024                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21025            }
21026
21027            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21028                ProcessRecord r = mLruProcesses.get(i);
21029                if (r.thread != null && r.persistent) {
21030                    Process.sendSignal(r.pid, sig);
21031                }
21032            }
21033        }
21034    }
21035
21036    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21037        if (proc == null || proc == mProfileProc) {
21038            proc = mProfileProc;
21039            profileType = mProfileType;
21040            clearProfilerLocked();
21041        }
21042        if (proc == null) {
21043            return;
21044        }
21045        try {
21046            proc.thread.profilerControl(false, null, profileType);
21047        } catch (RemoteException e) {
21048            throw new IllegalStateException("Process disappeared");
21049        }
21050    }
21051
21052    private void clearProfilerLocked() {
21053        if (mProfileFd != null) {
21054            try {
21055                mProfileFd.close();
21056            } catch (IOException e) {
21057            }
21058        }
21059        mProfileApp = null;
21060        mProfileProc = null;
21061        mProfileFile = null;
21062        mProfileType = 0;
21063        mAutoStopProfiler = false;
21064        mSamplingInterval = 0;
21065    }
21066
21067    public boolean profileControl(String process, int userId, boolean start,
21068            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21069
21070        try {
21071            synchronized (this) {
21072                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21073                // its own permission.
21074                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21075                        != PackageManager.PERMISSION_GRANTED) {
21076                    throw new SecurityException("Requires permission "
21077                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21078                }
21079
21080                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21081                    throw new IllegalArgumentException("null profile info or fd");
21082                }
21083
21084                ProcessRecord proc = null;
21085                if (process != null) {
21086                    proc = findProcessLocked(process, userId, "profileControl");
21087                }
21088
21089                if (start && (proc == null || proc.thread == null)) {
21090                    throw new IllegalArgumentException("Unknown process: " + process);
21091                }
21092
21093                if (start) {
21094                    stopProfilerLocked(null, 0);
21095                    setProfileApp(proc.info, proc.processName, profilerInfo);
21096                    mProfileProc = proc;
21097                    mProfileType = profileType;
21098                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21099                    try {
21100                        fd = fd.dup();
21101                    } catch (IOException e) {
21102                        fd = null;
21103                    }
21104                    profilerInfo.profileFd = fd;
21105                    proc.thread.profilerControl(start, profilerInfo, profileType);
21106                    fd = null;
21107                    mProfileFd = null;
21108                } else {
21109                    stopProfilerLocked(proc, profileType);
21110                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21111                        try {
21112                            profilerInfo.profileFd.close();
21113                        } catch (IOException e) {
21114                        }
21115                    }
21116                }
21117
21118                return true;
21119            }
21120        } catch (RemoteException e) {
21121            throw new IllegalStateException("Process disappeared");
21122        } finally {
21123            if (profilerInfo != null && profilerInfo.profileFd != null) {
21124                try {
21125                    profilerInfo.profileFd.close();
21126                } catch (IOException e) {
21127                }
21128            }
21129        }
21130    }
21131
21132    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21133        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21134                userId, true, ALLOW_FULL_ONLY, callName, null);
21135        ProcessRecord proc = null;
21136        try {
21137            int pid = Integer.parseInt(process);
21138            synchronized (mPidsSelfLocked) {
21139                proc = mPidsSelfLocked.get(pid);
21140            }
21141        } catch (NumberFormatException e) {
21142        }
21143
21144        if (proc == null) {
21145            ArrayMap<String, SparseArray<ProcessRecord>> all
21146                    = mProcessNames.getMap();
21147            SparseArray<ProcessRecord> procs = all.get(process);
21148            if (procs != null && procs.size() > 0) {
21149                proc = procs.valueAt(0);
21150                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21151                    for (int i=1; i<procs.size(); i++) {
21152                        ProcessRecord thisProc = procs.valueAt(i);
21153                        if (thisProc.userId == userId) {
21154                            proc = thisProc;
21155                            break;
21156                        }
21157                    }
21158                }
21159            }
21160        }
21161
21162        return proc;
21163    }
21164
21165    public boolean dumpHeap(String process, int userId, boolean managed,
21166            String path, ParcelFileDescriptor fd) throws RemoteException {
21167
21168        try {
21169            synchronized (this) {
21170                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21171                // its own permission (same as profileControl).
21172                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21173                        != PackageManager.PERMISSION_GRANTED) {
21174                    throw new SecurityException("Requires permission "
21175                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21176                }
21177
21178                if (fd == null) {
21179                    throw new IllegalArgumentException("null fd");
21180                }
21181
21182                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21183                if (proc == null || proc.thread == null) {
21184                    throw new IllegalArgumentException("Unknown process: " + process);
21185                }
21186
21187                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21188                if (!isDebuggable) {
21189                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21190                        throw new SecurityException("Process not debuggable: " + proc);
21191                    }
21192                }
21193
21194                proc.thread.dumpHeap(managed, path, fd);
21195                fd = null;
21196                return true;
21197            }
21198        } catch (RemoteException e) {
21199            throw new IllegalStateException("Process disappeared");
21200        } finally {
21201            if (fd != null) {
21202                try {
21203                    fd.close();
21204                } catch (IOException e) {
21205                }
21206            }
21207        }
21208    }
21209
21210    @Override
21211    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21212            String reportPackage) {
21213        if (processName != null) {
21214            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21215                    "setDumpHeapDebugLimit()");
21216        } else {
21217            synchronized (mPidsSelfLocked) {
21218                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21219                if (proc == null) {
21220                    throw new SecurityException("No process found for calling pid "
21221                            + Binder.getCallingPid());
21222                }
21223                if (!Build.IS_DEBUGGABLE
21224                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21225                    throw new SecurityException("Not running a debuggable build");
21226                }
21227                processName = proc.processName;
21228                uid = proc.uid;
21229                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21230                    throw new SecurityException("Package " + reportPackage + " is not running in "
21231                            + proc);
21232                }
21233            }
21234        }
21235        synchronized (this) {
21236            if (maxMemSize > 0) {
21237                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21238            } else {
21239                if (uid != 0) {
21240                    mMemWatchProcesses.remove(processName, uid);
21241                } else {
21242                    mMemWatchProcesses.getMap().remove(processName);
21243                }
21244            }
21245        }
21246    }
21247
21248    @Override
21249    public void dumpHeapFinished(String path) {
21250        synchronized (this) {
21251            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21252                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21253                        + " does not match last pid " + mMemWatchDumpPid);
21254                return;
21255            }
21256            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21257                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21258                        + " does not match last path " + mMemWatchDumpFile);
21259                return;
21260            }
21261            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21262            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21263        }
21264    }
21265
21266    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21267    public void monitor() {
21268        synchronized (this) { }
21269    }
21270
21271    void onCoreSettingsChange(Bundle settings) {
21272        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21273            ProcessRecord processRecord = mLruProcesses.get(i);
21274            try {
21275                if (processRecord.thread != null) {
21276                    processRecord.thread.setCoreSettings(settings);
21277                }
21278            } catch (RemoteException re) {
21279                /* ignore */
21280            }
21281        }
21282    }
21283
21284    // Multi-user methods
21285
21286    /**
21287     * Start user, if its not already running, but don't bring it to foreground.
21288     */
21289    @Override
21290    public boolean startUserInBackground(final int userId) {
21291        return mUserController.startUser(userId, /* foreground */ false);
21292    }
21293
21294    @Override
21295    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21296        return mUserController.unlockUser(userId, token, secret, listener);
21297    }
21298
21299    @Override
21300    public boolean switchUser(final int targetUserId) {
21301        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21302        UserInfo currentUserInfo;
21303        UserInfo targetUserInfo;
21304        synchronized (this) {
21305            int currentUserId = mUserController.getCurrentUserIdLocked();
21306            currentUserInfo = mUserController.getUserInfo(currentUserId);
21307            targetUserInfo = mUserController.getUserInfo(targetUserId);
21308            if (targetUserInfo == null) {
21309                Slog.w(TAG, "No user info for user #" + targetUserId);
21310                return false;
21311            }
21312            if (!targetUserInfo.supportsSwitchTo()) {
21313                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21314                return false;
21315            }
21316            if (targetUserInfo.isManagedProfile()) {
21317                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21318                return false;
21319            }
21320            mUserController.setTargetUserIdLocked(targetUserId);
21321        }
21322        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21323        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21324        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21325        return true;
21326    }
21327
21328    void scheduleStartProfilesLocked() {
21329        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21330            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21331                    DateUtils.SECOND_IN_MILLIS);
21332        }
21333    }
21334
21335    @Override
21336    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21337        return mUserController.stopUser(userId, force, callback);
21338    }
21339
21340    @Override
21341    public UserInfo getCurrentUser() {
21342        return mUserController.getCurrentUser();
21343    }
21344
21345    @Override
21346    public boolean isUserRunning(int userId, int flags) {
21347        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21348                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21349            String msg = "Permission Denial: isUserRunning() from pid="
21350                    + Binder.getCallingPid()
21351                    + ", uid=" + Binder.getCallingUid()
21352                    + " requires " + INTERACT_ACROSS_USERS;
21353            Slog.w(TAG, msg);
21354            throw new SecurityException(msg);
21355        }
21356        synchronized (this) {
21357            return mUserController.isUserRunningLocked(userId, flags);
21358        }
21359    }
21360
21361    @Override
21362    public int[] getRunningUserIds() {
21363        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21364                != PackageManager.PERMISSION_GRANTED) {
21365            String msg = "Permission Denial: isUserRunning() from pid="
21366                    + Binder.getCallingPid()
21367                    + ", uid=" + Binder.getCallingUid()
21368                    + " requires " + INTERACT_ACROSS_USERS;
21369            Slog.w(TAG, msg);
21370            throw new SecurityException(msg);
21371        }
21372        synchronized (this) {
21373            return mUserController.getStartedUserArrayLocked();
21374        }
21375    }
21376
21377    @Override
21378    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21379        mUserController.registerUserSwitchObserver(observer);
21380    }
21381
21382    @Override
21383    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21384        mUserController.unregisterUserSwitchObserver(observer);
21385    }
21386
21387    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21388        if (info == null) return null;
21389        ApplicationInfo newInfo = new ApplicationInfo(info);
21390        newInfo.initForUser(userId);
21391        return newInfo;
21392    }
21393
21394    public boolean isUserStopped(int userId) {
21395        synchronized (this) {
21396            return mUserController.getStartedUserStateLocked(userId) == null;
21397        }
21398    }
21399
21400    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21401        if (aInfo == null
21402                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21403            return aInfo;
21404        }
21405
21406        ActivityInfo info = new ActivityInfo(aInfo);
21407        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21408        return info;
21409    }
21410
21411    private boolean processSanityChecksLocked(ProcessRecord process) {
21412        if (process == null || process.thread == null) {
21413            return false;
21414        }
21415
21416        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21417        if (!isDebuggable) {
21418            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21419                return false;
21420            }
21421        }
21422
21423        return true;
21424    }
21425
21426    public boolean startBinderTracking() throws RemoteException {
21427        synchronized (this) {
21428            mBinderTransactionTrackingEnabled = true;
21429            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21430            // permission (same as profileControl).
21431            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21432                    != PackageManager.PERMISSION_GRANTED) {
21433                throw new SecurityException("Requires permission "
21434                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21435            }
21436
21437            for (int i = 0; i < mLruProcesses.size(); i++) {
21438                ProcessRecord process = mLruProcesses.get(i);
21439                if (!processSanityChecksLocked(process)) {
21440                    continue;
21441                }
21442                try {
21443                    process.thread.startBinderTracking();
21444                } catch (RemoteException e) {
21445                    Log.v(TAG, "Process disappared");
21446                }
21447            }
21448            return true;
21449        }
21450    }
21451
21452    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21453        try {
21454            synchronized (this) {
21455                mBinderTransactionTrackingEnabled = false;
21456                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21457                // permission (same as profileControl).
21458                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21459                        != PackageManager.PERMISSION_GRANTED) {
21460                    throw new SecurityException("Requires permission "
21461                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21462                }
21463
21464                if (fd == null) {
21465                    throw new IllegalArgumentException("null fd");
21466                }
21467
21468                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21469                pw.println("Binder transaction traces for all processes.\n");
21470                for (ProcessRecord process : mLruProcesses) {
21471                    if (!processSanityChecksLocked(process)) {
21472                        continue;
21473                    }
21474
21475                    pw.println("Traces for process: " + process.processName);
21476                    pw.flush();
21477                    try {
21478                        TransferPipe tp = new TransferPipe();
21479                        try {
21480                            process.thread.stopBinderTrackingAndDump(
21481                                    tp.getWriteFd().getFileDescriptor());
21482                            tp.go(fd.getFileDescriptor());
21483                        } finally {
21484                            tp.kill();
21485                        }
21486                    } catch (IOException e) {
21487                        pw.println("Failure while dumping IPC traces from " + process +
21488                                ".  Exception: " + e);
21489                        pw.flush();
21490                    } catch (RemoteException e) {
21491                        pw.println("Got a RemoteException while dumping IPC traces from " +
21492                                process + ".  Exception: " + e);
21493                        pw.flush();
21494                    }
21495                }
21496                fd = null;
21497                return true;
21498            }
21499        } finally {
21500            if (fd != null) {
21501                try {
21502                    fd.close();
21503                } catch (IOException e) {
21504                }
21505            }
21506        }
21507    }
21508
21509    private final class LocalService extends ActivityManagerInternal {
21510        @Override
21511        public void onWakefulnessChanged(int wakefulness) {
21512            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21513        }
21514
21515        @Override
21516        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21517                String processName, String abiOverride, int uid, Runnable crashHandler) {
21518            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21519                    processName, abiOverride, uid, crashHandler);
21520        }
21521
21522        @Override
21523        public SleepToken acquireSleepToken(String tag) {
21524            Preconditions.checkNotNull(tag);
21525
21526            ComponentName requestedVrService = null;
21527            ComponentName callingVrActivity = null;
21528            int userId = -1;
21529            synchronized (ActivityManagerService.this) {
21530                if (mFocusedActivity != null) {
21531                    requestedVrService = mFocusedActivity.requestedVrComponent;
21532                    callingVrActivity = mFocusedActivity.info.getComponentName();
21533                    userId = mFocusedActivity.userId;
21534                }
21535            }
21536
21537            if (requestedVrService != null) {
21538                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21539            }
21540
21541            synchronized (ActivityManagerService.this) {
21542                SleepTokenImpl token = new SleepTokenImpl(tag);
21543                mSleepTokens.add(token);
21544                updateSleepIfNeededLocked();
21545                return token;
21546            }
21547        }
21548
21549        @Override
21550        public ComponentName getHomeActivityForUser(int userId) {
21551            synchronized (ActivityManagerService.this) {
21552                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21553                return homeActivity == null ? null : homeActivity.realActivity;
21554            }
21555        }
21556
21557        @Override
21558        public void onUserRemoved(int userId) {
21559            synchronized (ActivityManagerService.this) {
21560                ActivityManagerService.this.onUserStoppedLocked(userId);
21561            }
21562        }
21563
21564        @Override
21565        public void onLocalVoiceInteractionStarted(IBinder activity,
21566                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21567            synchronized (ActivityManagerService.this) {
21568                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21569                        voiceSession, voiceInteractor);
21570            }
21571        }
21572
21573        @Override
21574        public void notifyStartingWindowDrawn() {
21575            synchronized (ActivityManagerService.this) {
21576                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21577            }
21578        }
21579
21580        @Override
21581        public void notifyAppTransitionStarting(int reason) {
21582            synchronized (ActivityManagerService.this) {
21583                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21584            }
21585        }
21586
21587        @Override
21588        public void notifyAppTransitionFinished() {
21589            synchronized (ActivityManagerService.this) {
21590                mStackSupervisor.notifyAppTransitionDone();
21591            }
21592        }
21593
21594        @Override
21595        public void notifyAppTransitionCancelled() {
21596            synchronized (ActivityManagerService.this) {
21597                mStackSupervisor.notifyAppTransitionDone();
21598            }
21599        }
21600
21601        @Override
21602        public List<IBinder> getTopVisibleActivities() {
21603            synchronized (ActivityManagerService.this) {
21604                return mStackSupervisor.getTopVisibleActivities();
21605            }
21606        }
21607
21608        @Override
21609        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21610            synchronized (ActivityManagerService.this) {
21611                mStackSupervisor.setDockedStackMinimized(minimized);
21612            }
21613        }
21614
21615        @Override
21616        public void killForegroundAppsForUser(int userHandle) {
21617            synchronized (ActivityManagerService.this) {
21618                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21619                final int NP = mProcessNames.getMap().size();
21620                for (int ip = 0; ip < NP; ip++) {
21621                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21622                    final int NA = apps.size();
21623                    for (int ia = 0; ia < NA; ia++) {
21624                        final ProcessRecord app = apps.valueAt(ia);
21625                        if (app.persistent) {
21626                            // We don't kill persistent processes.
21627                            continue;
21628                        }
21629                        if (app.removed) {
21630                            procs.add(app);
21631                        } else if (app.userId == userHandle && app.foregroundActivities) {
21632                            app.removed = true;
21633                            procs.add(app);
21634                        }
21635                    }
21636                }
21637
21638                final int N = procs.size();
21639                for (int i = 0; i < N; i++) {
21640                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21641                }
21642            }
21643        }
21644
21645        @Override
21646        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21647            if (!(target instanceof PendingIntentRecord)) {
21648                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21649                return;
21650            }
21651            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21652        }
21653    }
21654
21655    private final class SleepTokenImpl extends SleepToken {
21656        private final String mTag;
21657        private final long mAcquireTime;
21658
21659        public SleepTokenImpl(String tag) {
21660            mTag = tag;
21661            mAcquireTime = SystemClock.uptimeMillis();
21662        }
21663
21664        @Override
21665        public void release() {
21666            synchronized (ActivityManagerService.this) {
21667                if (mSleepTokens.remove(this)) {
21668                    updateSleepIfNeededLocked();
21669                }
21670            }
21671        }
21672
21673        @Override
21674        public String toString() {
21675            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21676        }
21677    }
21678
21679    /**
21680     * An implementation of IAppTask, that allows an app to manage its own tasks via
21681     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21682     * only the process that calls getAppTasks() can call the AppTask methods.
21683     */
21684    class AppTaskImpl extends IAppTask.Stub {
21685        private int mTaskId;
21686        private int mCallingUid;
21687
21688        public AppTaskImpl(int taskId, int callingUid) {
21689            mTaskId = taskId;
21690            mCallingUid = callingUid;
21691        }
21692
21693        private void checkCaller() {
21694            if (mCallingUid != Binder.getCallingUid()) {
21695                throw new SecurityException("Caller " + mCallingUid
21696                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21697            }
21698        }
21699
21700        @Override
21701        public void finishAndRemoveTask() {
21702            checkCaller();
21703
21704            synchronized (ActivityManagerService.this) {
21705                long origId = Binder.clearCallingIdentity();
21706                try {
21707                    // We remove the task from recents to preserve backwards
21708                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21709                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21710                    }
21711                } finally {
21712                    Binder.restoreCallingIdentity(origId);
21713                }
21714            }
21715        }
21716
21717        @Override
21718        public ActivityManager.RecentTaskInfo getTaskInfo() {
21719            checkCaller();
21720
21721            synchronized (ActivityManagerService.this) {
21722                long origId = Binder.clearCallingIdentity();
21723                try {
21724                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21725                    if (tr == null) {
21726                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21727                    }
21728                    return createRecentTaskInfoFromTaskRecord(tr);
21729                } finally {
21730                    Binder.restoreCallingIdentity(origId);
21731                }
21732            }
21733        }
21734
21735        @Override
21736        public void moveToFront() {
21737            checkCaller();
21738            // Will bring task to front if it already has a root activity.
21739            final long origId = Binder.clearCallingIdentity();
21740            try {
21741                synchronized (this) {
21742                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21743                }
21744            } finally {
21745                Binder.restoreCallingIdentity(origId);
21746            }
21747        }
21748
21749        @Override
21750        public int startActivity(IBinder whoThread, String callingPackage,
21751                Intent intent, String resolvedType, Bundle bOptions) {
21752            checkCaller();
21753
21754            int callingUser = UserHandle.getCallingUserId();
21755            TaskRecord tr;
21756            IApplicationThread appThread;
21757            synchronized (ActivityManagerService.this) {
21758                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21759                if (tr == null) {
21760                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21761                }
21762                appThread = ApplicationThreadNative.asInterface(whoThread);
21763                if (appThread == null) {
21764                    throw new IllegalArgumentException("Bad app thread " + appThread);
21765                }
21766            }
21767            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21768                    resolvedType, null, null, null, null, 0, 0, null, null,
21769                    null, bOptions, false, callingUser, null, tr);
21770        }
21771
21772        @Override
21773        public void setExcludeFromRecents(boolean exclude) {
21774            checkCaller();
21775
21776            synchronized (ActivityManagerService.this) {
21777                long origId = Binder.clearCallingIdentity();
21778                try {
21779                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21780                    if (tr == null) {
21781                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21782                    }
21783                    Intent intent = tr.getBaseIntent();
21784                    if (exclude) {
21785                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21786                    } else {
21787                        intent.setFlags(intent.getFlags()
21788                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21789                    }
21790                } finally {
21791                    Binder.restoreCallingIdentity(origId);
21792                }
21793            }
21794        }
21795    }
21796
21797    /**
21798     * Kill processes for the user with id userId and that depend on the package named packageName
21799     */
21800    @Override
21801    public void killPackageDependents(String packageName, int userId) {
21802        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21803        if (packageName == null) {
21804            throw new NullPointerException(
21805                    "Cannot kill the dependents of a package without its name.");
21806        }
21807
21808        long callingId = Binder.clearCallingIdentity();
21809        IPackageManager pm = AppGlobals.getPackageManager();
21810        int pkgUid = -1;
21811        try {
21812            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21813        } catch (RemoteException e) {
21814        }
21815        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21816            throw new IllegalArgumentException(
21817                    "Cannot kill dependents of non-existing package " + packageName);
21818        }
21819        try {
21820            synchronized(this) {
21821                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21822                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21823                        "dep: " + packageName);
21824            }
21825        } finally {
21826            Binder.restoreCallingIdentity(callingId);
21827        }
21828    }
21829}
21830